我正在嘗試用于MediaStore API保存影像,但它始終使用此名稱保存檔案
1637955326427.jpg并且檔案大小為0 B。這是我使用的代碼:
OutputStream fos;
ContentResolver resolver = getBaseContext().getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "fileName.jpg");
contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
try {
fos = resolver.openOutputStream(Objects.requireNonNull(imageUri));
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),list.get(0).getDocfile().getUri());
if(bitmap!=null){
bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
list.get(0).getDocFile()回傳一個DocumentFile我也測驗過這個API 28
提前謝謝
注意此圖片已存在于 上External Storage,只需將其復制即可。
編輯:我洗掉這段代碼fos = resolver.openOutputStream(imageUri);是重復的。我真的很抱歉。該檔案作業正常,但竊取了錯誤的名稱。
uj5u.com熱心網友回復:
首先讓我們看一下獲取現有影像的寫入權限。請注意,photopath 不一定存在,但應指向您希望保存檔案的位置。
if (!requestPhotoWritePermission(this, getImageUriFromFS(this, new File(photoPath)))) {
return;
} else {
takePicture();
}
這將與默認相機形成覆寫請求
public static Uri getImageUriFromFS(Context c, File file) {
long id = getFilePathToImageID(file, c);
Uri fromUri = ContentUris.withAppendedId( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,id);
return fromUri;
}
public static long getFilePathToImageID(File imagePath, Context context)
{
Uri mainUri;
Cursor cursor1 = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID},
MediaStore.Images.Media.DATA "=? ",
new String[]{imagePath.getAbsolutePath()}, null);
long id = 0;
if (cursor1 != null && cursor1.moveToFirst()) {
id = cursor1.getLong(cursor1.getColumnIndex(MediaStore.MediaColumns._ID));
cursor1.close();
}
return id;
}
public static boolean requestPhotoWritePermission(Activity activity, Uri fromUri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
boolean hasPermission = true;
if (activity.checkUriPermission(fromUri, Binder.getCallingPid(), Binder.getCallingUid(),
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION) != PackageManager.PERMISSION_GRANTED) {
hasPermission = false;
}
List<Uri> uriList = new ArrayList<>();
uriList.add(fromUri);
if (!hasPermission) {
PendingIntent pi = MediaStore.createWriteRequest(activity.getContentResolver(), uriList);
try {
activity.startIntentSenderForResult(pi.getIntentSender(), REQUEST_OVERWRITE_PERMISSION_CODE, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
return false;
}
return true;
}
return true;
}
這將保留通過相機意圖覆寫或創建新圖片的權限
然后在您的活動中:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 53) {
if (resultCode == RESULT_OK) {
//you'll want to take your picture here and possibly store the uri to your photo for later retrieval
takePicture();
}
}
如果許可請求被接受,這將拍照
要使用提供者的默認意圖拍攝照片:
在清單中宣告您的提供者
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.provider" android:enabled="true" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"> </meta-data> </provider>
1.5:xml檔案路徑檔案:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
name="internal_images"
path="files/Pictures" />
<external-files-path
name="internal_images_alternate"
path="Pictures" />
<external-path
name="external"
path="Documents" />
<external-files-path
name="external_files"
path="Documents" />
<cache-path
name="cache"
path="Documents" />
<external-cache-path
name="external_cache"
path="Documents" />
<files-path
name="files"
path="Documents" />
</paths>
以上將授予您保存到檔案檔案夾的權限。根據需要更換。
利用提供者拍照
public static File dispatchTakePictureIntent(Activity activity, String photoPath) { Intent takePictureIntent = getCameraIntentWithUpdatedPackages(activity); Uri photoURI = Uri.fromFile(new File(photoPath)); Uri photoUri = FileProvider.getUriForFile(activity.getApplicationContext(), activity.getApplicationContext().getPackageName() ".provider", new File(photoPath)); activity.grantUriPermission(photoURI.getAuthority(), photoUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); //disable strict mode policies StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); activity.startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); return new File(photoPath); return null;}
編輯:我忘記了一些東西
public static Intent getCameraIntentWithUpdatedPackages(Context context) {
List<ResolveInfo> resolveInfo = new ArrayList<>();
final Intent capturePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
PackageManager pm = context.getPackageManager();
resolveInfo = pm.queryIntentActivities(capturePhoto, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// For Android 11 we need to add specific camera apps
// due them are not added during ACTION_IMAGE_CAPTURE scanning...
// resolveInfo.addAll(getCameraSpecificAppsInfo(context));
}
capturePhoto.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
return capturePhoto;
}
編輯:按名稱更新(在請求覆寫權限后在 onActivityResult 中)
Uri fromUri = MediaUtils.getImageUriFromFS(this, new File(from));
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 1);
contentResolver.update(fromUri, contentValues, null, null);
contentValues.clear();
contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, new File(to).getName());
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0);
contentResolver.update(fromUri, contentValues, null, null);
uj5u.com熱心網友回復:
我洗掉這段代碼fos = resolver.openOutputStream(imageUri);是重復的。影像作業正常,但竊取了錯誤的名稱。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/367684.html
