Android6.0
(API 23
)之前的权限,是静态权限, 开发者只要在AndroidManifest.xml
中写上需要的权限,如下:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在AndroidManifest.xml
中写上需要的权限,这有两个作用:
1、用户在安装软件的时候,操作系统会把开发者写的这些权限列表展示给用户,但是,通常,用户在安装的过程中根本不关心到底这些权限是干啥的、有啥影响。如下:
2、如果某个API需要的权限,开发者没有在AndroidManifest.xml
中写,系统就会抛出SecurityException
异常, 如果用户没有捕获该异常,程序就会奔溃掉。
Android6.0
(API 23
)开始增加了动态权限,不仅仅要求开发者在AndroidManifest.xml
中写明确需要的权限, 某些涉及到用户隐私的权限,要求在调用该API之前,必须让用户确认授权这个权限。而且弹出的授权界面是操作系统本身的功能,不能绕过去。如下:
Android6.0
(API 23
)开始增加的动态权限申请API
实在太难用了,非常繁琐, 我们通常会使用RxPermissions简化开发。
常见的需要动态申请的权限:
android.permission.CALL_PHONE
权限动态申请和处理示例:
public static void call(Activity activity, String phoneNumber) {
new RxPermissions(activity).request(Manifest.permission.CALL_PHONE).subscribe(granted -> {
if (granted) {
try {
Uri uri = Uri.parse("tel:" + phoneNumber);
Intent intent = new Intent(Intent.ACTION_CALL, uri);
activity.startActivity(intent);
return true;
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(activity, "您没有授予打电话的权利,所以无法拨打电话", Toast.LENGTH_LONG).show();
}
});
}
android.permission.READ_PHONE_STATE
权限动态申请和处理示例:
public static void readIMEI(Context context) {
new RxPermissions(activity).request(Manifest.permission.READ_PHONE_STATE).subscribe(granted -> {
if (granted) {
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getDeviceId();
//TODO
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(context, "您没有授予获取电话状态相关的权限", Toast.LENGTH_LONG).show();
}
});
}
android.permission.READ_EXTERNAL_STORAGE
权限动态申请和处理示例:
private void readFile(Activity activity) {
new RxPermissions(activity).request(Manifest.permission.READ_EXTERNAL_STORAGE).subscribe(granted -> {
if (granted) {
try {
BufferedSource bufferedSource = Okio.buffer(Okio.source(new File(activity.getExternalCacheDir(), "xx.txt")));
String content = bufferedSource.readString(Charset.forName("UTF-8"));
//TODO
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(activity, "您没有授予读取SD卡的权利,所以无法查看SD中的内容", Toast.LENGTH_LONG).show();
}
});
}
此处使用了使用Okio简化读取文件的操作。
android.permission.WRITE_EXTERNAL_STORAGE
权限动态申请和处理示例:
private void writeFile(Activity activity) {
new RxPermissions(activity).request(Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(granted -> {
if (granted) {
try {
BufferedSink bufferedSink = Okio.buffer(Okio.sink(new File(activity.getExternalCacheDir(), "xx.txt")));
bufferedSink.writeUtf8("Hello");
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(activity, "您没有授予写入SD卡的权利", Toast.LENGTH_LONG).show();
}
});
}
此处使用了使用Okio简化写文件的操作。