我想从画廊创建一个图片选择器。我使用代码
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);
我的问题是在这个活动和视频文件显示。是否有一种方法可以过滤显示的文件,以便在此活动中不显示视频文件?
当前回答
只是为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)
其他回答
如果你只是寻找图像和多重选择。
看一次https://stackoverflow.com/a/15029515/1136023
这对将来很有帮助。我个人觉得使用MultipleImagePick很棒。
对于Kotlin使用新的ActivityResultContracts,因为startActivityForResult是废弃的:
private val mSelectedPicDataResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val selectedPicUri = result.data?.data
//use your selected pic
}
}
private fun startSelectPic() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
mSelectedPicDataResult.launch(intent)
}
由于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/*",我们指定文件资源管理器只加载图像。
对于只从本地选择添加这个:
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)
我也有同样的问题,我用这个密码
addIntent
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Tack Image"), PICK_PHOTO);
添加onActivityResult
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PHOTO && resultCode == Activity.RESULT_OK) {
if (data == null) {
//error
return;
}
try {
Uri uri = data.getData();
File file = FileUtil.from(currentActivity, uri);
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileUtil类
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtil {
private static final int EOF = -1;
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
private FileUtil() {
}
public static File from(Context context, Uri uri) throws IOException {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
String fileName = getFileName(context, uri);
String[] splitName = splitFileName(fileName);
File tempFile = File.createTempFile(splitName[0], splitName[1]);
tempFile = rename(tempFile, fileName);
tempFile.deleteOnExit();
FileOutputStream out = null;
try {
out = new FileOutputStream(tempFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (inputStream != null) {
copy(inputStream, out);
inputStream.close();
}
if (out != null) {
out.close();
}
return tempFile;
}
private static String[] splitFileName(String fileName) {
String name = fileName;
String extension = "";
int i = fileName.lastIndexOf(".");
if (i != -1) {
name = fileName.substring(0, i);
extension = fileName.substring(i);
}
return new String[]{name, extension};
}
private static String getFileName(Context context, Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf(File.separator);
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
private static File rename(File file, String newName) {
File newFile = new File(file.getParent(), newName);
if (!newFile.equals(file)) {
if (newFile.exists() && newFile.delete()) {
Log.d("FileUtil", "Delete old " + newName + " file");
}
if (file.renameTo(newFile)) {
Log.d("FileUtil", "Rename file to " + newName);
}
}
return newFile;
}
private static long copy(InputStream input, OutputStream output) throws IOException {
long count = 0;
int n;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
}
并且必须将provider_paths.xml添加到像image这样的XML文件夹中
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
最后在AndroidManifest.xml中添加如下内容
<application
...>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
...
</application>
我希望我能帮上忙