我想从画廊创建一个图片选择器。我使用代码
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, TFRequestCodes.GALLERY);
我的问题是在这个活动和视频文件显示。是否有一种方法可以过滤显示的文件,以便在此活动中不显示视频文件?
我想从画廊创建一个图片选择器。我使用代码
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, TFRequestCodes.GALLERY);
我的问题是在这个活动和视频文件显示。是否有一种方法可以过滤显示的文件,以便在此活动中不显示视频文件?
当前回答
对于只从本地选择添加这个:
i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)
这个工作得很好:
val i = Intent(Intent.ACTION_GET_CONTENT,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
i.type = "image/*"
i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)
startActivityForResult(Intent.createChooser(i,"Select Photo"),pickImageRequestCode)
其他回答
只是为API min 19的人提供一个更新的答案,根据文档:
在Android 4.4 (API级别19)或更高,你有额外的选项使用ACTION_OPEN_DOCUMENT意图,它显示一个系统控制的选择器UI控制,允许用户浏览其他应用程序提供的所有文件。从这个UI中,用户可以从任何支持的应用程序中选择一个文件。 在Android 5.0 (API级别21)及更高版本上,你也可以使用ACTION_OPEN_DOCUMENT_TREE意图,它允许用户为客户端应用程序选择要访问的目录。
使用存储访问框架打开文件- Android Docs
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.type = "image/*"
startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)
有时,您无法从所选择的图片中获取文件。 这是因为选择一个来自谷歌+,Drive, Dropbox或任何其他提供商。
最好的解决方案是让系统通过Intent来选择内容。ACTION_GET_CONTENT并使用内容提供程序获取结果。
您可以按照下面的代码或查看我更新的要点。
public void pickImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, PICK_PHOTO_FOR_AVATAR);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {
if (data == null) {
//Display an error
return;
}
InputStream inputStream = context.getContentResolver().openInputStream(data.getData());
//Now you can do whatever you want with your inpustream, save it as file, upload to a server, decode a bitmap...
}
}
由于startActivityForResult()已经废弃,我们可以使用ActivityResultLauncher以以下方式从图库中选择图像:
首先,我们需要定义一个ActivityResultLauncher<String[]>并在onCreate()(用于活动)或onViewCreated()(用于片段)中初始化它
ActivityResultLauncher<String[]> galleryActivityLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), new ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri result) {
if (result != null) {
// perform desired operations using the result Uri
} else {
Log.d(TAG, "onActivityResult: the result is null for some reason");
}
}
});
假设我们需要在点击submitButton时打开图库。
在onClickListener中,我们需要调用
galleryActivityLauncher.launch(new String[]{"image/*"});
这里的技巧是launch()的参数。通过在参数数组中添加"image/*",我们指定文件资源管理器只加载图像。
这是一个完整的示例请求权限(如果需要),从图库中选择图像,然后将图像转换为位图或文件
AndroidManifesh.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
活动
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button_pick_image.setOnClickListener {
pickImage()
}
}
private fun pickImage() {
if (ActivityCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
val intent = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.INTERNAL_CONTENT_URI
)
intent.type = "image/*"
intent.putExtra("crop", "true")
intent.putExtra("scale", true)
intent.putExtra("aspectX", 16)
intent.putExtra("aspectY", 9)
startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
READ_EXTERNAL_STORAGE_REQUEST_CODE
)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PICK_IMAGE_REQUEST_CODE) {
if (resultCode != Activity.RESULT_OK) {
return
}
val uri = data?.data
if (uri != null) {
val imageFile = uriToImageFile(uri)
// todo do something with file
}
if (uri != null) {
val imageBitmap = uriToBitmap(uri)
// todo do something with bitmap
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
READ_EXTERNAL_STORAGE_REQUEST_CODE -> {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// pick image after request permission success
pickImage()
}
}
}
}
private fun uriToImageFile(uri: Uri): File? {
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = contentResolver.query(uri, filePathColumn, null, null, null)
if (cursor != null) {
if (cursor.moveToFirst()) {
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val filePath = cursor.getString(columnIndex)
cursor.close()
return File(filePath)
}
cursor.close()
}
return null
}
private fun uriToBitmap(uri: Uri): Bitmap {
return MediaStore.Images.Media.getBitmap(this.contentResolver, uri)
}
companion object {
const val PICK_IMAGE_REQUEST_CODE = 1000
const val READ_EXTERNAL_STORAGE_REQUEST_CODE = 1001
}
}
演示 https://github.com/PhanVanLinh/AndroidPickImage
下面是kotlin中util方法的工作代码:
fun launchGalleryWithFragment() {
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
intent.type = "image/*"
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1001)
}
现在重写onActivityResult方法:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
var path: Uri? = null
if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK) {
if(dataIntent == null || dataIntent.data == null){
return null
}
path = dataIntent.data
}
}