实现UC浏览器启动应用时引导用户开启存储空间权限

来源:互联网 发布:淘宝联盟微信推广软件 编辑:程序博客网 时间:2024/04/28 10:13
在Android6.0之前,需要声明权限时,我们只需在AndroidManifest.xml中声明即可。但是在Android6.0之后的版本中,我们除了需要在AndroidManifest.xml中声明之外,还需要在使用该权限时动态向用户申请,且只有当用户允许以后,才能够正常使用。

如果我们的应用在使用过程中,必须要使用到外部存储空间,比如下载类、工具类应用,那么如何友好的引导用户开启存储空间权限呢?意外发现UC给出了一个很好的交互设计。

如图所示:


(1).应用开启时,在启动页检查是否开启了存储空间权限。如果已经开启,则直接进入应用;若未开启,弹出对话框引导用户开启权限。
(2).用户在点击下一步按钮时,当前对话框消失,并弹出系统权限请求对话框。如果用户点击允许,此时成功获取权限,直接进入应用;如果用户拒绝,则弹出下一个对话框。
(3).权限被拒绝后,会弹出该对话框。如果用户不愿意开启权限,点击退出会直接退出应用;如果用户想开启权限,点击前往设置按钮,可进入系统设置中选择开启权限,此时打开权限并返回到我们的应用中,会直接进入主界面。

好了,下面我们来使用代码一步步实现。

首先在清单文件中声明读写外部存储的权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

1.1 检查存储空间权限是否开启。
private boolean isPermissionAllowed() {    int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);    return permission == PackageManager.PERMISSION_GRANTED;}
ContextCompat是android.support.v4兼容包中的类,调用checkSelfPermission()方法并传入参数WRITE_EXTERNAL_STORAGE检查是否开启了存储空间权限。WRITE_EXTERNAL_STORAGE与READ_EXTERNAL_STORAGE两个权限使用任意一个即可,成功开启一个权限之后,另一个权限也可正常使用。

1.2 我们在Activity的onCreate()方法中,调用如下checkPermission()方法。
private void checkPermission() {    if (isPermissionAllowed()) {        startMainActivity();    } else {        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {            showStorageFailDialog();        } else {            showOpenStorageDialog();        }    }}
在方法内部,先检查权限是否开启。isPermissionAllowed()方法在6.0之前的系统中会直接返回true,6.0以上系统中只有在手动开启权限后才会返回true。在权限未开启的情况下,调用ActivityCompat.shouldShowRequestPermissionRationale()方法判断用户是否拒绝过该权限,若未拒绝过就显示“引导开启权限”的对话框,若之前已拒绝,则显示“权限授权失败”的对话框。showOpenStorageDialog()和showStorageFailDialog()方法会在后面介绍。

2.1 当isPermissionAllowed()返回false时,显示对话框引导用户开启权限。
private void showOpenStorageDialog() {    final AppCompatDialog dialog = new AppCompatDialog(this, R.style.no_title_dialog);    View view = LayoutInflater.from(this).inflate(R.layout.dialog_open_storage, null);    view.findViewById(R.id.next).setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            requestPermission();            dialog.dismiss();        }    });    int screenWidth = getResources().getDisplayMetrics().widthPixels;    ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(screenWidth * 4 / 5, ViewGroup.LayoutParams.WRAP_CONTENT);    dialog.setContentView(view, params);    dialog.setCancelable(false);    dialog.setCanceledOnTouchOutside(false);    dialog.show();}private static final int REQUEST_CODE_STORAGE = 1;private void requestPermission() {    ActivityCompat.requestPermissions(this,            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_STORAGE);}
这里将Dialog的Cancelable和CanceledOnTouchOutside都设置为false,用户无法直接取消对话框。当点击下一步时,调用ActivityCompat类的requestPermissions()方法,请求系统权限。

2.2 当弹出系统权限对话框时,用户可以选择禁止或允许,选择完成后onRequestPermissionsResult()方法被回调,我们重写Activity的onRequestPermissionsResult()方法获取返回结果。
@Overridepublic void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {    if (requestCode == REQUEST_CODE_STORAGE) {        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {            startMainActivity();        } else {            showStorageFailDialog();        }    }}
返回结果通过参数grantResults传递过来。我们判断如果grantResults数组中有值并且等于PERMISSION_GRANTED时,表示用户点击了允许,此时可以直接进入应用了。如果用户拒绝了权限,调用showStorageFailDialog()方法弹出权限获取失败的对话框。

3.1 显示存储空间权限获取失败的对话框。
private void showStorageFailDialog() {    final AppCompatDialog dialog = new AppCompatDialog(this, R.style.no_title_dialog);    View view = LayoutInflater.from(this).inflate(R.layout.dialog_storage_fail, null);    TextView hintText = (TextView) view.findViewById(R.id.hint);    SpannableString hint = new SpannableString(hintText.getText());    hint.setSpan(new ForegroundColorSpan(Color.parseColor("#333333")), 10, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    hintText.setText(hint);    view.findViewById(R.id.exit).setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            finish();        }    });    view.findViewById(R.id.start_setting).setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            mIsStartSetting = true;            startApplicationDetailsSetting();        }    });    int screenWidth = getResources().getDisplayMetrics().widthPixels;    ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(screenWidth * 4 / 5, ViewGroup.LayoutParams.WRAP_CONTENT);    dialog.setContentView(view, params);    dialog.setCancelable(false);    dialog.setCanceledOnTouchOutside(false);    dialog.show();}private boolean mIsStartSetting = false;private void startApplicationDetailsSetting() {    Uri uri = Uri.parse("package:" + getPackageName());    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, uri);    startActivity(intent);}
在该对话框中,我们会告诉用户必须要开启权限。用户不愿意,点击退出按钮可退出应用。如果想要进入应用,只能点击前往设置,进入系统的权限管理界面,引导用户开启存储空间权限。

3.2 上面在进入系统设置界面时,我们将mIsStartSetting变量设为true。当从系统设置界面返回时,Activity的onResume()方法被调用,在这里我们再次判断权限是否开启,如果成功开启就可以进入主界面了。若未开启,则权限授权失败的对话框会一直显示。
@Overrideprotected void onResume() {    super.onResume();    if (mIsStartSetting) {        mIsStartSetting = false;        if (isPermissionAllowed()) {            startMainActivity();        }    }}

最后附上完整工程代码下载链接:
http://download.csdn.net/detail/ruancoder/9718806
0 0