Android6.0権限管理

7882 ワード

前言
Android6.0(API 23)は、実行時に権限管理を適用するという新しい権限モードを導入する.このモードにより、ユーザは、インストールされた各アプリケーションに対してそれぞれ権限を付与または取り消すことができる権限をよりよく理解し、制御することができる.開発者にとっては,対応する権限機能を使用する際に,権限が付与されているか否かを先に判断しなければならないことを意味する.
危険権限
権限の管理には、すべての権限がユーザーに許可される必要はありません.一部の危険な権限だけが許可されます.下図参照
権限の確認、要求
  • AndroidManifestに必要な権限を追加
  • 危険権限機能を使用する前に権限の状態をチェックする
  • .
    checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
  • 権限がない場合(チェック権限ステータスがPackageManager.PERMISSION_GRANTEDでない場合)は、要求権限
  • を要求する.
    requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
  • は、ユーザ操作フォールバック中に操作を許可及び拒否する論理
  • を処理する.
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "      ", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "      !!!", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    ここで、requestPermissions()は、3番目のステップで複数の権限を一度に要求することができ、ユーザーが許可および拒否し、プロンプトを出さない権限をチェックすると、直接実行され、ユーザーが再び権限を選択することはありません.したがって、ユーザーが拒否した後、設定で手動で権限を開くには、権限が必要な機能が必要です.
    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    intent.setData(Uri.fromParts("package", getPackageName(), null));
    startActivity(intent);

    特殊機種への適合
    国内の多くの携帯電話メーカーがAndroid 6にいたためだ.0以前から独自の権限管理システムがあり、Android 6.0以降には、既存の権限管理システムが残っているものもあります.これにより,checkSelfPermission()で権限をチェックしているのに権限機能が使えなくなった.たとえばVIVOは、すべての場合checkSelfPermission()に権限が返されますが、権限操作に関連する操作を使用すると自動的にユーザー権限の許可を求めます.しかし、この場合、呼び出しはシステムのエラーを招くことはなく、サードパーティのメーカーも使用権限のヒントを与えています.以下、小米を例に、小米に権限を開くかどうかを判断する
    /**
    *       
    **/
    private static boolean checkOpsPermission(Context context, String permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            try {
                AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
                String opsName = AppOpsManager.permissionToOp(permission);
                if (opsName == null) {
                    return true;
                }
                int opsMode = appOpsManager.checkOpNoThrow(opsName, android.os.Process.myUid(), context.getPackageName());
                return opsMode == AppOpsManager.MODE_ALLOWED;
            } catch (Exception ex) {
                return true;
            }
        } else {
            return true;
        }
    }
    
    /**
     *         
     */
    public void openPermissionSetting(Activity activity) {
        String miuiVersion = getMiuiVersion();
        Intent intent = null;
        if ("V5".equals(miuiVersion)) {
            Uri packageURI = Uri.parse("package:" + activity.getApplicationInfo().packageName);
            intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
        } else if ("V6".equals(miuiVersion) || "V7".equals(miuiVersion)) {
            intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
            intent.putExtra("extra_pkgname", activity.getPackageName());
        } else if ("V8".equals(miuiVersion) || "V9".equals(miuiVersion)) {
            intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
            intent.putExtra("extra_pkgname", activity.getPackageName());
        }
    
        if (null != intent)
            activity.startActivity(intent);
    }
    
    /**
     *   MIUI  
     */
    public String getMiuiVersion() {
        String line;
        BufferedReader input = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop ro.miui.ui.version.name");
            input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
            line = input.readLine();
            input.close();
        } catch (IOException ex) {
            return null;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                }
            }
        }
        return line;
    }

    リファレンス
    Android 6.0実行時権限処理完全解析権限ベスト・プラクティスAndroid 6.0動的権限および小米(MIUI)権限の特殊処理