6.0及6.0以上權限動態詢問
private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 6;
private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE2 = 7;
//手機拍照
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(ReviewActivity.this,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
} else {
photo();
dialog.dismiss();
}
}
});
//從相冊選擇圖片
photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(ReviewActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_CALL_PHONE2);
} else {
int selectedMode;
selectedMode = MultiImageSelectorActivity.MODE_MULTI;
int maxNum = 9 - drr.size();
Intent intent = new Intent(ReviewActivity.this, MultiImageSelectorActivity.class);
// 是否顯示拍攝圖片
intent.putExtra(MultiImageSelectorActivity.EXTRA_SHOW_CAMERA, false);
// 最大可選擇圖片數量
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_COUNT, maxNum);
// 選擇模式
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_MODE, selectedMode);
startActivityForResult(intent, RESULT_LOAD_IMAGE);
dialog.dismiss();
}
}
});
/**
* 拍照方法代碼
*/
public void photo() {
try {
if (hasSdcard()) {
String sdcardState = Environment.getExternalStorageState();
String sdcardPathDir = Environment.getExternalStorageDirectory().getPath() + "/tempImage/";
File file = null;
if (Environment.MEDIA_MOUNTED.equals(sdcardState)) {
// 有sd卡,是否有myImage文件夾
File fileDir = new File(sdcardPathDir);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
// 是否有headImg文件
file = new File(sdcardPathDir + System.currentTimeMillis() + ".JPEG");
}
if (file != null) {
path = file.getPath();
photoUri = Uri.fromFile(file);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//通過FileProvider創建一個content類型的Uri
photoUri = FileProvider.getUriForFile(ReviewActivity.this, "com.zuihou.drunkenmonkey.fileprovider", file);
}
Intent openCameraIntent = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
openCameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加這一句表示對目標應用臨時授權該Uri所代表的文件
}
openCameraIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(openCameraIntent, TAKE_PICTURE);
}
} else {
ToastUtil.showToast(getApplicationContext(), "設備沒有SD卡!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 檢查設備是否存在SDCard的工具方法
*/
public static boolean hasSdcard() {
String state = Environment.getExternalStorageState();
return state.equals(Environment.MEDIA_MOUNTED);
}
這裏有一句代碼:
FileProvider.getUriForFile(ReviewActivity.this, "com.zuihou.drunkenmonkey.fileprovider", file);
在用Android 7.0版本時,調用相機拍照出現了異常 FileUriExposedException,就是在傳遞uri時出錯 Android 7.0後又修改了文件權限,可以使用FileProvider解決
在項目res目錄下創建xml文件夾
<?xml version="1.0" encoding="utf-8"?>
<paths>
<!-- xml文件是唯一設置分享的目錄 ,不能用代碼設置
1.<files-path> getFilesDir() /data/data//files目錄
2.<cache-path> getCacheDir() /data/data//cache目錄
3.<external-path> Environment.getExternalStorageDirectory()
SDCard/Android/data/你的應用的包名/files/ 目錄
4.<external-files-path> Context#getExternalFilesDir(String) Context.getExternalFilesDir(null).
5.<external-cache-path> Context.getExternalCacheDir().
-->
<!-- path :代表設置的目錄下一級目錄 eg:<external-path path="images/"
整個目錄爲Environment.getExternalStorageDirectory()+"/images/"
name: 代表定義在Content中的字段 eg:name = "myimages" ,並且請求的內容的文件名爲default_image.jpg
則 返回一個URI content://com.example.myapp.fileprovider/myimages/default_image.jpg
-->
<!--當path 爲空時 5個全配置就可以解決-->
<external-path
name="camera_photos"
path="" />
</paths>
在manifest.xml文件添加provider,相機,讀寫文件權限
<provider
android:name="android.support.v4.content.FileProvider" //固定值
android:authorities="com.zuihou.drunkenmonkey.fileprovider" //前面爲項目的包名,fileprovider固定
android:exported="false" //是否支持其它應用調用當前組件 ,要求爲flase
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS" //固定值
android:resource="@xml/file_paths" /> //在res目錄下定義的filepaths.xml文件,名字可以自定義
</provider>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
獲取權限後返回結果代碼
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
photo();
} else {
// Permission Denied
ToastUtil.showToast(ReviewActivity.this, "Permission Denied");
}
}
if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE2) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
int selectedMode;
selectedMode = MultiImageSelectorActivity.MODE_MULTI;
int maxNum = 9 - drr.size();
Intent intent = new Intent(ReviewActivity.this, MultiImageSelectorActivity.class);
// 是否顯示拍攝圖片
intent.putExtra(MultiImageSelectorActivity.EXTRA_SHOW_CAMERA, false);
// 最大可選擇圖片數量
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_COUNT, maxNum);
// 選擇模式
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_MODE, selectedMode);
startActivityForResult(intent, RESULT_LOAD_IMAGE);
dialog.dismiss();
} else {
// Permission Denied
ToastUtil.showToast(ReviewActivity.this, "Permission Denied");
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}