博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过ContentProvider访问应用的data区files的文件
阅读量:6329 次
发布时间:2019-06-22

本文共 6747 字,大约阅读时间需要 22 分钟。

  hot3.png

    工作中遇到需要将一张超过2M的图传递给另外一个应用使用。

之前是通过Intent中放Bundle对象,通过bundle对象存二进制数组,通过广播的形式发送给另外一个应用,另外一个应用根据key值来获取数组,将数组转成Bitmap。

      Bundle b = new Bundle();      b.putByteArray(key_byte, flattenBitmap(bitmap));            intent.putExtra(key_bundle, b);      sendBroadcast(intent);
 public static byte[] flattenBitmap(Bitmap bitmap) {  // Try go guesstimate how much space the icon will take when serialized  // to avoid unnecessary allocations/copies during the write.  int size = bitmap.getWidth() * bitmap.getHeight() * 4;  ByteArrayOutputStream out = new ByteArrayOutputStream(size);  try {   bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);   out.flush();   out.close();   return out.toByteArray();  } catch (IOException e) {   Log.w("Favorite", "Could not write icon");   return null;  } }

另外一个应用 只要通过intent 得到bundle:

Bundle b = intent.getBundleExtra(key_bundle);

byte [] bd = null;

 if(b != null)

         bd = (byte[]) b.get(key_byte);

得到这个数组就可以得到这个张bitmap了。

 

由于这种方式 传递的图是有大小限制的,如果传入的Bitmap超过一定的大小,就会无法传递过去,抛出异常。

 

现在改成通过ContentProvider的方式。

一开始的时候,写sqlite,然后再写provider共享出去,结果sqlite中存bitmap也是有限制的。

放弃之。

现在的方式:

ContentProvider中重新ParcelFileDescriptor openFile(Uri uri, String mode)这个方法。

 package com.android.launcher2;import java.io.BufferedOutputStream;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import android.content.ContentProvider;import android.content.ContentValues;import android.content.Context;import android.content.Intent;import android.content.UriMatcher;import android.content.res.AssetFileDescriptor;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.AsyncTask;import android.os.ParcelFileDescriptor;import android.util.DisplayMetrics;import android.util.Log;import android.view.WindowManager;public class LockscreenWallpaperProvider extends ContentProvider { private static final String TAG = "LockscreenWallpaperProvider"; public static final Uri CONTENT_URI = Uri   .parse("content://com.android.launcher.lockscreenwallpaper/"); private final static String AUTHORITY = "com.android.launcher.lockscreenwallpaper"; private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH); private static final int LOCKSCREEN_WALLPAPER = 1;  static {  MATCHER.addURI(AUTHORITY, "lockscreen_wallpaper.png", LOCKSCREEN_WALLPAPER); }    private static final String LOCKSCREEN_WALLPAPER_UPDATE = "com.ape.launcher.wallpaper.CROP_ACTION";  @Override public boolean onCreate() {  return true; } @Override public Cursor query(Uri uri, String[] projection, String selection,   String[] selectionArgs, String sortOrder) {  return null; } @Override public String getType(Uri uri) {  if (uri.toString().endsWith(".png")) {   return "image/png";  }  return null; } @Override public Uri insert(Uri uri, ContentValues values) {   Log.d(TAG, "insert---->uri = "+uri);   Log.d(TAG, "MATCHER.match(uri) =  "+MATCHER.match(uri));     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; }   @Override  public AssetFileDescriptor openAssetFile(Uri uri, String mode)   throws FileNotFoundException {  // TODO Auto-generated method stub  Log.d(TAG, "openAssetFile");  return super.openAssetFile(uri, mode); }   @Override public ParcelFileDescriptor openFile(Uri uri, String mode)   throws FileNotFoundException {  Log.d(TAG, "openFile::::::::getType(uri) = "+getType(uri));  Log.d(TAG, "uri = "+uri);  Log.d(TAG, "uri.getPath() = "+uri.getPath());  if ("image/png".equals(getType(uri))) {    Log.d(TAG, "openFile");    File file = new File(getContext().getFilesDir(),     uri.getPath());   if (file.exists()) {    Log.d(TAG, "file = exist");    return ParcelFileDescriptor.open(file,      ParcelFileDescriptor.MODE_READ_ONLY);   }else {    Log.d(TAG, "file != exist");   }  }  throw new FileNotFoundException(uri.getPath()); }   }

Androidmanifest.xml 写上

        
        

      这样就可以被别的应用访问了。

 package com.example.lockscreenwallpaperdemo;import java.io.BufferedOutputStream;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import android.app.Activity;import android.content.res.AssetFileDescriptor;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;public class MainActivity extends Activity { private ImageView mImageView; private Button button; public static final Uri URI_LOCKSCREEN_WALLPAPER = Uri.parse("content://com.android.launcher.lockscreenwallpaper/lockscreen_wallpaper.png");  @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);    mImageView = (ImageView)this.findViewById(R.id.image);  startLoadImageTask();   }   void startLoadImageTask() {  if (mLoadImageTask != null && mLoadImageTask.getStatus() != LoadImageAsyncTask.Status.FINISHED) {   mLoadImageTask.cancel();  }  mLoadImageTask = (LoadImageAsyncTask)new LoadImageAsyncTask().execute(); }  LoadImageAsyncTask mLoadImageTask;    class LoadImageAsyncTask extends AsyncTask
 {     protected Bitmap doInBackground(String... params) {   Bitmap bmpout = null;         try {     //通过ContentResolver获取图片的输入流,再转化为Bitmap     InputStream is = getContentResolver().openInputStream(URI_LOCKSCREEN_WALLPAPER);     bmpout = BitmapFactory.decodeStream(is);     } catch (FileNotFoundException e) {     // TODO Auto-generated catch block 32.e.printStackTrace();      Log.e(TAG, "FileNotFoundException----->33333");    }                     return bmpout;     }          protected void onPostExecute(Bitmap result) {      if (result == null) {       return;      }            if (!isCancelled()) {       mImageView.setImageBitmap(result);             }else {       result.recycle();      }     }     void cancel() {      super.cancel(true);     }    }    }

 这个方法解决访问的问题。

如果这个应用要去修改provider出来的数据,好像没有别的方法。insert 和update方法应该也不行。

如果某位大神知道,还请指导下,谢谢。

 

 

转载于:https://my.oschina.net/jm2020/blog/371372

你可能感兴趣的文章
为你量身定做的一场容器技术大会
查看>>
阿里宣布开源Flutter应用框架Fish Redux!
查看>>
艰困之道中学到的经验教训
查看>>
Oracle推出轻量级Java微服务框架Helidon
查看>>
基于clang插件的一种iOS包大小瘦身方案
查看>>
IBM技术专家:Hyperleger Fabric 架构与部署实例解析
查看>>
企业金融云存储建设之路
查看>>
腾讯云携手SENSORO,为城市安全保驾护航
查看>>
webpack学习(二)—— 进阶
查看>>
基于ES6的代码重构要点
查看>>
封装SLF4J/Log4j,不再处处定义logger变量
查看>>
可信前端之路-代码保护
查看>>
javascript操作符知识点整理
查看>>
如何打造一个令人愉悦的前端开发环境(二)
查看>>
LeetCode: 344. Reverse String
查看>>
126. Word Ladder II
查看>>
[Note] C++动态内存:智能指针、动态数组
查看>>
RecyclerView.Adapter优化了吗?
查看>>
关于 Cannot find module 'xxx' 错误的记录
查看>>
JPA使用枚举
查看>>