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

pix*_*xel 57 permissions android android-manifest

我有两个申请.

一个是宣布许可和单身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>
Run Code Online (Sandbox Code Playgroud)

第二个声明是使用权限

部分的AndroidManifest.xml

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

<application
Run Code Online (Sandbox Code Playgroud)

部分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")));
}
Run Code Online (Sandbox Code Playgroud)

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

结果我得到安全异常:

 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
Run Code Online (Sandbox Code Playgroud)

Yur*_*ury 101

我创建了一个可以使用它的测试代码并测试你的权限.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>
Run Code Online (Sandbox Code Playgroud)

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

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

<?xml version="1.0" encoding="utf-8"?>
Run Code Online (Sandbox Code Playgroud)

<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>
Run Code Online (Sandbox Code Playgroud)

和活动:

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);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

要测试它,只需从Server应用程序中删除uses-permission.您将收到安全违规错误.

  • 谢谢,我的错误是将`permission`属性仅用于`<application>`元素. (2认同)
  • 签名级别的权限意味着您的客户端和服务器应使用相同的证书进行签名.尝试使用危险级别启动代码,如果一切正常,则尝试使用签名启动.还有一件事,如果您使用签名我认为您需要导出已签名的apk文件然后安装它们. (2认同)

waq*_*lam 33

您需要通过专门声明它来在基础应用程序的清单中创建权限.例如:

<permission android:name="your.namespace.permission.TEST"
    android:protectionLevel="normal" android:label="This is my custom  permission" />
Run Code Online (Sandbox Code Playgroud)

然后在您想要的应用程序中使用它:

<uses-permission android:name="your.namespace.permission.TEST" />
Run Code Online (Sandbox Code Playgroud)

注意: 维护使用自定义权限安装应用程序的顺序至关重要.即你必须需要安装该应用程序首先它声明的许可,并在以后安装一个,这使得使用它.此订单中的任何中断都可能会破坏自定义的使用.权限.

  • 只要我没记错,安装应用程序的顺序也很重要。首先安装声明自定义权限的应用程序,然后安装使用该自定义权限的应用程序。 (2认同)

Ada*_*dam 7

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

这很重要,因为:

如果请求权限的应用程序(应用程序 B)安装在定义权限的应用程序(应用程序 A)之前,那么特定设备中将没有这样定义的权限,因此操作系统根本不会请求权限。

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

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

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

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