Android 四大组件之 Activity_ 权限验证

目录

 

1. 概述

2. 自定义的service

3. 系统service

(1) 调用  ContextWrapper.checkSelfPermission 确认是否有权限。   如果没有授权,则调用 Activity.requestPermissions

(2)  onRequestPermissionsResult 回调结果


1. 概述

当使用一些服务时,涉及到用户隐私时(如相机、联系人、电话权限等),一般需要用户手动授权用户授权后,才能进行操作。以此来保证用户隐私。

2. 自定义的service

对于自定义的服务, 在的AndroidManifest 会加上权限限定, 例如

<service android:name=".SimpleService"
    android:permission="com.sample.simpleservice.permission.CALLME">
</service>

其中"com.sample.simpleservice.permission.CALLME" 是自定义的约定的权限

而用调用这个service 的应用Client中,就要申明使用到这个权限:

<uses-permission android:name="com.sample.simpleservice.permission.CALLME"/>

3. 系统service

如  TelecomManager.endCall, 

参考 Android 四大组件之 Service_4_挂断电话(AIDL): https://blog.csdn.net/whjk20/article/details/112983081

这里调用endCall 需要Andoid.Manifest.java 中的权限

public static final String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";

因此,需要提示用户授权。

(1) 调用  ContextWrapper.checkSelfPermission 确认是否有权限。   如果没有授权,则调用 Activity.requestPermissions

    private void checkPhoneCallPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (this.checkSelfPermission(Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.ANSWER_PHONE_CALLS}, REQUEST_ANSWER_PHONE_CALLS_CODE);
            }
        }
    }

注意 requestPermissions 的详细说明, 需要判断:

  • 是否已经获取了权限
  • 是否已经拒绝了权限
  • 以上为否,才进行调用requestPermissions

需要传入权限名称,以及代码(自定义)。 并且结果会通过回调 Activity.onRequestPermissionsResult 通知

    /**
     * Requests permissions to be granted to this application. These permissions
     * must be requested in your manifest, they should not be granted to your app,
     * and they should have protection level {@link
     * android.content.pm.PermissionInfo#PROTECTION_DANGEROUS dangerous}, regardless
     * whether they are declared by the platform or a third-party app.
     * <p>
     * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
     * are granted at install time if requested in the manifest. Signature permissions
     * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
     * install time if requested in the manifest and the signature of your app matches
     * the signature of the app declaring the permissions.
     * </p>
     * <p>
     * Call {@link #shouldShowRequestPermissionRationale(String)} before calling this API to
     * check if the system recommends to show a rationale UI before asking for a permission.
     * </p>
     * <p>
     * If your app does not have the requested permissions the user will be presented
     * with UI for accepting them. After the user has accepted or rejected the
     * requested permissions you will receive a callback on {@link
     * #onRequestPermissionsResult(int, String[], int[])} reporting whether the
     * permissions were granted or not.
     * </p>
     * <p>
     * Note that requesting a permission does not guarantee it will be granted and
     * your app should be able to run without having this permission.
     * </p>
     * <p>
     * This method may start an activity allowing the user to choose which permissions
     * to grant and which to reject. Hence, you should be prepared that your activity
     * may be paused and resumed. Further, granting some permissions may require
     * a restart of you application. In such a case, the system will recreate the
     * activity stack before delivering the result to {@link
     * #onRequestPermissionsResult(int, String[], int[])}.
     * </p>
     * <p>
     * When checking whether you have a permission you should use {@link
     * #checkSelfPermission(String)}.
     * </p>
     * <p>
     * Calling this API for permissions already granted to your app would show UI
     * to the user to decide whether the app can still hold these permissions. This
     * can be useful if the way your app uses data guarded by the permissions
     * changes significantly.
     * </p>
     * <p>
     * You cannot request a permission if your activity sets {@link
     * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
     * <code>true</code> because in this case the activity would not receive
     * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
     * </p>
     * <p>
     * The <a href="https://github.com/googlesamples/android-RuntimePermissions">
     * RuntimePermissions</a> sample app demonstrates how to use this method to
     * request permissions at run time.
     * </p>
     *
     * @param permissions The requested permissions. Must me non-null and not empty.
     * @param requestCode Application specific request code to match with a result
     *    reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
     *    Should be >= 0.
     *
     * @throws IllegalArgumentException if requestCode is negative.
     *
     * @see #onRequestPermissionsResult(int, String[], int[])
     * @see #checkSelfPermission(String)
     * @see #shouldShowRequestPermissionRationale(String)
     */
    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {

(2)  onRequestPermissionsResult 回调结果

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_ANSWER_PHONE_CALLS_CODE) {
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//已获取了
                Toast.makeText(this, "Have grant permission: ANSWER_PHONE_CALLS", Toast.LENGTH_SHORT).show();
            } else {//没有允许,也没有拒绝过
                Toast.makeText(this, "ANSWER_PHONE_CALLS permission was NOT granted", Toast.LENGTH_SHORT).show();
            }
        }
    }

其中: PackageManager.java中定义

public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;

在获取了结果后,再做相应处理,例如启动camera等等

参考Github上Android 官方的例子:
https://github.com/googlesamples/android-RuntimePermissions

(MainActivity.java)

上一篇:python的闭包和装饰器


下一篇:移动安全-安卓权限获取