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

我有两个应用程序。

一个是声明权限和单个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 

部分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 

我创build了一个testing代码,您可以使用它并testing您的权限。 有两个应用程序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> 

活动文件中没有什么特别的,所以我不会在这里显示。

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); } }); } } 

要testing它只是从服务器应用程序中删除使用权限。 你会得到安全违规错误。

您需要通过独占声明在基本应用程序的清单中创build一个权限。 例如:

 <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" /> 

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

定义自定义权限是使用<Permission>标签完成的。请按照以下链接在应用程序中使用用户定义的权限:

声明和执行权限

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

这很重要,因为:

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

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

一种解决方法是在应用程序A和B中定义相同的自定义权限,以确保设备中存在权限,而不pipe首先安装哪个应用程序,所以当安装应用程序A时,权限将已经授予应用程序B.

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

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