![](/img/trans.png)
[英]Android MediaStore : Images.Media.insertImage vs ContentResolver.insert
[英]MediaStore contentResolver.insert() creates copies instead of replacing the existing file when taking photos (Android Q: 29)
我正在嘗試使用以下代碼保存從相機拍攝的圖像:
@RequiresApi(Build.VERSION_CODES.Q)
private fun setImageUri(): Uri {
val resolver = contentResolver
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "house2.jpg")
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.MediaColumns.RELATIVE_PATH, "Pictures/OLArt")
}
imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
return imageUri!!
}
該功能第一次運行良好。 然而,當圖像(house2.jpg)已經存在時,系統將創建另一個名為“house2 (1).jpg”、“house2 (2).jpg”等的文件(而不是替換舊文件)
我可以在 contentValues 中設置什么來強制解析器替換文件而不是創建它的副本嗎?
下面是拍照意圖的代碼。
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri()) //<- i paste in the imageUri here
// Ensure that there's a camera activity to handle the intent
takePictureIntent.resolveActivity(packageManager)?.also {
startActivityForResult(takePictureIntent, 102)
}
}
@CommonsWare 的評論有幫助。
這個想法是
創建查詢選擇時要注意的一件事是 MediaStore.MediaColumns.RELATIVE_PATH 需要終止“/”
即 'Pictures/OLArt/' << 注意 OLArt/ 后的斜線
val selection = "${MediaStore.MediaColumns.RELATIVE_PATH}='Pictures/OLArt/' AND "
+ "${MediaStore.MediaColumns.DISPLAY_NAME}='house2.jpg' "
以下是更新后的代碼。
@RequiresApi(Build.VERSION_CODES.Q)
private fun getExistingImageUriOrNullQ(): Uri? {
val projection = arrayOf(
MediaStore.MediaColumns._ID,
MediaStore.MediaColumns.DISPLAY_NAME, // unused (for verification use only)
MediaStore.MediaColumns.RELATIVE_PATH, // unused (for verification use only)
MediaStore.MediaColumns.DATE_MODIFIED //used to set signature for Glide
)
// take note of the / after OLArt
val selection = "${MediaStore.MediaColumns.RELATIVE_PATH}='Pictures/OLArt/' AND "
+ "${MediaStore.MediaColumns.DISPLAY_NAME}='house2.jpg' "
contentResolver.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, selection, null, null ).use { c ->
if (c != null && c.count >= 1) {
print("has cursor result")
c.moveToFirst().let {
val id = c.getLong(c.getColumnIndexOrThrow(MediaStore.MediaColumns._ID) )
val displayName = c.getString(c.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME) )
val relativePath = c.getString(c.getColumnIndexOrThrow(MediaStore.MediaColumns.RELATIVE_PATH) )
lastModifiedDate = c.getLong(c.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED) )
imageUri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
print("image uri update $displayName $relativePath $imageUri ($lastModifiedDate)")
return imageUri
}
}
}
print("image not created yet")
return null
}
然后我將此方法添加到我現有的代碼中
@RequiresApi(Build.VERSION_CODES.Q)
private fun setImageUriQ(): Uri {
val resolver = contentResolver
imageUri = getExistingImageUriOrNullQ() //try to retrieve existing uri (if any)
if (imageUri == null) {
//=========================
// existing codes for resolver.insert
//(SNIPPED)
//=========================
}
return imageUri!!
}
Angel Koh 的回答是正確的。
我只是用Java發布它:
@RequiresApi(Build.VERSION_CODES.Q)
public static Uri CheckIfUriExistOnPublicDirectory(Context c ,String[] projection, String selection){
ContentResolver resolver = c.getContentResolver();
Cursor cur = resolver.query(MediaStore.Downloads.EXTERNAL_CONTENT_URI, projection, selection , null, null);
if (cur != null) {
if(cur.getCount()>0){
if (cur.moveToFirst()) {
String filePath = cur.getString(0);
long id = cur.getLong(cur.getColumnIndexOrThrow(MediaStore.MediaColumns._ID));
String displayName = cur.getString(cur.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME) );
String relativePath = cur.getString(cur.getColumnIndexOrThrow(MediaStore.MediaColumns.RELATIVE_PATH) );
long z = cur.getLong(cur.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED) );
return imageUri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
} else {
// Uri was ok but no entry found.
}
}else{
// content Uri was invalid or some other error occurred
}
cur.close();
} else {
// content Uri was invalid or some other error occurred
}
return null;
}
和使用方法:
String[] projection = {MediaStore.MediaColumns._ID,
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.RELATIVE_PATH,
MediaStore.MediaColumns.DATE_MODIFIED
};
String selection = MediaStore.MediaColumns.RELATIVE_PATH + "='" + Environment.DIRECTORY_DOWNLOADS + File.separator + folderName + File.separator + "' AND "
+ MediaStore.MediaColumns.DISPLAY_NAME+"='" + fileName + "'";
uri = CheckIfUriExistOnPublicDirectory(context,projection,selection);
if(uri != null){
// file already exist
}else{
// file not exist, insert
}
您是否嘗試過使用方法 update ?
檢查它是否在沒有任何內容時創建一個新文件,如果它不起作用,則根據文件是否已創建使用插入或更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.