Android之通过ContentProvider共享文件

使用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)