xxx
常用的mime type
多种文件类型选择办法
记得先申请sdcard的存储权限额
清单文件添加如下这种权限
23以上需要动态获取权限,获取成功以后下边才好执行,否则没有 权限就异常了。
清单文件里忘了写权限了,结果运行就挂,来个弹框
软件包安装程序已停止
调用下边的 方法启动,主要是看type,如果不显示文件类型,那就“/”,其他类型可以自己查下
private void openFileChoose(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("video/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent,123);
}
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(data!=null){
Uri uri=data.getData();
System.out.println("uri============="+uri);
}
}
使用记录
首先,可能要求选择多种类型都可以,主要就是传个参数EXTRA_MIME_TYPES,后边是你需要的类型数组
然后type里就写/了。
代码如下
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"audio/*", "video/*", "image/*"});
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1234);
然后实际需求是一次可以选多个文件,刚开始以为做不到,后边无聊查了下Intent,发现还真有一个可以用
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true);
看下源码说明
/**
* Extra used to indicate that an intent can allow the user to select and
* return multiple items. This is a boolean extra; the default is false. If
* true, an implementation is allowed to present the user with a UI where
* they can pick multiple items that are all returned to the caller. When
* this happens, they should be returned as the {@link #getClipData()} part
* of the result Intent.
*
* @see #ACTION_GET_CONTENT
* @see #ACTION_OPEN_DOCUMENT
*/
public static final String EXTRA_ALLOW_MULTIPLE =
"android.intent.extra.ALLOW_MULTIPLE";
使用这个,返回的数据就不是getData了,而是getClipData(),这个拿到ClipData,点下方法就知道了,可以拿到count,可以getItemAt获取item,里边该有的数据都有了。
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
data.getClipData()
copy的
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
public String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
// Log.i(TAG,"isExternalStorageDocument***"+uri.toString());
// Log.i(TAG,"docId***"+docId);
// 以下是打印示例:
// isExternalStorageDocument***content://com.android.externalstorage.documents/document/primary%3ATset%2FROC2018421103253.wav
// docId***primary:Test/ROC2018421103253.wav
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
// Log.i(TAG,"isDownloadsDocument***"+uri.toString());
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
// Log.i(TAG,"isMediaDocument***"+uri.toString());
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Log.i(TAG,"content***"+uri.toString());
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
// Log.i(TAG,"file***"+uri.toString());
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
public boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
调用权限的工具类
这里默认的requestCode是从1开始自增的,记得别和activity里其他冲突了。
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.PermissionChecker;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
public class FragmentPermissionHolder extends Fragment {
public static void checkPermission(FragmentActivity fragmentActivity,String[] permissions,RequestListener requestListener){
if (PermissionChecker.checkCallingOrSelfPermission(fragmentActivity,
permissions[0]) != PackageManager.PERMISSION_GRANTED){
getInstance(fragmentActivity).requestPermissions(permissions,requestListener);
}else{
requestListener.onSuccess(permissions);
}
}
public static final String TAG_FRAGMENT="tag_fragment_temp";
public static FragmentPermissionHolder getInstance(FragmentActivity fragmentActivity){
FragmentPermissionHolder fragment= (FragmentPermissionHolder) fragmentActivity.getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT);
if(fragment==null){
fragment=new FragmentPermissionHolder();
FragmentManager fragmentManager=fragmentActivity.getSupportFragmentManager();
fragmentManager.beginTransaction().add(fragment, TAG_FRAGMENT).commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
return fragment;
}
private SparseArray callbackMap=new SparseArray<>();
private int code=0;
public void requestPermissions(String[] permissions,RequestListener requestListener){
code++;
callbackMap.put(code,requestListener);
requestPermissions(permissions,code);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
RequestListener callback=callbackMap.get(requestCode);
callbackMap.delete(requestCode);
for(int i=0;i
代码中使用如下,传入自己要申请的权限即可
private void permissionCheck() {
FragmentPermissionHolder.checkPermission(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
new FragmentPermissionHolder.RequestListener() {
@Override
public void onSuccess(String[] permissions) {
openFileChoose();
}
@Override
public void onFailed(String[] permissions) {
dismissAllowingStateLoss();
}
});
}