Android 6.0 - 動態許可權管理的解決方案

來源:互聯網
上載者:User

標籤:stp   elf   button   strong   content   oct   png   靜態   pat   

轉載請標註

Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了使用者體驗, 同時也為程式員帶來新的負擔. 動態許可權管理就是這樣, 一方面讓使用者更加容易的控制自己的隱私, 一方面需要重新適配應用許可權. 時代總是不斷髮展, 程式總是以人為本, 讓我們為應用添加動態許可權管理吧! 這裡提供了一個非常不錯的解決方案, 提供源碼, 項目可以直接使用.


Permissions

Android系統包含預設的授權提示框, 但是我們仍需要設定自己的頁面. 原因是系統提供的授權框, 會有不再提示的選項. 如果使用者選擇, 則無法觸發授權提示. 使用自訂的提示頁面, 可以給予使用者手動修改授權的指導.

本文樣本的GitHub

在Api 23中, 許可權需要動態擷取, 核心許可權必須滿足. 標準流程:


流程圖

如果使用者點擊, 不再提示, 則系統授權彈窗將不會彈出. 流程變為:


流程圖

流程就這些, 讓我們看看代碼吧.

1. 許可權

在AndroidManifest中, 添加兩個許可權, 錄音修改音量.

    <!--危險許可權-->    <uses-permission android:name="android.permission.RECORD_AUDIO"/>    <!--一般許可權-->    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

危險許可權必須要授權, 一般許可權不需要.

檢測權限類別

/** * 檢查許可權的工具類 * <p/> * Created by wangchenlong on 16/1/26. */public class PermissionsChecker {    private final Context mContext;    public PermissionsChecker(Context context) {        mContext = context.getApplicationContext();    }    // 判斷許可權集合    public boolean lacksPermissions(String... permissions) {        for (String permission : permissions) {            if (lacksPermission(permission)) {                return true;            }        }        return false;    }    // 判斷是否缺少許可權    private boolean lacksPermission(String permission) {        return ContextCompat.checkSelfPermission(mContext, permission) ==                PackageManager.PERMISSION_DENIED;    }}
2. 首頁

假設首頁需要使用許可權, 在頁面顯示前, 即onResume時, 檢測許可權,
如果缺少, 則進入許可權擷取頁面; 接收傳回值, 拒絕許可權時, 直接關閉.

public class MainActivity extends AppCompatActivity {    private static final int REQUEST_CODE = 0; // 請求碼    // 所需的全部許可權    static final String[] PERMISSIONS = new String[]{            Manifest.permission.RECORD_AUDIO,            Manifest.permission.MODIFY_AUDIO_SETTINGS    };    @Bind(R.id.main_t_toolbar) Toolbar mTToolbar;    private PermissionsChecker mPermissionsChecker; // 許可權檢測器    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);        setSupportActionBar(mTToolbar);        mPermissionsChecker = new PermissionsChecker(this);    }    @Override protected void onResume() {        super.onResume();        // 缺少許可權時, 進入許可權配置頁面        if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) {            startPermissionsActivity();        }    }    private void startPermissionsActivity() {        PermissionsActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);    }    @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        // 拒絕時, 關閉頁面, 缺少主要許可權, 無法運行        if (requestCode == REQUEST_CODE && resultCode == PermissionsActivity.PERMISSIONS_DENIED) {            finish();        }    }}

核心許可權必須滿足, 如攝像應用, 網路攝影機許可權就是必須的, 如果使用者不予授權, 則直接關閉.

3. 授權頁

授權頁, 首先使用系統預設的授權頁, 當使用者拒絕時, 指導使用者手動設定, 當使用者再次操作失敗後, 返回繼續提示. 使用者手動退出授權頁時, 給使用頁發送授權失敗的通知.

/** * 許可權擷取頁面 * <p/> * Created by wangchenlong on 16/1/26. */public class PermissionsActivity extends AppCompatActivity {    public static final int PERMISSIONS_GRANTED = 0; // 許可權授權    public static final int PERMISSIONS_DENIED = 1; // 許可權拒絕    private static final int PERMISSION_REQUEST_CODE = 0; // 系統許可權管理頁面的參數    private static final String EXTRA_PERMISSIONS =            "me.chunyu.clwang.permission.extra_permission"; // 許可權參數    private static final String PACKAGE_URL_SCHEME = "package:"; // 方案    private PermissionsChecker mChecker; // 許可權檢測器    private boolean isRequireCheck; // 是否需要系統許可權檢測    // 啟動當前許可權頁面的公開介面    public static void startActivityForResult(Activity activity, int requestCode, String... permissions) {        Intent intent = new Intent(activity, PermissionsActivity.class);        intent.putExtra(EXTRA_PERMISSIONS, permissions);        ActivityCompat.startActivityForResult(activity, intent, requestCode, null);    }    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getIntent() == null || !getIntent().hasExtra(EXTRA_PERMISSIONS)) {            throw new RuntimeException("PermissionsActivity需要使用靜態startActivityForResult方法啟動!");        }        setContentView(R.layout.activity_permissions);        mChecker = new PermissionsChecker(this);        isRequireCheck = true;    }    @Override protected void onResume() {        super.onResume();        if (isRequireCheck) {            String[] permissions = getPermissions();            if (mChecker.lacksPermissions(permissions)) {                requestPermissions(permissions); // 請求許可權            } else {                allPermissionsGranted(); // 全部許可權都已擷取            }        } else {            isRequireCheck = true;        }    }    // 返回傳遞的許可權參數    private String[] getPermissions() {        return getIntent().getStringArrayExtra(EXTRA_PERMISSIONS);    }    // 請求許可權相容低版本    private void requestPermissions(String... permissions) {        ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);    }    // 全部許可權均已擷取    private void allPermissionsGranted() {        setResult(PERMISSIONS_GRANTED);        finish();    }    /**     * 使用者權限處理,     * 如果全部擷取, 則直接過.     * 如果許可權缺失, 則提示Dialog.     *     * @param requestCode  請求碼     * @param permissions  許可權     * @param grantResults 結果     */    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {            isRequireCheck = true;            allPermissionsGranted();        } else {            isRequireCheck = false;            showMissingPermissionDialog();        }    }    // 含有全部的許可權    private boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {        for (int grantResult : grantResults) {            if (grantResult == PackageManager.PERMISSION_DENIED) {                return false;            }        }        return true;    }    // 顯示缺失許可權提示    private void showMissingPermissionDialog() {        AlertDialog.Builder builder = new AlertDialog.Builder(PermissionsActivity.this);        builder.setTitle(R.string.help);        builder.setMessage(R.string.string_help_text);        // 拒絕, 退出應用        builder.setNegativeButton(R.string.quit, new DialogInterface.OnClickListener() {            @Override public void onClick(DialogInterface dialog, int which) {                setResult(PERMISSIONS_DENIED);                finish();            }        });        builder.setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() {            @Override public void onClick(DialogInterface dialog, int which) {                startAppSettings();            }        });        builder.show();    }    // 啟動應用的設定    private void startAppSettings() {        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);        intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));        startActivity(intent);    }}

注意isRequireCheck參數的使用, 防止和系統提示框重疊.
系統授權提示: ActivityCompat.requestPermissions, ActivityCompat相容低版本.

效果


自訂授權

關鍵區段就這些了, 動態許可權授權雖然給程式員帶來了一些麻煩, 但是對使用者還是很有必要的, 我們也應該歡迎, 畢竟每個程式員都是半個產品經理.

危險許可權列表

 

Android 6.0 - 動態許可權管理的解決方案(轉)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.