自從6.0開始球榆,SD卡的讀寫也需要獲取運行時權(quán)限徽惋。我們應(yīng)盡量避免去動態(tài)獲取SD卡權(quán)限,而是將文件緩存在Android/data/應(yīng)用包名路徑下铅歼,此路徑不需要獲取權(quán)限,而且當應(yīng)用刪除時此路徑也會刪除
//在Android/data/應(yīng)用包名/cache下换可,一般放一些不重要的數(shù)據(jù)椎椰,因為可能會被垃圾清理程序清除
File file=getExternalCacheDir();//
//重要的文件可以存在Android/data/應(yīng)用包名/files下,一般放一些長時間保存的數(shù)據(jù)
getExternalFilesDir("");
//如果是getExternalFilesDir("abc") 則會在files下新建一個abc目錄
下面以獲取撥打電話的例子來講解運行時權(quán)限
Intent intent=new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:13426112458"));
startActivity(intent);
記得在清單文件里添加<uses-permission android:name="android.permission.CALL_PHONE" />
- 當項目的gradle中沾鳄,targetSdkVersion<23時慨飘,運行程序,不會請求運行時權(quán)限译荞。
- 當我們把targetSdkVersion改為23或者是23以上再運行程序瓤的,發(fā)現(xiàn)還是沒有請求運行時權(quán)限。這是因為應(yīng)用升級時會把之前請求道的權(quán)限帶到新升級到的版本吞歼。
一般寫法
//判斷 如果沒有撥打電話的權(quán)限
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) !=PackageManager.PERMISSION_GRANTED)
{
//請求撥打電話的權(quán)限
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE},101);
} else {
callPhone();
}
請求權(quán)限的回調(diào)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 101:
//判斷是否獲取到權(quán)限
if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
//請求到權(quán)限
callPhone();
}else{
Toast.makeText(MainActivity.this,"權(quán)限被拒絕",Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}```
有一點需要注意:撥打電話的方法需要添加權(quán)限異常
``` private void callPhone() {
try {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:13426112458"));
startActivity(intent);
}catch (SecurityException e){//權(quán)限異常圈膏,因為有可能在任何地方在沒有請求權(quán)限的情況下調(diào)用callPhone()方法
}
}
如果需要同時獲取多個權(quán)限
List<String> permissionList = new ArrayList<String>();
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.CALL_PHONE);
}
//注意讀寫sd卡權(quán)限需要在清單文件里注冊
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (!permissionList.isEmpty()) {//permissionList不為空,說明有權(quán)限需要動態(tài)獲取
//注意第二個參數(shù)如何將List轉(zhuǎn)換為數(shù)組
ActivityCompat.requestPermissions(MainActivity.this, permissionList.toArray(new String[permissionList.size()]), 101);
} else {
doSomeThing();
}```
權(quán)限請求的回調(diào)
``` @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 101:
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, permissions[i] + "權(quán)限被拒絕", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, permissions[i] + "權(quán)限被允許", Toast.LENGTH_SHORT).show();
}
}
}
break;
default:
break;
}
}
封裝運行時權(quán)限的獲取
一般我們的應(yīng)用中都會有一個BaseActivity篙骡,其他的Activity都要繼承這個BaseActivity稽坤。我們將運行時權(quán)限的代碼封裝進BaseActivity
public class BaseActivity extends Activity {
PermissionListener mListener;
public void requestRuntimePermissions(String[] permissions, PermissionListener listener) {
mListener = listener;
List<String> listPermission = new ArrayList<>();
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
listPermission.add(permission);
}
}
if (listPermission.isEmpty()) {//所有權(quán)限都以獲取
mListener.onSuccess();
} else {
ActivityCompat.requestPermissions(this, listPermission.toArray(new String[listPermission.size()]), 1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && requestCode == 1) {
List<String> deniedPermissions = new ArrayList<>();//被拒絕的權(quán)限列表
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {//被拒絕
deniedPermissions.add(permissions[i]);
}
}
if (deniedPermissions.isEmpty()) {//沒有被拒絕的權(quán)限
mListener.onSuccess();
} else {
mListener.onFailed(deniedPermissions);
}
}
}
}```
接口很簡單,就一個成功跟失敗的回調(diào)糯俗,這里就不添加了