有些App需要打开本地文件,这个功能怎么做呢,有些人自己封装了一套方法(佩服佩服),我搜来搜去最简单的方法是调用Android本身的文件管理系统。实现之后在这里记录一下,只需要三四步:
(以下代码主要来自于Android官方的Sample:Strorage Client)
1、在MainActivity类中加入以下方法:
private static final int READ_REQUEST_CODE = 1337;//自己指定一个intent的请求码,下面用到时解释。
Uri filePathUri=null; //下面用于存放回传的文件地址。
//此方法用于调用系统的文件管理应用,选择文件并将路径传给本Activity
public void performFileSearch() {
// BEGIN_INCLUDE (use_open_document_intent)
// ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file browser.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);//新建intent对象,参数为调用系统的文件管理系统。
// Filter to only show results that can be "opened", such as a file (as opposed to a list
// of contacts or timezones)
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only images, using the image MIME data type.
// If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
// To search for all documents available via installed storage providers, it would be
// 这里可以设置要显示的文件的类型,用MIME data tpe的规范来设置,常见的类型可以看这个网页:
//https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
//设置为*/*表示可打开所有文件。只显示pdf的话可以设置为application/pdf
intent.setType("*/*");
//要设置多种类型可打开,则需要用putExtra。
intent.putExtra(Intent.EXTRA_MIME_TYPES,new String[]{"application/pdf","text/plain","application/vnd.openxmlformats-officedocument.wordprocessingml.document"});
//这个方法将上面设置好的intent发出,调用android系统的文件管理系统,在用户选择点击文件之后将结果返回给本Activity。
//READ_REQUEST_CODE为自己指定的一个任意整数,用于标记这个请求,以便下面收到回复的时候进行对比判断并作出相应的处理。
//因为你的程序可能会发出多个intent和多个activity进行互动,每次互动就要有一个唯一的请求码进行标识。
startActivityForResult(intent, READ_REQUEST_CODE);
}
2、重写onActivityResult方法,接收用户点击选择文件的动作结果并进行处理:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {//用请求码过滤一下我们所需要的互动请求,并验证操作是否成功。
// 用户所点选的文件将以URI地址方式回传,要对这个URI地址进行处理。
// A URI to the document selected by the user document will be contained in the return intent
// provided to this method as a parameter. Pull that uri using "resultData.getData()"
if (resultData != null) {
filePathUri=resultData.getData();//获取回传的文件URI地址。以下两行代码是对所获取到的pdf进行处理并用RecyclerView显示到界面上,具体可以看前两篇blog的介绍。
PdfViewAdapter pdfViewAdapter=new PdfViewAdapter(openPdf(filePathUri));//openPdf方法将pdf文件全部转化为bmp放入数组传给我们之前写好的Adapter
recyclerView.setAdapter(pdfViewAdapter);//rv设置adapter
}
}
}
3、重写MainActivity的onClick方法:(这里也就是调用上面第一步所写的方法而已,没什么特别)。
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.open:
performFileSearch();//点击打开按钮的时候调用此方法调用系统的文件管理应用
break;
}
}
4、在界面XML文件中按钮的代码中指明使用上面的onClick方法:
<Button
android:id="@+id/open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:onClick="onClick"
android:text="打开"
app:layout_constraintEnd_toEndOf="parent"
tools:layout_editor_absoluteY="3dp" />
记得要在Manifes文件中添加存储的读写权限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="knowing.pleasure">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<application
android:allowBackup="true"
android:requestLegacyExternalStorage="true"
android:icon="@mipmap/ic_launcher"
……………………
并在打开app的时候检查权限,如用户没有授权则提醒用户授权。在onCreate方法中添加以下代码:
//申请sd读写权限
int permission_write = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
int permission_read = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE);
if (permission_write != PackageManager.PERMISSION_GRANTED
|| permission_read != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "正在请求权限", Toast.LENGTH_SHORT).show();
//申请权限,特征码自定义为1,可在回调时进行相关判断
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
5、打开目录的方法(还没试验,先记录一下):
https://developer.android.com/training/data-storage/shared/documents-files?hl=zh-cn 以下代码段展示了如何创建和调用用于打开目录的 intent:
public void openDirectory(Uri uriToLoad) {
// Choose a directory using the system's file picker.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
// Provide read access to files and sub-directories in the user-selected
// directory.
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Optionally, specify a URI for the directory that should be opened in
// the system file picker when it loads.
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uriToLoad);
startActivityForResult(intent, your-request-code);
}