Android之通过ContentProvider共享文件
16lz
2021-01-23
使用ContentProvider共享文件时,一定要重写openFile方法,否则会报异常。
如:
public class ContentProviderDemo extends ContentProvider { @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { //由于是应用内的不同进程,故这里把文件放到data/data/包名 目录下 String path = getContext().getFilesDir().getParent(); File file = new File(path, uri.getPath().substring(1)); // ParcelFileDescriptor.MODE_READ_ONLY:只可读 // ParcelFileDescriptor.MODE_WRITE_ONLY:只可写 // ParcelFileDescriptor.MODE_READ_WRITE:可读可写 return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); } ...}
如果uri = content://jobdispatcher/abc.txt时,uri.getPath和uri.getEncodedPath都是"/abc.txt",特别注意是包含"/"的。
注册:
例子:提供provider的APP A通过发送定向广播向指定APP B发送共享文件的uri,收到该定向广播的APP A通过uri解析文件。
发广播:
String RECEIVE_MSG_ACTION = "com.example.sspreceiver.msg_action";Button button1 = (Button) findViewById(R.id.button1);button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction(RECEIVE_MSG_ACTION); Uri data = Uri.parse("msg://com.example.ssp1"); intent.setData(data); // 收到该广播的应用需要根据uri访问provider提供的文件,故这里put一个uri intent.putExtra("uri", "content://jobdispatcher/abc.txt"); MainActivity.this.sendBroadcast(intent); }});
接收广播的注册:
收到定向广播的处理方式:
public class Ssp1Receiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String uri = intent.getStringExtra("uri"); if (uri != null) { try { // 处理方式1:直接通过uri读文件 InputStream inputStream = context.getContentResolver() .openInputStream(Uri.parse(uri)); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream)); String lineStr = null; while ((lineStr = bufferedReader.readLine()) != null) { System.out.println("lineStr:" + lineStr); } bufferedReader.close(); // 处理方式2:直接通过uri写文件 context.getContentResolver().openOutputStream(Uri.parse(uri), "w"); // 处理方式3:把文件拷贝到本地处理 AssetFileDescriptor descriptor = context.getContentResolver() .openAssetFileDescriptor(Uri.parse(uri), "r"); InputStream is = descriptor.createInputStream(); // 根据uri解析文件名 int start = uri.lastIndexOf('/'); String fileName = uri.substring(start + 1); // 把文件拷贝到本地data/data/包名/files 目录下 fileName = context.getFilesDir().getAbsolutePath() + "/" + fileName; OutputStream os = new FileOutputStream(new File(fileName)); byte[] b = new byte[1024]; int len; while ((len = is.read(b)) != -1) { os.write(b, 0, len); } os.flush(); is.close(); os.close(); // 读取文件 File file = new File(fileName); if (file.isFile() && file.exists()) { InputStreamReader reader = new InputStreamReader( new FileInputStream(file)); BufferedReader buffered = new BufferedReader(reader); String lineTxt = null; while ((lineTxt = buffered.readLine()) != null) { System.out.println("lineTxt:" + lineTxt); } reader.close(); buffered.close(); } } catch (Exception e) { e.printStackTrace(); } } }}
例子中共享文件是存放在data/data/目录下的,以防止被人为修改。当然也可以共享sd卡中的文件。只是安全性方面不保险。
更多相关文章
- android的快捷方式——应用程序界面
- Android保存Log信息到本地文件
- java和Android文件下载断点续传和图片下载代码实现,可直接复制简
- 列出sdcard里所有.mp3文件,并且可以点击播放
- Android手机开发——向SD卡上的文件追加内容
- Unity android 读取文件,读取APK包文件
- Android 用Socket实现PC和手机的文件传输
- Android的APK文件反编绎