我有两个应用程序。
一个是声明权限并使用单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
答案 0 :(得分: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>
活动文件中没有什么特别的,所以我不会在这里显示它。
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);
}
});
}
}
要测试它,只需从Server应用程序中删除uses-permission。您将收到安全违规错误。
答案 1 :(得分:31)
您需要在基础应用的清单中创建权限 完全宣布它。例如:
<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" />
注意: 维护使用自定义权限安装应用程序的顺序至关重要。即您必须安装该应用程序第一个,该应用程序声明该权限,然后安装使用该权限的应用程序。此订单中的任何中断都可能会破坏自定义。权限的使用。
答案 2 :(得分:2)
如答案中所述,您还应考虑安装应用的顺序。
这很重要,因为:
如果请求许可的应用程序(应用程序B)安装在定义权限的应用程序(应用程序A)之前,则在特定设备中将没有此类已定义的权限,因此操作系统不会要求许可。
稍后,当您安装App A并尝试运行App B时,后者将无法访问安全组件。
一种解决方法是在应用,A和B中定义相同的自定义权限,以确保设备中存在权限,无论首先安装哪个应用,因此在安装应用A时,权限将被授予App B.
在这种情况下,您应该确保两个声明中的保护级别相同,因为这可能会导致安全风险。
(请注意,从Android 5.0开始,您无法在多个应用程序中定义相同的权限,除非这些应用程序使用相同的签名密钥签名)。
答案 3 :(得分:1)
使用<Permission>
标记定义自定义权限。
请按照以下链接在应用程序中使用用户定义的权限:
答案 4 :(得分:1)
接受的答案显示了创建自定义权限的正确流程。 我有一些注意事项来决定我测试后的权限和权限名称
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
在 Android < 6 上,用户在安装或更新应用程序时授予 dangerous
权限。 Android 替我们做,我们不需要编码
Android >= 6,用户在使用应用程序时授予 dangerous
权限(运行时权限)。我们需要编写代码来请求运行时权限
Android 危险权限名称需要有 2 部分(在 Android 10、Pixel 4XL 上测试),label
、description
、icon
不需要使权限生效
<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