一、新建一个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获取时会提示权限不足。但是通过代码生成的文件则完全没有问题,有发现并解决了这个问题的。请一定回复或邮件告诉我,谢谢。
新闻热点
疑难解答