打开系统文件选择器,获取文件真实路径

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();
                    }
                });
    }

你可能感兴趣的:(打开系统文件选择器,获取文件真实路径)