首页 > 学院 > 开发设计 > 正文

ContentProvider跨应用获取data/data/包名下的文件

2019-11-09 18:37:41
字体:
来源:转载
供稿:网友

一、新建一个MyPRovider类,重写openFile方法。

package com.sh.main;/** * Desc: * Create by SunHang on 17-1-24 17:25 * Email:htuhang@163.com */import android.content.ContentProvider;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.net.Uri;import android.os.ParcelFileDescriptor;import android.support.annotation.Nullable;import android.util.Log;import com.eetrust.utils.LogUtil;import java.io.File;import java.io.FileNotFoundException;/** * 使用contentProvider的时候 数据库不需要关闭 * * @author mxy *         我们在操作该ContentProvider数据的时候,需要根据特定的Uri去操作 *         Uri构造格式如下:content://<AndroidManifest.xml配置的provider的authorities名字>/自定义内容 */public class MyProvider extends ContentProvider {    private static int GET_FILE = 1;    private static final String TAG = "MyProvider";    private static final String FileName = "MYFILE";    private static final String DirName = "MYDIR";    private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);    static {        matcher.addURI("com.sh.main.MyProvider", "getUri", GET_FILE);    }    private String pathName;    @Override    public boolean onCreate() {        return false;    }    @Nullable    @Override    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {        return null;    }    @Nullable    @Override    public String getType(Uri uri) {        return null;    }    @Nullable    @Override    public Uri insert(Uri uri, ContentValues values) {        return null;    }    @Override    public int delete(Uri uri, String selection, String[] selectionArgs) {        return 0;    }    @Override    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {        return 0;    }    @Nullable    @Override    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {        Log.d(TAG, "openFile: uri = " + uri);        File path = getContext().getDir(DirName, getContext().MODE_PRIVATE);        pathName = path.getPath() + File.separator;//文件夹路径        Log.d(TAG, "openFile: " + pathName + FileName);        File file = new File(pathName, FileName);//文件路径        if (fileExist()) {            return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);        } else {            System.out.println("文件不存在");            return null;        }    }    public boolean fileExist() {        File fname;        boolean result = false;        LogUtil.d(TAG, "FileExist()");        try {            fname = new File(pathName, FileName);            if (fname.exists() && fname.isFile()) {                result = true;            }        } catch (SecurityException se) {            LogUtil.e(TAG, se.toString());        }        return result;    }}二、AndroidManifest中声明

        <provider android:name="com.sh.main.MyProvider"            android:authorities="com.sh.main.MyProvider"            android:exported="true" >        </provider>
<!--authorities全手机唯一,不可与其他provider重复;exported代表此文件可导出-->
三、另一个应用通过provider获取文件,我是通过AsyncTask获取显示(习惯了,,)

package com.sh.myapplicationb;import android.net.Uri;import android.os.AsyncTask;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class MainActivity extends AppCompatActivity {    private TextView tv_get_provider;    public static final Uri URI_KEY = Uri.parse("content://com.sh.main.MyProvider");    private File providerFile;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tv_get_provider = (TextView) findViewById(R.id.tv_get_provider);        getProvider.execute(new Void[]{});    }    AsyncTask<Void, Void, Integer> getProvider = new AsyncTask<Void, Void, Integer>() {        @Override        protected Integer doInBackground(Void... voids) {            providerFile = getProviderFile();//通过provider获取文件            if (providerFile != null) {                return 1;            } else {                return 0;            }        }        @Override        protected void onPostExecute(Integer integer) {            if (integer == 1) {                tv_get_provider.setText(providerFile.length()+"");//如果获取到文件大小等于源文件,则表示成功            } else {                tv_get_provider.setText("NULL");            }        }    };    public File getProviderFile() {        try {            File file = new File(MainActivity.this.getFilesDir(), "bbb");//文件的存放位置,这里保存为B应用包名下files目录下的bbb文件            InputStream is = getContentResolver().openInputStream(URI_KEY);//通过输入流读取文件            if (is != null) {                inputStreamToFile(is, file);//将输入流转换为文件            }            return file;        } catch (FileNotFoundException e) {            e.printStackTrace();            return null;        }    }    public void inputStreamToFile(InputStream ins,File file){        OutputStream os = null;        try {            os = new FileOutputStream(file);        } catch (FileNotFoundException e) {            e.printStackTrace();        }        int bytesRead = 0;        byte[] buffer = new byte[8192];        try {            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {                os.write(buffer, 0, bytesRead);            }        } catch (IOException e) {            e.printStackTrace();        }        try {            os.close();        } catch (IOException e) {            e.printStackTrace();        }        try {            ins.close();        } catch (IOException e) {            e.printStackTrace();        }    }}四、有个蛋疼的问题,用genymotion模拟器,通过root权限手动添加的文件(随便打几个字符),通过ContentProvider获取时会提示权限不足。但是通过代码生成的文件则完全没有问题,有发现并解决了这个问题的。请一定回复或邮件告诉我,谢谢。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表