我的看法
最近随着6.0版本的扩散,我发现了一些权限问题,有视频,拍照,语音等等都涉及到。
在6.0版本,android增加了一个权限管理,如果项目使用api23以上,但是代码中如果不添加请求权限代码的话,那么则会报错。
如果程序中调用了语音方面的话,这属于危险级别权限,如果不在AndroidManifest添加权限,一旦调用语音也会报错。
有人说将api改成23以下就好了,我认为这段时间的确可以将就下,但是随着android版本的迭代快速的情况下,越早了解越早掌握权限这方面功能越好。
转
这个链接十分详细的介绍了权限细节以及如何请求。
//www.greatytc.com/p/dbe4d37731e6(/p/dbe4d37731e6)
第三方库动态权限检测,一句话代码搞定!
https://github.com/forJrking/HeiPermission(https://github.com/forJrking/HeiPermission)
权限组
权限组 | 权限 |
---|---|
CALENDAR日历 | READ_CALENDAR |
WRITE_CALENDAR | |
CAMERA相机 | CAMERA |
WRITE_CALENDAR | |
CAMERA联络 | READ_CONTACTS |
WRITE_CONTACTS | |
GET_ACCOUNTS | |
LOCATION位置 | ACCESS_FINE_LOCATION 允许一个程序访问精良位置(如GPS) (Allows an application to access fine (e.g., GPS) location) |
ACCESS_COARSE_LOCATION 允许一个程序访问CellID或WiFi热点来获取粗略的位置(Allows an application to access coarse (e.g., Cell-ID, WiFi) location) | |
MICROPHONE麦克风 | RECORD_AUDIO |
PHONE电话 | READ_PHONE_STATE |
CALL_PHONE | |
READ_CALL_LOG | |
WRITE_CALL_LOG | |
ADD_VOICEMAIL | |
USE_SIP | |
PROCESS_OUTGOING_CALLS | |
SENSORS传感器 | BODY_SENSORS |
SMS短讯服务 | SEND_SMS |
RECEIVE_SMS | |
READ_SMS | |
RECEIVE_WAP_PUSH | |
RECEIVE_MMS | |
STORAGE存储 | READ_EXTERNAL_STORAGE |
WRITE_EXTERNAL_STORAGE |
我的应用这么写
其实基本核心就这两段代码
这个用来请求权限
public static final int EXTERNAL_STORAGE_REQ_CODE = 10 ;
public void requestPermission(){
//判断当前Activity是否已经获得了该权限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//如果App的权限申请曾经被用户拒绝过,就需要在这里跟用户做出解释
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this,"please give me the permission",Toast.LENGTH_SHORT).show();
} else {
//进行权限请求
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
EXTERNAL_STORAGE_REQ_CODE);
}
}
}
当用户操作后,就跳到该方法
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case EXTERNAL_STORAGE_REQ_CODE: {
// 如果请求被拒绝,那么通常grantResults数组为空
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申请成功,进行相应操作
} else {
//申请失败,可以继续向用户解释。
}
return;
}
}
}
可以再改进一些
1.像我的日记diary,写入sd卡这个权限是必要的,所以是在app欢迎界面的时候,就进行了权限要求,如果客户拒绝,那就循环请求:) 哈哈哈哈哈
2.解释为什么需要这些权限是很有必要的
改进后的代码
逻辑:比如我的日记diary需要相机、麦克风、存储权限,并且我需要开始app的时候就启动请求权限,只有存储权限是必要的。而相机、麦克风权限,可以在使用的时候再请求
/* *
* 这是根据设置来切换风格的
* Created by zhongjh on 2016/3/12.
*/
public class StartActivity extends ToolBarActivity {
//存储请求权限的requestCode
public static final int EXTERNAL_STORAGE_REQ_CODE = 1;
// //拍照请求权限的requestCode
// public static final int EXTERNAL_CAMERA_REQ_CODE = 2;
// //麦克风请求权限的requestCode
// public static final int MICROPHONE_STORAGE_REQ_CODE = 3;
@Override
protected void onInitCreate(Bundle savedInstanceState) {
//请求存储权限
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, "日记diary需要请求您的SD卡权限!把数据存储在SD卡方便您私人移植!否则运行不了日记diary!", EXTERNAL_STORAGE_REQ_CODE)) {
start();
}
}
@Override
protected void onInitListener() {
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case EXTERNAL_STORAGE_REQ_CODE: {
// 如果请求被拒绝,那么通常grantResults数组为空
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申请成功,进行相应操作
Toast.makeText(this, "授权成功!请重新打开日记diary让数据库生效!", Toast.LENGTH_SHORT).show();
StartActivity.this.finish();
} else {
//申请失败,可以继续向用户解释。
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, "日记diary需要请求您的SD卡权限!把数据存储在SD卡方便您私人移植!否则运行不了日记diary!", EXTERNAL_STORAGE_REQ_CODE);
}
}
}
}
/**
* 所有授权都通过了就显示正式的app
*/
private void start() {
requestWindowFeature(Window.FEATURE_NO_TITLE);// 填充标题栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
SharedPreferences sp = getActivity().getSharedPreferences(UserSetting.SETTING, MODE_PRIVATE);
int setting_main = sp.getInt(UserSetting.SETTING_MAIN, -1);
Intent intent = new Intent();
//根据类型打开窗体
switch (setting_main) {
case 0:
intent.setClass(getActivity(), MainActivity.class);
startActivity(intent);
break;
case 1:
intent.setClass(getActivity(), MainTwoActivity.class);
startActivity(intent);
break;
case -1:
//这是个欢迎界面,这个欢迎界面结束后就赋值setting_main为1
intent.setClass(getActivity(), PagerActivity.class);
startActivity(intent);
break;
}
getActivity().finish();
}
/**
* @param permission 权限
* @param ContentText 对话框提示内容
* @param requestCode 权限请求号,返回时需要用到
* @return 是否授权
*/
public boolean requestPermission(String permission, String ContentText, int requestCode) {
//判断当前Activity是否已经获得了该权限
if (ContextCompat.checkSelfPermission(this,
permission)
!= PackageManager.PERMISSION_GRANTED) {
//如果App的权限申请曾经被用户拒绝过,就需要在这里跟用户做出解释
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
permission)) {
// 构造对话框
SweetAlertDialog sweetAlertDialog = new SweetAlertDialog(getActivity(), SweetAlertDialog.WARNING_TYPE);
sweetAlertDialog.setContentText(ContentText);
sweetAlertDialog.setCancelable(false);
sweetAlertDialog.setConfirmText("确定");
sweetAlertDialog.setConfirmClickListener(sweetAlertDialog1 -> {
sweetAlertDialog1.dismiss();
//进行权限请求
ActivityCompat.requestPermissions(this,
new String[]{permission},
requestCode);
});
sweetAlertDialog.show();
} else {
//进行权限请求
ActivityCompat.requestPermissions(this,
new String[]{permission},
requestCode);
}
return false;
} else {
return true;
}
}
}