Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 6.0 運行時權限簡潔封裝

Android 6.0 運行時權限簡潔封裝

編輯:關於Android編程

MeloDev的這篇文章跟我的想法不謀而合,不一樣的地方是在於我加了個必要權限判斷,開發中我們會發現,有些權限是必須獲取到的,不然會影響到一部分的功能,如SD卡權限,當然,如果用戶不允許開通此類權限,APP理論上來說還是要允許用戶繼續使用的,但是我們要在很多地方加入權限判斷,很是麻煩,所以干脆流氓一點吧,添加一個必要權限判斷,如果必要權限被拒絕了,先彈窗,告知用戶去個人中心手動開啟,如果不然,直接退出APP....

整個世界都清淨了!!!


好了,現在來看看如何封裝:

我將運行時權限封裝到 BaseActivity 中,BaseActivity 繼承AppCompatActivity。
注解都寫得很詳細了,直接上代碼。

回調接口:

/**
 * Created by caihan on 2017/1/1.
 * 權限申請接口
 */

public interface PermissionsResultListener {
    void onPermissionGranted();

    void onPermissionDenied();
}

BaseActivity裡的權限代碼:

/**
 * Created by caihan on 2017/1/1.
 */
public abstract class BaseActivity extends AppCompatActivity{
    private static final String TAG = "BaseActivity";
    protected Context mContext;

    // For Android 6.0
    private PermissionsResultListener mListener;
    //申請標記值
    public static final int REQUEST_CODE_ASK_PERMISSIONS = 100;
    //手動開啟權限requestCode
    public static final int SETTINGS_REQUEST_CODE = 200;
    //拒絕權限後是否關閉界面或APP
    private boolean mNeedFinish = false;
    //界面傳遞過來的權限列表,用於二次申請
    private ArrayList mPermissionsList = new ArrayList<>();
    //必要全選,如果這幾個權限沒通過的話,就無法使用APP
    protected static final ArrayList FORCE_REQUIRE_PERMISSIONS = new ArrayList() {
        {
            add(Manifest.permission.INTERNET);
            add(Manifest.permission.READ_EXTERNAL_STORAGE);
            add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            add(Manifest.permission.ACCESS_FINE_LOCATION);
            add(Manifest.permission.ACCESS_COARSE_LOCATION);
        }
    };

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent != null) {
            setIntent(intent);
            mContext = this;
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //沒actionbar
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        //取消橫屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //輸入法彈出的時候不頂起布局
        //如果我們不設置"adjust..."的屬性,對於沒有滾動控件的布局來說,采用的是adjustPan方式,
        // 而對於有滾動控件的布局,則是采用的adjustResize方式。
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |
                WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
//        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |
//                WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        mContext = this;
    }

    /**
     * 權限允許或拒絕對話框
     *
     * @param permissions 需要申請的權限
     * @param needFinish  如果必須的權限沒有允許的話,是否需要finish當前 Activity
     * @param callback    回調對象
     */
    protected void requestPermission(final ArrayList permissions, final boolean needFinish,
                                     final PermissionsResultListener callback) {
        if (permissions == null || permissions.size() == 0) {
            return;
        }
        mNeedFinish = needFinish;
        mListener = callback;
        mPermissionsList = permissions;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //獲取未通過的權限列表
            ArrayList newPermissions = checkEachSelfPermission(permissions);
            if (newPermissions.size() > 0) {// 是否有未通過的權限
                requestEachPermissions(newPermissions.toArray(new String[newPermissions.size()]));
            } else {// 權限已經都申請通過了
                if (mListener != null) {
                    mListener.onPermissionGranted();
                }
            }
        } else {
            if (mListener != null) {
                mListener.onPermissionGranted();
            }
        }
    }

    /**
     * 申請權限前判斷是否需要聲明
     *
     * @param permissions
     */
    private void requestEachPermissions(String[] permissions) {
        if (shouldShowRequestPermissionRationale(permissions)) {// 需要再次聲明
            showRationaleDialog(permissions);
        } else {
            ActivityCompat.requestPermissions(BaseActivity.this, permissions,
                    REQUEST_CODE_ASK_PERMISSIONS);
        }
    }

    /**
     * 彈出聲明的 Dialog
     *
     * @param permissions
     */
    private void showRationaleDialog(final String[] permissions) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("提示")
                .setMessage("為了應用可以正常使用,請您點擊確認申請權限。")
                .setPositiveButton("確認",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                ActivityCompat.requestPermissions(BaseActivity.this, permissions,
                                        REQUEST_CODE_ASK_PERMISSIONS);
                            }
                        })
                .setNegativeButton("取消",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                if (mNeedFinish) finish();
                            }
                        })
                .setCancelable(false)
                .show();
    }

    /**
     * 檢察每個權限是否申請
     *
     * @param permissions
     * @return newPermissions.size > 0 表示有權限需要申請
     */
    private ArrayList checkEachSelfPermission(ArrayList permissions) {
        ArrayList newPermissions = new ArrayList();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                newPermissions.add(permission);
            }
        }
        return newPermissions;
    }

    /**
     * 再次申請權限時,是否需要聲明
     *
     * @param permissions
     * @return
     */
    private boolean shouldShowRequestPermissionRationale(String[] permissions) {
        for (String permission : permissions) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 申請權限結果的回調
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_ASK_PERMISSIONS && permissions != null) {
            // 獲取被拒絕的權限列表
            ArrayList deniedPermissions = new ArrayList<>();
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                    deniedPermissions.add(permission);
                }
            }
            // 判斷被拒絕的權限中是否有包含必須具備的權限
            ArrayList forceRequirePermissionsDenied =
                    checkForceRequirePermissionDenied(FORCE_REQUIRE_PERMISSIONS, deniedPermissions);
            if (forceRequirePermissionsDenied != null && forceRequirePermissionsDenied.size() > 0) {
                // 必備的權限被拒絕,
                if (mNeedFinish) {
                    showPermissionSettingDialog();
                } else {
                    if (mListener != null) {
                        mListener.onPermissionDenied();
                    }
                }
            } else {
                // 不存在必備的權限被拒絕,可以進首頁
                if (mListener != null) {
                    mListener.onPermissionGranted();
                }
            }
        }
    }

    /**
     * 檢查回調結果
     *
     * @param grantResults
     * @return
     */
    private boolean checkEachPermissionsGranted(int[] grantResults) {
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    private ArrayList checkForceRequirePermissionDenied(
            ArrayList forceRequirePermissions, ArrayList deniedPermissions) {
        ArrayList forceRequirePermissionsDenied = new ArrayList<>();
        if (forceRequirePermissions != null && forceRequirePermissions.size() > 0
                && deniedPermissions != null && deniedPermissions.size() > 0) {
            for (String forceRequire : forceRequirePermissions) {
                if (deniedPermissions.contains(forceRequire)) {
                    forceRequirePermissionsDenied.add(forceRequire);
                }
            }
        }
        return forceRequirePermissionsDenied;
    }

    /**
     * 手動開啟權限彈窗
     */
    private void showPermissionSettingDialog() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("提示")
                .setMessage("必要的權限被拒絕")
                .setPositiveButton("去設置", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        AppUtils.getAppDetailsSettings(BaseActivity.this, SETTINGS_REQUEST_CODE);
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                        if (mNeedFinish) AppUtils.restart(BaseActivity.this);
                    }
                })
                .setCancelable(false)
                .show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //如果需要跳轉系統設置頁後返回自動再次檢查和執行業務 如果不需要則不需要重寫onActivityResult
        if (requestCode == SETTINGS_REQUEST_CODE) {
            requestPermission(mPermissionsList, mNeedFinish, mListener);
        }
    }

}

跳轉應用設置和關閉APP進程的代碼:

    /**
     * 獲取App具體設置
     *
     * @param context 上下文
     */
    public static void getAppDetailsSettings(Context context, int requestCode) {
        getAppDetailsSettings(context, context.getPackageName(), requestCode);
    }

    /**
     * 獲取App具體設置
     *
     * @param context     上下文
     * @param packageName 包名
     */
    public static void getAppDetailsSettings(Context context, String packageName, int requestCode) {
        if (StringUtils.isSpace(packageName)) return;
        ((AppCompatActivity) context).startActivityForResult(
                IntentUtils.getAppDetailsSettingsIntent(packageName), requestCode);
    }

    /**
     * 獲取App具體設置的意圖
     *
     * @param packageName 包名
     * @return intent
     */
    public static Intent getAppDetailsSettingsIntent(String packageName) {
        Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
        intent.setData(Uri.parse("package:" + packageName));
        return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }

    /**
     * 通過任務管理器殺死進程
     * 需添加權限 {@code }

 

* * @param context */ public static void restart(Context context) { int currentVersion = android.os.Build.VERSION.SDK_INT; if (currentVersion > android.os.Build.VERSION_CODES.ECLAIR_MR1) { Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(startMain); System.exit(0); } else {// android2.1 ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE); am.restartPackage(context.getPackageName()); } }

界面上調用代碼:
這裡我直接傳了必要權限數列過去,因此如果有任何一個權限沒通過,都會退出APP,
如果你打算分場合請求權限的話,可以修改下我的代碼,必要和非必要權限都從界面傳遞過來就可以了。

        requestPermission(FORCE_REQUIRE_PERMISSIONS, true, new PermissionsResultListener() {
            @Override
            public void onPermissionGranted() {
                ToastUtils.showShortToast("已申請權限");
            }

            @Override
            public void onPermissionDenied() {
                ToastUtils.showShortToast("拒絕申請權限");
            }
        });
 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved