如何在 Android 中以自定义文件名保存相机拍摄的图像?
How to save camera captured image with custom file name in Android?
我正在尝试用 Android 中的相机拍照,我想使用 UUID 使用自定义文件名保存它(例如:f12b5700-1d92-11e9-ab14-d663bd873d93.jpg) .
在下面的代码中,在 onActivityResult
中,我确实在 photoPath 中得到了 f12b5700-1d92-11e9-ab14-d663bd873d93.jpg 但是当我检查设备上的实际图像,它被保存为 timestamp.jpg(例如:1548082653944.jpg)。我的问题是如何让图片以自定义名称保存?
private var photoURI: Uri? = null
private fun takePhoto()
{
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, UUID.randomUUID().toString() + ".jpg")
photoURI = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(packageManager) != null)
{
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(intent, PHOTO_REQUEST_CODE);
}
}
在 onActivityResult 处理程序中,代码如下所示:
if (requestCode == PHOTO_REQUEST_CODE)
{
if (resultCode == Activity.RESULT_OK)
{
val proj = arrayOf(MediaStore.Images.Media.TITLE)
val cursor = contentResolver.query(photoURI!!, proj, null, null, null)
val index = cursor!!.getColumnIndex(MediaStore.Images.Media.TITLE)
cursor.moveToFirst()
photoPath = cursor.getString(index)
cursor.close()
Toast.makeText(this, photoPath, Toast.LENGTH_LONG).show()
}
else
{
capturedImage.setImageURI(null)
Toast.makeText(this, "Photo was not taken", Toast.LENGTH_SHORT).show()
}
}
经过一些努力,我在 CommonsWare 的帮助下解决了这个问题 link:
https://github.com/commonsguy/cw-omnibus/tree/v8.13/Camera/FileProvider
此外,我还从这些 link 中得到了帮助:
https://guides.codepath.com/android/Accessing-the-Camera-and-Stored-Media
https://guides.codepath.com/android/Sharing-Content-with-Intents#sharing-files-with-api-24-or-higher
https://developer.android.com/training/camera/photobasics
诀窍是使用 FileProvider。
我必须在 AndroidManifest.xml
中添加 <provider>
工作代码如下所示:
if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED)
{
Toast.makeText(this, "Storage is not available", Toast.LENGTH_LONG).show()
return
}
var imageName = UUID.randomUUID().toString() + ".jpg"
var output = File(Environment.getExternalStoragePublicDirectory(appName), imageName)
if (!output.parentFile.exists() && !output.parentFile.mkdir())
{
Toast.makeText(this, "Unable to create storage folder", Toast.LENGTH_LONG).show()
return
}
photoURI = FileProvider.getUriForFile(this, authority, output)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(packageManager) != null)
{
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(intent, PHOTO_REQUEST_CODE);
}
提供商:
<provider
android:authorities="com.domain.appname.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="appname" path="appname" />
</paths>
相应地更改 com.domain.appname 和应用程序名称。
我正在尝试用 Android 中的相机拍照,我想使用 UUID 使用自定义文件名保存它(例如:f12b5700-1d92-11e9-ab14-d663bd873d93.jpg) .
在下面的代码中,在 onActivityResult
中,我确实在 photoPath 中得到了 f12b5700-1d92-11e9-ab14-d663bd873d93.jpg 但是当我检查设备上的实际图像,它被保存为 timestamp.jpg(例如:1548082653944.jpg)。我的问题是如何让图片以自定义名称保存?
private var photoURI: Uri? = null
private fun takePhoto()
{
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, UUID.randomUUID().toString() + ".jpg")
photoURI = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(packageManager) != null)
{
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(intent, PHOTO_REQUEST_CODE);
}
}
在 onActivityResult 处理程序中,代码如下所示:
if (requestCode == PHOTO_REQUEST_CODE)
{
if (resultCode == Activity.RESULT_OK)
{
val proj = arrayOf(MediaStore.Images.Media.TITLE)
val cursor = contentResolver.query(photoURI!!, proj, null, null, null)
val index = cursor!!.getColumnIndex(MediaStore.Images.Media.TITLE)
cursor.moveToFirst()
photoPath = cursor.getString(index)
cursor.close()
Toast.makeText(this, photoPath, Toast.LENGTH_LONG).show()
}
else
{
capturedImage.setImageURI(null)
Toast.makeText(this, "Photo was not taken", Toast.LENGTH_SHORT).show()
}
}
经过一些努力,我在 CommonsWare 的帮助下解决了这个问题 link: https://github.com/commonsguy/cw-omnibus/tree/v8.13/Camera/FileProvider
此外,我还从这些 link 中得到了帮助:
https://guides.codepath.com/android/Accessing-the-Camera-and-Stored-Media
https://guides.codepath.com/android/Sharing-Content-with-Intents#sharing-files-with-api-24-or-higher
https://developer.android.com/training/camera/photobasics
诀窍是使用 FileProvider。 我必须在 AndroidManifest.xml
中添加<provider>
工作代码如下所示:
if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED)
{
Toast.makeText(this, "Storage is not available", Toast.LENGTH_LONG).show()
return
}
var imageName = UUID.randomUUID().toString() + ".jpg"
var output = File(Environment.getExternalStoragePublicDirectory(appName), imageName)
if (!output.parentFile.exists() && !output.parentFile.mkdir())
{
Toast.makeText(this, "Unable to create storage folder", Toast.LENGTH_LONG).show()
return
}
photoURI = FileProvider.getUriForFile(this, authority, output)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(packageManager) != null)
{
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(intent, PHOTO_REQUEST_CODE);
}
提供商:
<provider
android:authorities="com.domain.appname.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="appname" path="appname" />
</paths>
相应地更改 com.domain.appname 和应用程序名称。