fileProvider 拍照打开相册,安装apk网上有很多文档自行搜索,这里只是单纯的介绍进程间文件共享。
场景:app A 共享文件,app B 接收
一,app A 基本配置
1,配置AndroidManifest.xml
因为fileProvider 继承 contentProvider,所以要在AndroidManifest文件中配置,这里要注意,需要配置meta-data 指向一个xml文件。xml文件中配置的是需要共享的文件目录。
name:是固定的;
authorities:包名+".provider",包名最好写活是唯一标识,"."后面自定义。
exported:false 固定写法,true会报错
grantUriPermissions :true 权限能够被内容提供器范围内的任何数据。
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/files_path"/>
</provider>
files_path 配置:我的图片目录为:data/data/com.example.demo/files文件夹下,所以只需要配置
“<fiels_path name=“image” path=”." />"就可以,如果共享其他目录下文件,参考下面配置
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="image" path="." /> // context.getFilesDir
</paths>
<root-path name="root" path="" /> // 设备的根目录
<files-path name="image" path="." /> // context.getFilesDir
<cache-path name="cache" path="." /> //context.getCacheDir()
<external-path name="external" path="." /> //Environment.getExternalStorageDirectory()
<external-files-path name="name" path="." /> //context.getExternalFilesDirs()
<external-cache-path name="name" path="." /> //getExternalCacheDirs()
2,将文件转成Uri路径
注意:通过FileProvider.getrUriForFile转Uri。 getUriForFile 中 authority 参数要和AndroidManifest中配置的authorities一样
//本地文件路径data/data/com.example.demo/files/image.jpg
File file = new File(getFilesDir().getPath(), "image.jpg");
Uri contentUri = FileProvider.getUriForFile(this,getPackageName() + ".provider", file);
3,通过广播将文件发送给app B,其他方式参考官网
String RECEIVE_ACTION = "com.example.receive.msg_action";
private void sendReceive() {
File file = new File(getFilesDir().getPath(), "image.jpg");
Uri contentUri = FileProvider.getUriForFile(this,
getPackageName() + ".provider", file);
Intent intent = new Intent(RECEIVE_ACTION);
intent.putExtra("uri", contentUri.toString());
//toPackage:app B 的包名,uri:文件uri路径,modeFlags:读写权限
grantUriPermission("com.example.demo1",contentUri,Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
this.sendBroadcast(intent);
}
二,app B 接收文件
1,注册广播
public class MainActivity extends AppCompatActivity {
String RECEIVE_ACTION="com.example.receive.msg_action";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyReceive receive=new MyReceive();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(RECEIVE_ACTION);
registerReceiver(receive,intentFilter);
}
}
2,获取到Uri路径
class MyReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String path = intent.getStringExtra("uri");
Uri uri = Uri.parse(path);
Log.i("MainActivity", "接收到了来自app A 发送的uri");
}
3,通过getContentResolver().openInputStream将Uri路径转成流写入文件中即可(不要在广播内执行耗时任务,可开启服务执行)
String filePath = context.getFilesDir().getPath();
File file = new File(filePath + "/image.jpg");
try {
InputStream in = context.getContentResolver().openInputStream(uri);
file.createNewFile();
FileOutputStream fo = new FileOutputStream(file);
int read = in.read();
while (read != -1) {
fo.write(read);
read = in.read();
}
//关闭流
fo.flush();
fo.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}