版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
随着Android6.0的普及,权限申请也变成了我们开发中必写的一段代码。比如sd卡权限、定位权限、拍照权限,这些几乎都是每个app必备的。而一般情况下我们都会在需要权限之前申请,然后各种判断。那既然是一些必备的是权限,我们为何不在我们一次打开app的时候就把这个全部都申请了呢?可是一下申请那么多权限对用户来说显然不是很友好,所以我们不妨在申请权限之前告诉一下用户,好让用户有个心理准备。于是借鉴了饿了么的权限申请界面,封装了一个对话框。
这个对话框只是用来展现应用当中需要用到的权限列表,不具备申请权限的功能,申请权限请搭配相关第三方库,比如《 》;另外,考虑到这个对话框一般在APP首次使用的时候才会弹出来,所以搭配《 》实现保存状态值,用于判断是否需要显示这个对话框。
效果图
代码分析
PermissionDialog:对话框界面,继承AlertDialog
使用步骤
一、项目组织结构图
注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
1、将PermissionDialog.java文件复制到项目中
package com.why.project.permissiondialog.dialog;import android.app.Activity;import android.app.AlertDialog;import android.content.Context;import android.graphics.Color;import android.graphics.ColorMatrixColorFilter;import android.os.Bundle;import android.support.v4.content.ContextCompat;import android.util.DisplayMetrics;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ScrollView;import android.widget.TextView;import com.why.project.permissiondialog.R;/** * Created by HaiyuKing * Used 权限申请对话框 */public class PermissionDialog extends AlertDialog { //上下文 private Context mContext; //内容的父节点,用于内容较多时可以滚动 private ScrollView mListScroll; //内容 private LinearLayout mListLayout; //确认按钮 private TextView mConfirmBtn; public PermissionDialog(Context context) { //设置对话框样式 super(context, R.style.style_permission_dialog); //设置为false,按对话框以外的地方不起作用 setCanceledOnTouchOutside(false); //设置为false,按返回键不能退出 setCancelable(false); this.mContext = context; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.permission_dialog_layout); initViews(); initDatas(); initEvents(); } /**初始化view*/ private void initViews() { mListScroll = findViewById(R.id.permission_dialog_list_scroll); mListLayout = findViewById(R.id.layout_list); mConfirmBtn = findViewById(R.id.dialog_confirm_btn); } /**初始化数据*/ private void initDatas() { //获取图标的颜色值 int mFilterColor = ContextCompat.getColor(mContext,R.color.permission_dialog_img_color); int blue = Color.blue(mFilterColor); int green = Color.green(mFilterColor); int red = Color.red(mFilterColor); float[] cm = new float[]{ 1, 0, 0, 0, red,// 红色值 0, 1, 0, 0, green,// 绿色值 0, 0, 1, 0, blue,// 蓝色值 0, 0, 0, 1, 1 // 透明度 }; ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm); //初始化权限列表区域 int[] permissionImgIds = mContext.getResources().getIntArray(R.array.permission_icon); String[] permissionTitles = mContext.getResources().getStringArray(R.array.permission_title); String[] permissionInfos = mContext.getResources().getStringArray(R.array.permission_info); for(int i = 0; i < permissionImgIds.length; i++){ String title = permissionTitles[i]; String info = permissionInfos[i]; View itemView = View.inflate(mContext,R.layout.permission_list_item,null); ((ImageView)itemView.findViewById(R.id.item_img)).setImageResource(mContext.getResources().obtainTypedArray(R.array.permission_icon).getResourceId(i, 0)); ((ImageView)itemView.findViewById(R.id.item_img)).setColorFilter(filter);//设置图标的颜色 ((TextView)itemView.findViewById(R.id.item_title)).setText(title); ((TextView)itemView.findViewById(R.id.item_info)).setText(info); mListLayout.addView(itemView); } //设置内容区域的父节点的高度和内容文本大小 final DisplayMetrics display = new DisplayMetrics(); ((Activity)this.mContext).getWindowManager().getDefaultDisplay().getMetrics(display); final int screenHeight = display.heightPixels; //先设置宽度,然后再调整高度 mListScroll.setLayoutParams(new LinearLayout.LayoutParams(display.widthPixels - mContext.getResources().getDimensionPixelOffset(R.dimen.permission_dialog_margin) * 2, ViewGroup.LayoutParams.WRAP_CONTENT)); //runnable中的方法会在View的measure、layout等事件后触发 mListScroll.post(new Runnable() { @Override public void run() { if (mListScroll.getMeasuredHeight() > screenHeight / 2) { mListScroll.setLayoutParams(new LinearLayout.LayoutParams(display.widthPixels - mContext.getResources().getDimensionPixelOffset(R.dimen.permission_dialog_margin) * 2, screenHeight / 2)); }else{ //屏幕宽度减去外边距*2 mListScroll.setLayoutParams(new LinearLayout.LayoutParams(display.widthPixels - mContext.getResources().getDimensionPixelOffset(R.dimen.permission_dialog_margin) * 2, ViewGroup.LayoutParams.WRAP_CONTENT)); } } }); } /**初始化监听事件*/ private void initEvents() { mConfirmBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(mOnCertainButtonClickListener != null){ mOnCertainButtonClickListener.onCertainButtonClick(); } dismiss(); } }); } @Override public void dismiss() { super.dismiss(); } public static abstract interface OnCertainButtonClickListener { //确认按钮的点击事件接口 public abstract void onCertainButtonClick(); } private OnCertainButtonClickListener mOnCertainButtonClickListener; public void setOnCertainButtonClickListener(OnCertainButtonClickListener mOnCertainButtonClickListener) { this.mOnCertainButtonClickListener = mOnCertainButtonClickListener; }}
2、将permission_dialog_bg.xml、permission_dialog_one_btn_bg.xml复制到drawable目录下
3、将图片资源复制到drawable-xxhdpi目录下
4、将permission_dialog_layout.xml、permission_list_item.xml布局文件复制到项目中
5、在arrays.xml中添加以下代码【根据实际情况,通过注释控制图标的个数,标题、说明数组需要和图标数组一一对应】
- @drawable/permission_ic_storage
- @drawable/permission_ic_camera
- @drawable/permission_ic_location
- @drawable/permission_ic_phone
- @drawable/permission_ic_micro_phone
- @drawable/permission_ic_calendar
- @drawable/permission_ic_contacts
- @drawable/permission_ic_sms
- @drawable/permission_ic_sensors
- 文件存储
- 相机相册
- 位置信息
- 电话状态
- 录制声音
- 日程信息
- 通讯录
- 短信信息
- 传感器
- 允许应用读取、写入外部存储
- 允许应用访问摄像头进行拍照
- 允许应用获取定位信息
- 允许应用访问电话状态
- 允许应用通过手机或耳机的麦克录制声音
- 允许应用读取用户的日程信息
- 允许应用访问联系人通讯录信息
- 允许应用获取短信信息
- 允许应用获取传感器信息
6、在colors.xml中添加以下代码【根据实际情况设置图标和按钮的背景颜色值】
#008577 #00574B #D81B60 #ffffffff #000000 #87000000 #000000 #07b4a2 #FFFFFF
7、在dimens.xml中添加以下代码
16dp 16dp 8dp 30dp 15dp 22sp 16sp 8dp 16sp
8、在strings.xml中添加以下代码
PermissionDialog 权限申请 为了您能正常使用,需要以下权限
9、在styles.xml中添加以下代码
三、使用方法
在代码中调用如下:
package com.why.project.permissiondialog;import android.os.Build;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import com.why.project.permissiondialog.dialog.PermissionDialog;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_showdialog).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { boolean hasShow = PreferencesUtils.getBoolean(MainActivity.this,PreferencesUtils.HAS_SHOW_PREMISSION_DIALOG,false); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ! hasShow){ PermissionDialog permissionDialog = new PermissionDialog(MainActivity.this); permissionDialog.setOnCertainButtonClickListener(new PermissionDialog.OnCertainButtonClickListener() { @Override public void onCertainButtonClick() { //搭配SharedPreferences 将状态值记录下来,实现APP首次打开的时候才会弹出这个对话框 PreferencesUtils.putBoolean(MainActivity.this,PreferencesUtils.HAS_SHOW_PREMISSION_DIALOG,true); //调用运行时权限申请框架 } }); permissionDialog.show(); }else{ //调用运行时权限申请框架 } } }); }}
注意:
实际项目中,需要手动调整arrays.xml文件中的权限数组个数,不显示的注释掉,保证三个数组的一一对应;
根据项目的主题颜色,调整colors.xml文件中的图标、按钮的背景颜色值;
混淆配置
无