我正在为Android 2.1开发一个应用程序。我想让我的用户在我的应用程序中选择个人资料图片(我没有使用联系人框架)。
理想的解决方案是启动一个使用户能够从图库中选择图像的意图,但如果没有合适的图像,则使用相机拍照(反之亦然,即允许用户拍摄)如果他们知道他们已经有了合适的图像了,那就让他们进入画廊并选择所说的图像。)
目前我可以做其中一个但不能两个都做。
如果我使用MediaStore.ACTION_IMAGE_CAPTURE直接进入相机模式,则无法进入图库。
如果我使用Intent.ACTION_PICK直接进入图库,那么我可以选择图像,但是如果我点击相机按钮(在图库的右上角),则会触发新的相机意图。因此,拍摄的任何照片都不会直接返回给我的应用程序。 (当然你可以按后退按钮退回到图库并从那里选择图像,但这是一个额外的不必要的步骤,并不是很直观)。
那么有没有办法将两者结合起来,或者我将不得不提供一个菜单来从我的应用程序中做一个或另一个?似乎这是一个常见的用例......当然我错过了什么?
答案 0 :(得分:119)
您可以尝试这样做:
// ...
// Within your enclosing Class
// ...
private static final int SELECT_PICTURE = 1;
// ...
Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra
(
Intent.EXTRA_INITIAL_INTENTS,
new Intent[] { takePhotoIntent }
);
startActivityForResult(chooserIntent, SELECT_PICTURE);
要了解如何处理活动结果,请参阅this question
注意:关键点是如何确定是否使用了相机或图库。这个代码示例中显示了这一点:https://stackoverflow.com/a/12347567/294884
答案 1 :(得分:13)
更新:此时使用EXTRA_INITIAL_INTENTS
的另一个答案是更好的答案。当我写回答时,EXTRA_INITIAL_INTENTS
尚未存在,因为它已在API Level 5中添加。
那么有没有办法将两者结合起来 我将不得不提供菜单 从我的内心做一个或另一个 应用
编写自己的图库,其中包含您想要的功能。
我认为菜单会更简单。
似乎这是常用的 案件......当然我错过了什么?
您旁边的开发人员会认为图库应该允许您从本地图库中选择,或者跳到Flickr从那里进行选择。另一位开发人员会认为相机不仅应该允许通过相机“拍照”,而且可以通过从画廊中选择一些东西来“拍照”,从你想象的方式反转。另一位开发人员会认为图库应该允许从本地图库,Flickr或相机或网络连接的网络摄像头中进行选择。还有一个开发人员认为画廊是愚蠢的,用户应该只通过文件浏览器选择文件。等等。
所有这些都在一个环境(手机)中,其中操作系统的闪存非常宝贵。
因此,恕我直言,核心Android团队选择为你按照你认为合适的方式组装构建模块,而不是试图适应所有可能的模式,这并不完全令人震惊。
答案 2 :(得分:2)
我的答案几乎与@Macarse解决方案完全相同,但我还添加了另一个展示图库应用程序的意图(例如:Google照片),并用Kotlin编写:
val REQUEST_CODE_GET_IMAGE = 101
private fun addProfileImage() {
val pickImageFileIntent = Intent()
pickImageFileIntent.type = "image/*"
pickImageFileIntent.action = Intent.ACTION_GET_CONTENT
val pickGalleryImageIntent = Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
val captureCameraImageIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val pickTitle = "Capture from camera or Select from gallery the Profile photo"
val chooserIntent = Intent.createChooser(pickImageFileIntent, pickTitle)
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(captureCameraImageIntent, pickGalleryImageIntent))
startActivityForResult(chooserIntent, REQUEST_CODE_GET_IMAGE)
}
从结果意图中提取图像:
private var imageTempFile: File? = null
private var imageMimeType: String? = null
private fun extractImage(intent: Intent?) {
val imageUri = intent?.data
imageUri?.let {
Glide.with(this)
.load(imageUri)
.into(profileImageCiv)
imageTempFile = MediaUtils.copyContentFromUriToCacheFile(this, imageUri, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
imageMimeType = MediaUtils.getMimeType(this, imageUri)
} ?: run {
intent?.extras?.get("data")?.let { bitmap -> // Bitmap was returned as raw bitmap
Glide.with(this)
.load(bitmap)
.into(profileImageCiv)
imageTempFile = MediaUtils.writeBitmapToCacheFile(this, bitmap as Bitmap, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
imageMimeType = "image/jpeg" // The bitmap was compressed as JPEG format. The bitmap itself doesn't have any format associated to it
} ?: run {
imageTempFile = null
imageMimeType = null
Log.e("Intent data is null.")
Log.d("Error during photo selection")
}
}
}