Android中如何使用自定义权限?

发布于 2024-12-26 03:37:42 字数 2112 浏览 0 评论 0原文

我有两个应用程序。

一种是声明权限并具有单个 Activity

AndroidManifest.xml 的一部分,

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:permission="your.namespace.permission.TEST" >
    <activity
        android:name=".DeclaringPermissionActivity"
        android:label="@string/app_name" >

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter> 
         <action android:name="android.intent.action.VIEW" /> 
         <category android:name="android.intent.category.DEFAULT" /> 
         <category android:name="android.intent.category.BROWSABLE" /> 
         <data android:scheme="myapp"
             android:host="myapp.mycompany.com" /> 
        </intent-filter> 
    </activity>
</application>

第二种声明是使用权限

AndroidManifest.xml

<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="your.namespace.permission.TEST" />

<application

的一部分 < code>Activity:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("myapp://myapp.mycompany.com/index")));
}

我正在安装声明权限的应用程序,然后运行第二个应用程序。

结果我得到安全异常:

 01-11 09:46:55.249: E/AndroidRuntime(347): java.lang.RuntimeException: Unable to start activity ComponentInfo{your.namespace2/your.namespace2.UsingPErmissionActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW dat=myapp://myapp.mycompany.com/index cmp=your.namespace/.DeclaringPermissionActivity } from ProcessRecord{407842c0 347:your.namespace2/10082} (pid=347, uid=10082) requires your.namespace.permission.TEST

I have two applications.

One is declaring permission and having single Activity:

Part of AndroidManifest.xml

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:permission="your.namespace.permission.TEST" >
    <activity
        android:name=".DeclaringPermissionActivity"
        android:label="@string/app_name" >

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter> 
         <action android:name="android.intent.action.VIEW" /> 
         <category android:name="android.intent.category.DEFAULT" /> 
         <category android:name="android.intent.category.BROWSABLE" /> 
         <data android:scheme="myapp"
             android:host="myapp.mycompany.com" /> 
        </intent-filter> 
    </activity>
</application>

The second declares that is uses permission

Part of AndroidManifest.xml

<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="your.namespace.permission.TEST" />

<application

Part of Activity:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("myapp://myapp.mycompany.com/index")));
}

I'm installing the application declaring permission, then I run the second application.

In a result I get security exception:

 01-11 09:46:55.249: E/AndroidRuntime(347): java.lang.RuntimeException: Unable to start activity ComponentInfo{your.namespace2/your.namespace2.UsingPErmissionActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW dat=myapp://myapp.mycompany.com/index cmp=your.namespace/.DeclaringPermissionActivity } from ProcessRecord{407842c0 347:your.namespace2/10082} (pid=347, uid=10082) requires your.namespace.permission.TEST

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

倾城花音 2025-01-02 03:37:42

我创建了一个测试代码,您可以使用它并测试您的权限。有两个应用程序 PermissionTestClient 声明权限并使用此权限保护其活动。这是它的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.testpackage.permissiontestclient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <permission android:name="com.testpackage.mypermission" android:label="my_permission" android:protectionLevel="dangerous"></permission>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:permission="com.testpackage.mypermission"
            android:name=".PermissionTestClientActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter >
                <action android:name="com.testpackage.permissiontestclient.MyAction" />
                <category android:name="android.intent.category.DEFAULT" />                
            </intent-filter>
        </activity>
    </application>

</manifest>

Activity 文件没有什么特别的,所以我不会在这里展示它。

PermissionTestServer 应用程序从 PermissionTestClient 调用活动。这是它的清单文件:

<?xml version="1.0" encoding="utf-8"?>

<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="com.testpackage.mypermission"/>

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".PermissionTestServerActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

和活动:

package com.testpackage.permissiontestserver;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class PermissionTestServerActivity extends Activity {
    private static final String TAG = "PermissionTestServerActivity";

    /** Called when the activity is first created. */
    Button btnTest;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btnTest = (Button) findViewById(R.id.btnTest);
        btnTest.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "Button pressed!");
                Intent in = new Intent();
                in.setAction("com.testpackage.permissiontestclient.MyAction");
                in.addCategory("android.intent.category.DEFAULT");
                startActivity(in);
            }
        });
    }
}

要测试它,只需从服务器应用程序中删除使用权限。您将收到安全违规错误。

I created a test code you can use it and test your permissions. There are two applications PermissionTestClient which declares permission and protects its activity with this permission. Here is its manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.testpackage.permissiontestclient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <permission android:name="com.testpackage.mypermission" android:label="my_permission" android:protectionLevel="dangerous"></permission>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:permission="com.testpackage.mypermission"
            android:name=".PermissionTestClientActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter >
                <action android:name="com.testpackage.permissiontestclient.MyAction" />
                <category android:name="android.intent.category.DEFAULT" />                
            </intent-filter>
        </activity>
    </application>

</manifest>

There is nothing special in Activity file so I will not show it here.

PermissionTestServer application calls activity from PermissionTestClient. Here is its manifest file:

<?xml version="1.0" encoding="utf-8"?>

<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="com.testpackage.mypermission"/>

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".PermissionTestServerActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

And Activity:

package com.testpackage.permissiontestserver;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class PermissionTestServerActivity extends Activity {
    private static final String TAG = "PermissionTestServerActivity";

    /** Called when the activity is first created. */
    Button btnTest;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btnTest = (Button) findViewById(R.id.btnTest);
        btnTest.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "Button pressed!");
                Intent in = new Intent();
                in.setAction("com.testpackage.permissiontestclient.MyAction");
                in.addCategory("android.intent.category.DEFAULT");
                startActivity(in);
            }
        });
    }
}

To test it just remove uses-permission from Server application. You'll get security violation error.

爱本泡沫多脆弱 2025-01-02 03:37:42

您需要在基本应用程序的清单中创建权限
独家声明。例如:

<permission android:name="your.namespace.permission.TEST"
    android:protectionLevel="normal" android:label="This is my custom  permission" />

稍后在您想要的应用程序中使用它,如下所示:

<uses-permission android:name="your.namespace.permission.TEST" />

注意: 维护具有自定义权限的应用程序的安装顺序至关重要。即您必须首先安装声明权限的应用程序,然后再安装使用该权限的应用程序。此顺序中的任何中断都可能会破坏自定义权限的使用。

You need to create a permission in your base app's manifest by
declaring it exclusively. For example:

<permission android:name="your.namespace.permission.TEST"
    android:protectionLevel="normal" android:label="This is my custom  permission" />

And later make use of it in your desired app as:

<uses-permission android:name="your.namespace.permission.TEST" />

Note: It is vital to maintain the order in which you install your applications with custom permissions. i.e You must need to install that app first which declares the permission and later install the one which makes use of it. Any disruption in this order may break the usage of custom. permissions.

深陷 2025-01-02 03:37:42

正如答案中提到的,您还应该考虑安装应用程序的顺序。

这很重要,因为:

如果请求权限的应用程序(应用程序 B)安装在定义权限的应用程序(应用程序 A)之前,则特定设备中将不存在此类定义的权限,因此操作系统不会请求完全没有许可。

稍后,当您安装应用程序 A 并尝试运行应用程序 B 时,后者将无法访问安全组件。

一种解决方法是在应用程序 A 和 B 中定义相同的自定义权限,以确保无论先安装哪个应用程序,该权限都存在于设备中,因此当安装应用程序 A 时,该权限将已经存在 。

但在这种情况下,您应该确保两个声明中的保护级别相同,因为这可能会导致安全风险

(此处请注意,从 android 5.0 及以上版本开始,您不能在多个应用程序中定义相同的权限,除非这些应用程序使用相同的签名密钥进行签名)。

As mentioned in the answers, you should also take into account the order you install the apps.

this is important because:

if the App that requests the permission (App B) is installed before the App that defines the permission (App A), then there will be no such defined permission in the specific device so the OS won't ask for the permission at all.

later on, when you install the App A and try to run App B, the latter will fail to access the secure component.

One workaround would be to define the same custom permission in both Apps, A and B in order to make sure that the permission exists in the device regardless of which App is installed first, so when the App A is installed, the permission will be already granted to App B.

In that case though, you should make sure that the protection level is the same in both declarations because this can lead to security risk.

(note here that from android 5.0 and on you cannot define the same permission in more than one App, except when those Apps are signed with the same signature key).

韶华倾负 2025-01-02 03:37:42

接受的答案显示了创建自定义权限的正确流程。
在我在 Android 上进行测试后,我有一些注释来决定哪个权限和权限名称

android:protectionLevel="normal" // don't need user confirmation to grant, similar to some low-risk permission like android.permission.INTERNET

android:protectionLevel="dangerous" // need user confirmation to grant // similar to some high-risk permission like android.permission.CAMERA

android:protectionLevel="signature" // both app need to sign with the same signature

< 6、用户在安装或更新应用时授予dangerous权限。 Android 为我们做这件事,我们不需要编码
Android >= 6,用户在使用应用时授予dangerous权限(运行时权限)。我们需要编写代码来请求运行时权限

Android 危险权限名称需要有 2 部分(在 Android 10、Pixel 4XL 上测试),labeldescriptionicon< /code> 不需要使权限生效

<permission
        android:name="my.MyCustomPermission" // work well
        android:name="MyCustomPermission" // not work, the runtime permission dialog won't show
        android:label="" // don't required
        android:description="" // don't required
        android:icon="" // don't required

The accepted answer shows the correct flow to create custom permissions.
I have some note to decide which permission and permission name after my testing

android:protectionLevel="normal" // don't need user confirmation to grant, similar to some low-risk permission like android.permission.INTERNET

android:protectionLevel="dangerous" // need user confirmation to grant // similar to some high-risk permission like android.permission.CAMERA

android:protectionLevel="signature" // both app need to sign with the same signature

On Android < 6, user grant dangerous permission when install or update app. Android do it for us, we don't need to code
Android >= 6, user grant dangerous permission when using app (Runtime Permission). We need to code to request runtime permission

Android dangerous permission name need to has 2 parts (test on Android 10, Pixel 4XL), label, description, icon is not required to make permission work

<permission
        android:name="my.MyCustomPermission" // work well
        android:name="MyCustomPermission" // not work, the runtime permission dialog won't show
        android:label="" // don't required
        android:description="" // don't required
        android:icon="" // don't required
拍不死你 2025-01-02 03:37:42

使用 标签定义自定义权限。
请点击以下链接在应用程序中使用用户定义的权限:

声明和执行权限

Defining custom permission is done using <Permission> tag..
Please follow the link below to use user defined permissions in application:

Declaring and Enforcing Permissions

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文