实际项目中经常需要调用文件管理器,选择下载路径或者上传的本地文件路径。今天就给大家做个demo示范该功能的实现过程。

一、实现效果预览

以下为三星S6的样机测试效果,当然不同手机调用后的效果不一样。

二、代码实现

布局文件很简单,就一个Button和TextView,这里不示范了,直接上实现代码:
  1 package com.panhouye.selectfile;
  2 
  3 import android.annotation.SuppressLint;
  4 import android.app.Activity;
  5 import android.content.ContentUris;
  6 import android.content.Context;
  7 import android.content.Intent;
  8 import android.database.Cursor;
  9 import android.net.Uri;
 10 import android.os.Build;
 11 import android.os.Bundle;
 12 import android.os.Environment;
 13 import android.provider.DocumentsContract;
 14 import android.provider.MediaStore;
 15 import android.support.v7.app.AppCompatActivity;
 16 import android.view.View;
 17 import android.widget.Button;
 18 import android.widget.TextView;
 19 import android.widget.Toast;
 20 
 21 public class MainActivity extends AppCompatActivity {
 22     TextView tv;
 23     @Override
 24     protected void onCreate(Bundle savedInstanceState) {
 25         super.onCreate(savedInstanceState);
 26         setContentView(R.layout.activity_main);
 27         Button btn = (Button) findViewById(R.id.btn);
 28         tv = (TextView) findViewById(R.id.tv);
 29         btn.setOnClickListener(new View.OnClickListener() {
 30             @Override
 31             public void onClick(View v) {
 32                 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
 33                 //intent.setType(“image/*”);//选择图片
 34                 //intent.setType(“audio/*”); //选择音频
 35                 //intent.setType(“video/*”); //选择视频 (mp4 3gp 是android支持的视频格式)
 36                 //intent.setType(“video/*;image/*”);//同时选择视频和图片
 37                 intent.setType("*/*");//无类型限制
 38                 intent.addCategory(Intent.CATEGORY_OPENABLE);
 39                 startActivityForResult(intent, 1);
 40             }
 41         });
 42     }
 43     String path;
 44     @Override
 45     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 46         if (resultCode == Activity.RESULT_OK) {
 47             Uri uri = data.getData();
 48             if ("file".equalsIgnoreCase(uri.getScheme())){//使用第三方应用打开
 49                 path = uri.getPath();
 50                 tv.setText(path);
 51                 Toast.makeText(this,path+"11111",Toast.LENGTH_SHORT).show();
 52                 return;
 53             }
 54             if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//4.4以后
 55                 path = getPath(this, uri);
 56                 tv.setText(path);
 57                 Toast.makeText(this,path,Toast.LENGTH_SHORT).show();
 58             } else {//4.4以下下系统调用方法
 59                 path = getRealPathFromURI(uri);
 60                 tv.setText(path);
 61                 Toast.makeText(MainActivity.this, path+"222222", Toast.LENGTH_SHORT).show();
 62             }
 63         }
 64     }
 65 
 66     public String getRealPathFromURI(Uri contentUri) {
 67         String res = null;
 68         String[] proj = { MediaStore.Images.Media.DATA };
 69         Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
 70         if(null!=cursor&&cursor.moveToFirst()){;
 71             int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
 72             res = cursor.getString(column_index);
 73             cursor.close();
 74         }
 75         return res;
 76     }
 77 
 78     /**
 79      * 专为Android4.4设计的从Uri获取文件绝对路径,以前的方法已不好使
 80      */
 81     @SuppressLint("NewApi")
 82     public String getPath(final Context context, final Uri uri) {
 83 
 84         final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
 85 
 86         // DocumentProvider
 87         if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
 88             // ExternalStorageProvider
 89             if (isExternalStorageDocument(uri)) {
 90                 final String docId = DocumentsContract.getDocumentId(uri);
 91                 final String[] split = docId.split(":");
 92                 final String type = split[0];
 93 
 94                 if ("primary".equalsIgnoreCase(type)) {
 95                     return Environment.getExternalStorageDirectory() + "/" + split[1];
 96                 }
 97             }
 98             // DownloadsProvider
 99             else if (isDownloadsDocument(uri)) {
100 
101                 final String id = DocumentsContract.getDocumentId(uri);
102                 final Uri contentUri = ContentUris.withAppendedId(
103                         Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
104 
105                 return getDataColumn(context, contentUri, null, null);
106             }
107             // MediaProvider
108             else if (isMediaDocument(uri)) {
109                 final String docId = DocumentsContract.getDocumentId(uri);
110                 final String[] split = docId.split(":");
111                 final String type = split[0];
112 
113                 Uri contentUri = null;
114                 if ("image".equals(type)) {
115                     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
116                 } else if ("video".equals(type)) {
117                     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
118                 } else if ("audio".equals(type)) {
119                     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
120                 }
121 
122                 final String selection = "_id=?";
123                 final String[] selectionArgs = new String[]{split[1]};
124 
125                 return getDataColumn(context, contentUri, selection, selectionArgs);
126             }
127         }
128         // MediaStore (and general)
129         else if ("content".equalsIgnoreCase(uri.getScheme())) {
130             return getDataColumn(context, uri, null, null);
131         }
132         // File
133         else if ("file".equalsIgnoreCase(uri.getScheme())) {
134             return uri.getPath();
135         }
136         return null;
137     }
138 
139     /**
140      * Get the value of the data column for this Uri. This is useful for
141      * MediaStore Uris, and other file-based ContentProviders.
142      *
143      * @param context       The context.
144      * @param uri           The Uri to query.
145      * @param selection     (Optional) Filter used in the query.
146      * @param selectionArgs (Optional) Selection arguments used in the query.
147      * @return The value of the _data column, which is typically a file path.
148      */
149     public String getDataColumn(Context context, Uri uri, String selection,
150                                 String[] selectionArgs) {
151 
152         Cursor cursor = null;
153         final String column = "_data";
154         final String[] projection = {column};
155 
156         try {
157             cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
158                     null);
159             if (cursor != null && cursor.moveToFirst()) {
160                 final int column_index = cursor.getColumnIndexOrThrow(column);
161                 return cursor.getString(column_index);
162             }
163         } finally {
164             if (cursor != null)
165                 cursor.close();
166         }
167         return null;
168     }
169 
170     /**
171      * @param uri The Uri to check.
172      * @return Whether the Uri authority is ExternalStorageProvider.
173      */
174     public boolean isExternalStorageDocument(Uri uri) {
175         return "com.android.externalstorage.documents".equals(uri.getAuthority());
176     }
177 
178     /**
179      * @param uri The Uri to check.
180      * @return Whether the Uri authority is DownloadsProvider.
181      */
182     public boolean isDownloadsDocument(Uri uri) {
183         return "com.android.providers.downloads.documents".equals(uri.getAuthority());
184     }
185 
186     /**
187      * @param uri The Uri to check.
188      * @return Whether the Uri authority is MediaProvider.
189      */
190     public boolean isMediaDocument(Uri uri) {
191         return "com.android.providers.media.documents".equals(uri.getAuthority());
192     }
193 }

三、小结

这是调用系统自带的文件管理,无法保证和控制统一的界面显示,所以大家还是要实现与自己APP统一的文件管理界面,共勉。