使用FileProvider共享文件
2017-09-24 12:53
381 查看
需要一下几步
一、在共享端设置
首先,需要在 Menifest里添加 provider 标签,
[html] view
plain copy
<!-- 在这里定义共享信息 -->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.fileproviderdemo.fileprovider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
然后,指定共享目录
在res目录下,新建目录xml,在xml下新建filepaths.xml 文件
[html] view
plain copy
<?xml version="1.0" encoding= "utf-8"?>
<resources>
<paths >
<files-path path="files/" name="intfiles" />
<external-path path="files/" name="extfiles" />
</paths >
</resources>
别忘了外部路径需要权限。
二、创建一个文件选择Activity。
[html] view
plain copy
<!-- 文件选择页面ACTIVITY -->
<activity
android:name=".FileSelectActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="text/plain" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
三、在代码中响应
[java] view
plain copy
/*当条目被点击时,设置setResult,将选择的结果返回给调用此activity的activity*/
@Override
public boolean onChildClick (ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
/*得到点击的File*/
File file = ((File[])mGroupMap.get(mGroups [groupPosition]))[childPosition];
Uri fileUri;
/*authority 必须和Menifest的provider标签里定义的一致*/
String authority = getResources().getString(R.string.fileprovider_authority );
try {
fileUri = FileProvider. getUriForFile(
FileSelectActivity. this,
authority,
file);
Intent resultIntent = new Intent();
if (fileUri != null) {
resultIntent.addFlags(
Intent. FLAG_GRANT_READ_URI_PERMISSION );
// Put the Uri and MIME type in the result Intent
resultIntent.setDataAndType(
fileUri,
getContentResolver().getType(fileUri));
// 设置返回结果状态,
setResult(Activity. RESULT_OK,
resultIntent);
} else {
resultIntent.setDataAndType( null, "" );
setResult( RESULT_CANCELED,
resultIntent);
}
finish();
} catch (Exception e) {
e.printStackTrace();
}
finally{
finish();
}
return true ;
}
四、在请求端,也就是请求共享的App的代码中,发起请求
[java] view
plain copy
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType( "text/plain");
startActivityForResult(intent, 0);
被调用Activity返回前,调用setResult方法,设置了RESULT_OK,在被调用Activity结束后,系统会调用onActivityResult方法
得到之前设置的RESULT_OK状态,表示成功获取到文件。如果获取失败,则应该设置RESULT_CANCEL。
[java] view
plain copy
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
// TODO Auto-generated method stub
if (resultCode != RESULT_OK) {
tvFileContent.setText("未成功获得文件" );
tvFileName.setText("未成功获得文件" );
} else {
readFile(data.getData());
}
}
private void readFile(Uri returnUri) {
Context context = getActivity();
ParcelFileDescriptor inputPFD;
//获取文件句柄
try {
inputPFD = context.getContentResolver().openFileDescriptor(returnUri, "r" );
} catch (FileNotFoundException e) {
e.printStackTrace();
tvFileContent.setText("获取文件句柄失败" );
tvFileName.setText("获取文件句柄失败" );
return;
}
//获取文件名字和大小
Cursor returnCursor =
context.getContentResolver().query(returnUri, null, null , null, null);
/*
* Get the column indexes of the data in the Cursor,
* move to the first row in the Cursor, get the data,
* and display it.
*/
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
tvFileName.setText("文件名:" +returnCursor.getString(nameIndex)+", 大小:"+
Long. toString(returnCursor.getLong(sizeIndex))+" B");
returnCursor.close();
//读取文件内容
String content = "";
FileReader fr = null;
char[] buffer = new char[1024];
try {
StringBuilder strBuilder = new StringBuilder();
fr = new FileReader(inputPFD.getFileDescriptor());
while (fr.read(buffer) != -1) {
strBuilder.append(buffer);
}
fr.close();
content = strBuilder.toString();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (content.length() != 0) {
tvFileContent.setText(content);
} else {
tvFileContent.setText("<内容空>" );
}
try {
inputPFD.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
一、在共享端设置
首先,需要在 Menifest里添加 provider 标签,
[html] view
plain copy
<!-- 在这里定义共享信息 -->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.fileproviderdemo.fileprovider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
然后,指定共享目录
在res目录下,新建目录xml,在xml下新建filepaths.xml 文件
[html] view
plain copy
<?xml version="1.0" encoding= "utf-8"?>
<resources>
<paths >
<files-path path="files/" name="intfiles" />
<external-path path="files/" name="extfiles" />
</paths >
</resources>
别忘了外部路径需要权限。
二、创建一个文件选择Activity。
[html] view
plain copy
<!-- 文件选择页面ACTIVITY -->
<activity
android:name=".FileSelectActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="text/plain" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
三、在代码中响应
[java] view
plain copy
/*当条目被点击时,设置setResult,将选择的结果返回给调用此activity的activity*/
@Override
public boolean onChildClick (ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
/*得到点击的File*/
File file = ((File[])mGroupMap.get(mGroups [groupPosition]))[childPosition];
Uri fileUri;
/*authority 必须和Menifest的provider标签里定义的一致*/
String authority = getResources().getString(R.string.fileprovider_authority );
try {
fileUri = FileProvider. getUriForFile(
FileSelectActivity. this,
authority,
file);
Intent resultIntent = new Intent();
if (fileUri != null) {
resultIntent.addFlags(
Intent. FLAG_GRANT_READ_URI_PERMISSION );
// Put the Uri and MIME type in the result Intent
resultIntent.setDataAndType(
fileUri,
getContentResolver().getType(fileUri));
// 设置返回结果状态,
setResult(Activity. RESULT_OK,
resultIntent);
} else {
resultIntent.setDataAndType( null, "" );
setResult( RESULT_CANCELED,
resultIntent);
}
finish();
} catch (Exception e) {
e.printStackTrace();
}
finally{
finish();
}
return true ;
}
四、在请求端,也就是请求共享的App的代码中,发起请求
[java] view
plain copy
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType( "text/plain");
startActivityForResult(intent, 0);
被调用Activity返回前,调用setResult方法,设置了RESULT_OK,在被调用Activity结束后,系统会调用onActivityResult方法
得到之前设置的RESULT_OK状态,表示成功获取到文件。如果获取失败,则应该设置RESULT_CANCEL。
[java] view
plain copy
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
// TODO Auto-generated method stub
if (resultCode != RESULT_OK) {
tvFileContent.setText("未成功获得文件" );
tvFileName.setText("未成功获得文件" );
} else {
readFile(data.getData());
}
}
private void readFile(Uri returnUri) {
Context context = getActivity();
ParcelFileDescriptor inputPFD;
//获取文件句柄
try {
inputPFD = context.getContentResolver().openFileDescriptor(returnUri, "r" );
} catch (FileNotFoundException e) {
e.printStackTrace();
tvFileContent.setText("获取文件句柄失败" );
tvFileName.setText("获取文件句柄失败" );
return;
}
//获取文件名字和大小
Cursor returnCursor =
context.getContentResolver().query(returnUri, null, null , null, null);
/*
* Get the column indexes of the data in the Cursor,
* move to the first row in the Cursor, get the data,
* and display it.
*/
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
tvFileName.setText("文件名:" +returnCursor.getString(nameIndex)+", 大小:"+
Long. toString(returnCursor.getLong(sizeIndex))+" B");
returnCursor.close();
//读取文件内容
String content = "";
FileReader fr = null;
char[] buffer = new char[1024];
try {
StringBuilder strBuilder = new StringBuilder();
fr = new FileReader(inputPFD.getFileDescriptor());
while (fr.read(buffer) != -1) {
strBuilder.append(buffer);
}
fr.close();
content = strBuilder.toString();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (content.length() != 0) {
tvFileContent.setText(content);
} else {
tvFileContent.setText("<内容空>" );
}
try {
inputPFD.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
相关文章推荐
- Android实践 -- 使用FileProvider安全的共享文件 简介篇
- android 7.0 使用FileProvider在应用间共享文件(相机适配)
- Android7.0 使用FileProvider 共享文件
- Android实践 -- 使用FileProvider安全的共享文件 应用篇
- 快速使用FileProvider解决Android7.0文件权限问题
- Android7.0须知--应用间共享文件(FileProvider)
- 【文件上传->jQuery-File-Upload】jQuery-File-Upload图片上传组件简要使用指南(挥泪共享)
- Android 7.0 适配-应用之间共享文件(FileProvider)
- Android 7.0 行为变更 通过FileProvider在应用间共享文件
- Android 7.0配置fileprovider共享文件 解决FileUriExposedException
- Android 应用间共享文件(FileProvider)
- 使用文件映射的方式进行共享数据中CreateFileMapping、MapViewOfFile函数参数说明
- Android N 7.0 应用间共享文件(FileProvider)
- 使用FileProvider 分享文件
- Android 7.0 通过FileProvider实现应用间文件共享
- Content Provider(二)之 FileProvider 实现应用文件共享
- FileProvider文件共享
- Unreal Engine 4 —— 使用IPlatformFile进行Shader文件在开发团队间的共享
- 快速使用FileProvider解决Android7.0文件权限问题
- 快速使用FileProvider解决Android7.0文件权限问题