Android 权限使用问题

博主在探讨Android权限使用时遇到问题,发现自定义权限的`android:name`必须使用反向域风格(如com.tom.permission)才能正常工作。官方文档虽然建议如此,但未明确指出不遵循会导致错误。通过实验得出此结论,并分享了相关测试应用的经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是一个问题贴,但是我的积分不够分不够发帖啦  ̄□ ̄||


答案

自定义权限:


 
<permission android:name="DeclarPermissionDangerous" android:description="@string/app_name" android:icon="@mipmap/ic_launcher" android:protectionLevel="dangerous" />

后来确定问题在于 android:name="permissionName"

经测试 permissionName 如果定义为 反向域风格reverse-domain-style(com.tom.permission) 即可正常使用。

Google 官方文档的意思是建议使用“反向域风格”,但是如果不使用会造成错误,这也是试验过才知道的。

  1. https://developer.android.google.cn/guide/topics/manifest/permission-element.html#nm




问题

我写了两个应用测试权限相关的功能细节

应用a 声明(创造)权限并用来保护自己的 Activity
应用b 声明(使用)权限并且调用应用 a 的 activity

应用 a 代码
AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="tom.work.foxmail.com.declarpermission">

    <permission
        android:name="DeclarPermissionNormal"
        android:description="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:protectionLevel="normal" />

    <permission
        android:name="DeclarPermissionDangerous"
        android:description="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:protectionLevel="dangerous" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity
            android:name=".DeclarePermissionActivityNull"
            android:exported="true" />

        <activity
            android:name=".DeclarePermissionActivityNormal"
            android:exported="true"
            android:permission="DeclarPermissionNormal" />

        <activity
            android:name=".DeclarePermissionActivityDangerous"
            android:exported="true"
            android:permission="DeclarPermissionDangerous" />


    </application>


</manifest>



应用 A 的 4个 Activity

//MainActivity 可以正常启动另外三个 Activity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.initView();
    }

    private void initView() {
        findViewById(R.id.btn_permission_null).setOnClickListener(this);
        findViewById(R.id.btn_permission_normal).setOnClickListener(this);
        findViewById(R.id.btn_permission_dangerous).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        Intent intent = null;
        switch (view.getId()) {
            case R.id.btn_permission_null:
                intent = new Intent(this, DeclarePermissionActivityNull.class);
                break;
            case R.id.btn_permission_normal:
                intent = new Intent(this, DeclarePermissionActivityNormal.class);
                break;
            case R.id.btn_permission_dangerous:
                intent = new Intent(this, DeclarePermissionActivityDangerous.class);
                break;
        }
        startActivity(intent);
    }
}


//DeclarePermissionActivityNull 可以被 应用 B 启动
public class DeclarePermissionActivityNull extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.initView();
    }

    private void initView() {
        TextView textView = findViewById(R.id.textView);
        textView.setText("无需权限");
    }
}

//DeclarePermissionActivityNormal 无法被 应用 B 启动
public class DeclarePermissionActivityNormal extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.initView();
    }

    private void initView() {
        TextView textView = findViewById(R.id.textView);
        textView.setText("<permission android:name=\"DeclarPermission.normal\" />");
    }
}

//DeclarePermissionActivityDangerous 无法被应用 B 启动
public class DeclarePermissionActivityDangerous extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.initView();
    }

    private void initView() {
        TextView textView = findViewById(R.id.textView);
        textView.setText("<permission android:name=\"DeclarPermission.dangerous\" />");
    }
}






应用 B AndroidManifest.xml   权限已经声明
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="tom.work.foxmail.com.usepermission">

    <uses-permission android:name="DeclarPermissionNormal" />
    <uses-permission android:name="DeclarPermissionDangerous" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>



MainActivity 尝试使用已经声明的权限,不论是否运行时请求该权限,都无法使用该权限
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.initView();
    }

    private void initView() {

        findViewById(R.id.btn_start_without_permission).setOnClickListener(this);
        findViewById(R.id.btn_start_with_permission_normal).setOnClickListener(this);
        findViewById(R.id.btn_start_with_permission_dangerous).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        Intent intent = new Intent();

        switch (view.getId()) {
            case R.id.btn_start_with_permission_dangerous:


                switch (ContextCompat.checkSelfPermission(this, "DeclarPermissionDangerous")) {
                    case PERMISSION_GRANTED:
                        Toast.makeText(this, "权限已经被授予了", Toast.LENGTH_SHORT).show();
                        ComponentName componentNameDangerous = new ComponentName(
                                "tom.work.foxmail.com.declarpermission"
                                , "tom.work.foxmail.com.declarpermission.DeclarePermissionActivityDangerous");
                        intent.setComponent(componentNameDangerous);
                        startActivity(intent);
                        break;
                    case PERMISSION_DENIED:
                        String[] arrayPermission = {"Custom_permission_protection"};
                        ActivityCompat.requestPermissions(this, arrayPermission, 3);
                        break;
                }


//                ComponentName componentNameDangerous = new ComponentName(
//                        "tom.work.foxmail.com.declarpermission"
//                        , "tom.work.foxmail.com.declarpermission.DeclarePermissionActivityDangerous");
//                intent.setComponent(componentNameDangerous);
//                startActivity(intent);
                break;
            case R.id.btn_start_with_permission_normal:

                switch (ContextCompat.checkSelfPermission(this, "DeclarPermissionNormal")) {
                    case PERMISSION_GRANTED:
                        Toast.makeText(this, "权限已经被授予了", Toast.LENGTH_SHORT).show();
                        ComponentName componentNameNormal = new ComponentName(
                                "tom.work.foxmail.com.declarpermission"
                                , "tom.work.foxmail.com.declarpermission.DeclarePermissionActivityNormal");
                        intent.setComponent(componentNameNormal);
                        startActivity(intent);
                        break;
                    case PERMISSION_DENIED:
                        String[] arrayPermission = {"Custom_permission_protection"};
                        ActivityCompat.requestPermissions(this, arrayPermission, 2);
                        break;
                }

//                ComponentName componentNameNormal = new ComponentName(
//                        "tom.work.foxmail.com.declarpermission"
//                        , "tom.work.foxmail.com.declarpermission.DeclarePermissionActivityNormal");
//                intent.setComponent(componentNameNormal);
//                startActivity(intent);
                break;
            case R.id.btn_start_without_permission:
                ComponentName componentNameNull = new ComponentName(
                        "tom.work.foxmail.com.declarpermission"
                        , "tom.work.foxmail.com.declarpermission.DeclarePermissionActivityNull");
                intent.setComponent(componentNameNull);
                startActivity(intent);
                break;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 3:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "成功 ^_^ 获取:DeclarPermissionDangerous", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "失败 !!!\n 获取:DeclarPermissionDangerous", Toast.LENGTH_SHORT).show();
                }
                break;
            case 2:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "成功 ^_^ 获取:DeclarPermissionNormal", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "失败 !!!\n 获取:DeclarPermissionNormal", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}




当前的问题如下
如果运行时申请权限,grantResults[0]=-1  ,权限获取失败
如果不适用运行时申请权限的代码 (见注释)异常如下:
java.lang.SecurityException: Permission Denial: starting Intent { cmp=tom.work.foxmail.com.declarpermission/.DeclarePermissionActivityNormal } 
from ProcessRecord{9976e73 15212:tom.work.foxmail.com.usepermission/u0a139} (pid=15212, uid=10139) requires DeclarPermissionNormal

//或者:::

java.lang.SecurityException: Permission Denial: starting Intent { cmp=tom.work.foxmail.com.declarpermission/.DeclarePermissionActivityDangerous } 
from ProcessRecord{d60c40d 15400:tom.work.foxmail.com.usepermission/u0a139} (pid=15400, uid=10139) requires DeclarPermissionDangerous



上述问题让我很难理解,请大伙帮忙提提意见吧。 ^_^
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值