寫在前面
近期項目的需求是需要去調用相機相冊去拍照獲取圖片保存到服務器
公司的測試機試Android6.0以下的 所以之前調用相機一點都沒問題 可是跑在Android8.0+的手機上 調用相機相冊就會出現錯誤
暴露的Url
所以在博客找到了相關文章,結合自身的需求 總結了這篇文章 希望能給您帶來幫助
1.Android6.0+需要動態申請權限,請參考博文
2.我們需要在AndroidMainfest如下配置
<!-- 適配Android8.0調用相機報錯的問題 -->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="(您的包名).fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<activity android:name=".business.archives.activity.HrAuthenticationActivity"></activity>
3.在res文件下 創建一個名爲xml的文件 在其中創建一個以 上面的代碼中
android:resource="@xml/file_paths" /> file_paths 一樣的文件名
4.file_paths文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="" name="camera_photos" />
</paths>
</resources>
5.在需要調用相機的Activity/Fragment 加入需要準備的變量和常量
//文件
private File file;
//相機請求碼
private final int REQUEST_CAMERA = 1;
6.調用相機的代碼
private void useCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/test/" + System.currentTimeMillis() + ".jpg");
file.getParentFile().mkdirs();
//改變Uri com.xykj.customview.fileprovider注意和xml中的一致
Uri uri = FileProvider.getUriForFile(this, "com.miaoyin.zcda.fileprovider", file);
//添加權限
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, REQUEST_CAMERA);
}
7.申請寫入權限
public void applyWritePermission() {
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT >= 23) {
int check = ContextCompat.checkSelfPermission(this, permissions[0]);
// 權限是否已經 授權 GRANTED---授權 DINIED---拒絕
if (check == PackageManager.PERMISSION_GRANTED) {
//調用相機
useCamera();
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
} else {
useCamera();
}
}
8.以下爲必要代碼 cv
/**
* 拍照的,照片路徑
*/
public void jsPath() {
//獲取SD卡安裝狀態
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
//設置圖片保存路徑
photoPath = SAVED_IMAGE_PATH + "/" + System.currentTimeMillis() + ".png";
File imageDir = new File(photoPath);
if (!imageDir.exists()) {
try {
//根據一個 文件地址生成一個新的文件用來存照片
imageDir.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
takePhotoByMethod1();
} else {
Toast.makeText(SubmitCarryCampLicenseActivity.this, "SD卡未插入", Toast.LENGTH_SHORT).show();
}
}
private void takePhotoByMethod1() {
//實例化intent,指向攝像頭
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//根據路徑實例化圖片文件
File photoFile = new File(photoPath);
//設置拍照後圖片保存到文件中
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
//啓動拍照activity並獲取返回數據
startActivityForResult(intent, REQUEST_CAMERA);
}
9.onActivityResult 回調代碼
if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) {
// Log.e("TAG", "---------" + FileProvider.getUriForFile(this, "com.xykj.customview.fileprovider", file));
//在手機相冊中顯示剛拍攝的圖片
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
String path = contentUri.getPath();
Log.e("TAGSSSSSSSSS", contentUri.toString());
//文件的路徑
String absolutePath = file.getAbsolutePath();
//文件的名字
String parent = file.getName();
Log.e("TAGQQQQQQQQQ", parent + "===" + absolutePath);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
//設置圖片
sdPic.setImageBitmap(BitmapFactory.decodeFile(file.getAbsolutePath()));
}else{
File photoFile = new File(photoPath);
if (photoFile.exists()) {
//通過圖片地址將圖片加載到bitmap裏面
Bitmap bm = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
//將拍攝的照片顯示到界面上
//這是返回來的路徑
// results.confirm(pathsa);
Toast.makeText(SubmitCarryCampLicenseActivity.this, "通過", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(SubmitCarryCampLicenseActivity.this, "圖片文件不存在", Toast.LENGTH_LONG).show();
}
}
}
10.在權限回調用加入一下代碼
if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
useCamera();
} else {
// 沒有獲取 到權限,從新請求,或者關閉app
Toast.makeText(this, "需要存儲權限", Toast.LENGTH_SHORT).show();
}
11.加入調用相冊的代碼
public void showPhoto() {
Intent it1 = new Intent(Intent.ACTION_PICK);
it1.setType("image/*");
mPhoto = 1;
startActivityForResult(it1, 200);
}
12.加入相冊剪裁功能
if (requestCode == 200 && resultCode == RESULT_OK) {
Intent it = new Intent("com.android.camera.action.CROP");
it.putExtra("crop", true);
Uri data1 = data.getData();
it.setDataAndType(data1, "image/*");
it.putExtra("aspactX", 1);
it.putExtra("aspactY", 1);
it.putExtra("outputX", 80);
it.putExtra("outputY", 80);
it.putExtra("return-data", true);
startActivityForResult(it, 300);
}
到這裏8.0+調用相冊就完成了
希望能對您有所幫助