android 6.0以上权限,我是通过PermissionsDispatcher进行申请,操作的,具体使用方法,见PermissionsDispatcher,Android 6.0运行时权限详解
@RuntimePermissions
public class SplashActivity extends BaseCompatActivity
....
@TargetApi(Build.VERSION_CODES.M)
private void requestPermission()
{
//申请权限
SplashActivityPermissionsDispatcher.doNeedsPermissionWithCheck(this);
}
//6.0权限控制
@NeedsPermission({Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE})
void doNeedsPermission()
{
toLogin();
}
/**
* 权限请求回调,提示用户之后,用户点击“允许”或者“拒绝”之后调用此方法
*
* @param requestCode 定义的权限编码
* @param permissions 权限名称
* @param grantResults 允许/拒绝
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
SplashActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
@OnShowRationale({Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE})
void showRationale(PermissionRequest request)
{
request.proceed(); // 提示用户权限使用的对话框
}
/**
* 如果用户拒绝该权限执行的方法
*/
@OnPermissionDenied({Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE})
void onPermissionDenied()
{
toLogin();
}
@OnNeverAskAgain({Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE})
void onNeverAskAgain()
{
toLogin();
}
6.0以下,检测权限的方法,只要Manifest.xml有注册这个权限,那么就返回true在网上找了很多检测权限的方法,最后证明都无效
现在把有效的方法说一下,SystemUtils类
//Android6.0以下的摄像头权限处理:
public static boolean isCameraCanUse() {
boolean canUse = true;
Camera mCamera = null;
try {
mCamera = Camera.open();
// setParameters 是针对魅族MX5 做的。MX5 通过Camera.open() 拿到的Camera
Camera.Parameters mParameters = mCamera.getParameters();
mCamera.setParameters(mParameters);
} catch (Exception e) {
canUse = false;
}
if (mCamera != null) {
mCamera.release();
}
return canUse;
}
/**
* 判断是是否有录音权限
*/
public static boolean isHasPermission(final Context context)
{
// 音频获取源
int audioSource = MediaRecorder.AudioSource.MIC;
// 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025
int sampleRateInHz = 44100;
// 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道
int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
// 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
// 缓冲区字节大小
int bufferSizeInBytes = 0;
bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);
//开始录制音频
try
{
// 防止某些手机崩溃
audioRecord.startRecording();
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
/**
* 根据开始录音判断是否有录音权限
*/
if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING)
{
return false;
}
//根据录音长度判断
byte[] bytes = new byte[1024];
int readSize = audioRecord.read(bytes, 0, 1024); //至于为什么写1024 我也不知道
if (readSize == AudioRecord.ERROR_INVALID_OPERATION || readSize <= 0)
{
return false;
}
//如果短时间内频繁检测,会造成audioRecord还未销毁完成,此时检测会返回RECORDSTATE_STOPPED状态,再去read,会读到0的size,所以此时默认权限通过
if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED)
{
return true;
}
audioRecord.stop();
audioRecord.release();//释放资源
audioRecord = null;
return true;
}
电话权限,即使关闭了,还是能拨打电话,只能说通过try-catch尝试进行判断,如果不想这么麻烦,可以使用不需要权限的拨打电话的方法
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + mobile));
context.startActivity(intent);
定位权限,关闭权限以后,还是可以定位,参照百度地图,高德地图,微信,qq,所以如果通过关闭定位权限,不让app定位,这个恐怕不行,只有关闭gps或者网络才可以不让定位
/**
* 手机是否开启位置服务,如果没有开启那么所有app将不能使用定位功能
*/
public static boolean isLocServiceEnable(Activity context)
{
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (gps || network)
{
return true;
}
return false;
}
通过动态申请的方法,用户可以关闭权限,或者点击不再询问,这样在用到权限的操作的时候,可能会崩溃,这个要在操作之前,进行一些权限检测,这个要分6.0以上和6.0以下的情况
//6.0以上检测某个权限是否已申请
public static boolean checkPermission(Context mContexts, String permissionName)
{
PackageManager pm = mContexts.getPackageManager();
boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission(permissionName, getPackageInfo(mContexts).packageName));
return permission;
}
自定义一个dialog,作为提示
public static void showPermissionDialog(Activity activity, String info)
{
final NoticeDialog noticeDialog = new NoticeDialog(activity);
noticeDialog.setTvSureContentVisible(true);
noticeDialog.setBottomButtonLayoutVisible(false);
noticeDialog.setNoticeContent(info + "权限已关闭,请您去手机设置中开启。");
noticeDialog.setSureButtonText("确定");
noticeDialog.setSureListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
noticeDialog.dismiss();
}
});
noticeDialog.showAtLocation(activity.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
}
封装一个检测是否有麦克风权限的方法
public static boolean isHasRecordPermission(Activity activity)
{
boolean hasPermission = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if (!checkPermission(activity, "android.permission.RECORD_AUDIO"))
{
hasPermission = false;
}
}
else
{
if (!isHasPermission(activity))
{
hasPermission = false;
}
}
return hasPermission;
}
使用方法:
相机权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(!SystemUtils.checkPermission(ChooseFamilyMemberActivity.this,"android.permission.CAMERA")
){
SystemUtils. showPermissionDialog(ChooseFamilyMemberActivity.this,"相机");
return;
}
}else{
if (!SystemUtils.isCameraCanUse())
{//针对6.0以下
SystemUtils. showPermissionDialog(ChooseFamilyMemberActivity.this,"相机");
return;
}
}
定位权限
if(!SystemUtils.checkPermission(context,"android.permission.ACCESS_FINE_LOCATION")
||!SystemUtils.checkPermission(context,"android.permission.ACCESS_COARSE_LOCATION")){
SystemUtils.showPermissionDialog(context,"位置");
return;
}
if(!SystemUtils.isLocServiceEnable(context)){
final NoticeDialog noticeDialog = new NoticeDialog(context);
noticeDialog.setTitleVisible(true);
noticeDialog.setTitle("提示");
noticeDialog.setNoticeContent("定位不可用,请打开gps或者网络");
noticeDialog.setBottomButtonLayoutVisible(false);
noticeDialog.setTvSureContentVisible(true);
noticeDialog.setSureButtonText("确定");
noticeDialog.setSureListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
noticeDialog.dismiss();
}
});
noticeDialog.showAtLocation(context.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
return;
}
麦克风权限
if (!SystemUtils.isHasRecordPermission(activity))
{
SystemUtils.showPermissionDialog(activity, "麦克风");
return;
}
参考资料
Android6.0权限机制(三):6.0以前国产手机权限处理