android6.0或以上版本,如果目标SDK 大于等于23,就需要做好动态申请权限,具体看网上文章,如果不适配,最多就是权限有时候被限制了,然后只能报错,所以还是都适配一下最好。几乎是必须的。android自然的API,需要在Activity 中使用,而且有一个回调函数,所以我们稍变通一下,采用一个新建的透明Activity 来响应这个动态申请权限,申请完毕,在回调时候关闭即可,给用户的感觉也想是当前界面在响应。
package com.show.blue.utils;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import com.support.loader.utils.LogBlue;
import java.util.ArrayList;
import java.util.List;
/**
* 动态申请权限
* Created by liangzhenxiong on 16/2/16.
*/
public class PermissionActivity extends Activity {
final static int REQUEST_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<String> newPermissions = getIntent().getStringArrayListExtra("newPermissions");
if (newPermissions == null) {
finish();
return;
}
handle(newPermissions);
}
private void handle(ArrayList<String> newPermissions) {
for (String permission : newPermissions) {
boolean already_request = ActivityCompat.shouldShowRequestPermissionRationale(PermissionActivity.this, permission);
if (already_request) {
PermissionListener.showWhy(newPermissions);
finish();
return;
}
}
ActivityCompat.requestPermissions(PermissionActivity.this,
newPermissions.toArray(new String[newPermissions.size()]),
REQUEST_CODE);
}
public interface PermissionListener {
void allow();//权限允许
void decline();//权限拒绝
void showWhy(ArrayList<String> permissions);//权限已经被拒绝,弹窗解析,第一次弹窗被拒绝
}
private static PermissionListener PermissionListener;
public static boolean ShowRequestPermission(Context context, String[] permissions, PermissionListener permissionListener) {
PermissionListener = null;
if (permissionListener == null) {
return false;
} else {
if (permissions == null || permissions.length == 0) {
permissionListener.allow();
return true;
}
int targetSDKVer = context.getApplicationInfo().targetSdkVersion; //只有目标SDK大于等于23的才会有授权
if (targetSDKVer >= 23 && Build.VERSION.SDK_INT >= 23) {
ArrayList<String> newPermissions = showPermission(context, permissions);
if (newPermissions.size() == 0) {
permissionListener.allow();
} else {
Intent intent = new Intent();
PermissionListener = permissionListener;
intent.putStringArrayListExtra("newPermissions", newPermissions);
intent.setClass(context, PermissionActivity.class);
context.startActivity(intent);
}
return true;
} else {
PackageManager packageManager = context.getPackageManager();
String packageName = context.getPackageName();
final int permissionCount = permissions.length;
for (int i = 0; i < permissionCount; i++) {
int grant = packageManager.checkPermission(
permissions[i], packageName);
if (grant == PackageManager.PERMISSION_DENIED) {
permissionListener.decline();
return true;
}
}
permissionListener.allow();
return true;
}
}
}
private static ArrayList<String> showPermission(Context context, String[] permissions) {
ArrayList<String> newPermissions = new ArrayList<>(permissions.length);
for (String permission : permissions) {
int PERMISSION_GRANTED = ContextCompat.
checkSelfPermission(context, permission);
LogBlue.i("TAG", "===" + PERMISSION_GRANTED);
if (PackageManager.PERMISSION_DENIED == PERMISSION_GRANTED) {
newPermissions.add(permission);
}
}
return newPermissions;
}
@Override
protected void onDestroy() {
super.onDestroy();
PermissionListener = null;
}
@Override
@SuppressLint("NewApi")
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (REQUEST_CODE == requestCode) {
if (grantResults.length > 0) {
for (int grant : grantResults) {
if (grant != PackageManager.PERMISSION_GRANTED) {
if (PermissionListener != null) {
PermissionListener.decline();
PermissionListener = null;
break;
}
}
}
if (PermissionListener != null) {
PermissionListener.allow();
}
}
}
PermissionListener = null;
finish();
}
}
调用代码
PermissionActivity.ShowRequestPermission(this, new String[]{Manifest.permission.WRITE_CONTACTS, Manifest.permission.CAMERA},
new PermissionActivity.PermissionListener() {
@Override
public void allow() {
ShowToast.showTips(LauncherActivity.this, "允许权限");
}
@Override
public void decline() {
ShowToast.showTips(LauncherActivity.this, "拒绝权限");
}
@Override
public void showWhy(ArrayList<String> permissions) {
ShowToast.showTips(LauncherActivity.this, "权限已经被拒绝,弹窗解析,第一次弹窗被拒绝");
}
});
以上代码是动态申请部分权限代码,适合在
targetSdkVersion>=23时候
只要在23或以上的目标版本,系统才认为采用动态申请权限,采用透明Activity 然后回调响应,具体看代码,建议采用V4包做适配;
权限很简单,只是封装一下,哪里用哪里调用,而不用每个Activity都创建权限的回调函数,无需关联APP界面
下面用别人博客copy过来
PROTECTION_NORMAL类权限
当用户安装或更新应用时,系统将授予应用所请求的属于 PROTECTION_NORMAL 的所有权限(安装时授权的一类基本权限)。这类权限包括:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | android.permission.ACCESS_LOCATION_EXTRA_COMMANDS android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_NOTIFICATION_POLICY android.permission.ACCESS_WIFI_STATE android.permission.ACCESS_WIMAX_STATE android.permission.BLUETOOTH android.permission.BLUETOOTH_ADMIN android.permission.BROADCAST_STICKY android.permission.CHANGE_NETWORK_STATE android.permission.CHANGE_WIFI_MULTICAST_STATE android.permission.CHANGE_WIFI_STATE android.permission.CHANGE_WIMAX_STATE android.permission.DISABLE_KEYGUARD android.permission.EXPAND_STATUS_BAR android.permission.FLASHLIGHT android.permission.GET_ACCOUNTS android.permission.GET_PACKAGE_SIZE android.permission.INTERNET android.permission.KILL_BACKGROUND_PROCESSES android.permission.MODIFY_AUDIO_SETTINGS android.permission.NFC android.permission.READ_SYNC_SETTINGS android.permission.READ_SYNC_STATS android.permission.RECEIVE_BOOT_COMPLETED android.permission.REORDER_TASKS android.permission.REQUEST_INSTALL_PACKAGES android.permission.SET_TIME_ZONE android.permission.SET_WALLPAPER android.permission.SET_WALLPAPER_HINTS android.permission.SUBSCRIBED_FEEDS_READ android.permission.TRANSMIT_IR android.permission.USE_FINGERPRINT android.permission.VIBRATE android.permission.WAKE_LOCK android.permission.WRITE_SYNC_SETTINGS com.android.alarm.permission.SET_ALARM com.android.launcher.permission.INSTALL_SHORTCUT com.android.launcher.permission.UNINSTALL_SHORTCUT |
只需要在AndroidManifest.xml中简单声明这些权限就好,安装时就授权。不需要每次使用时都检查权限,而且用户不能取消以上授权。