Android分享图片失败解决方案
前言:在做图片分享到微博或是用彩信分享的时候,会遇到“无法将图片添加到信息中”,其实这个问题的原因是创建的那个图片默认是,只能被当前应用调用,无法被其他应用调用,即分享的时候,无法读取到图片,并提示IO错误,所以解决方案就是创建文件的时候,赋予这个文件读写权限,即可以被其他应用读写。
代码如下:
1.保存图片到内存中:data/data/应用包名/files/文件
/** * 将图片存放在公开的文件中,用于其他应用读取 * * @param in * 数据流 * @param name * 文件的名字 * @param context * 上下文 */ public static void copyPrivateRawResourceToPubliclyAccessibleFile( InputStream in, String name, Context context) { FileOutputStream outputStream = null; try { // openFileOutput是android提供的一个方法,参数1:文件的名字包含扩展名(名字中不能包含/),参数2:创建文件所有的权限 outputStream = ((Activity) context).openFileOutput(name, Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE); byte[] buffer = new byte[1024]; int length = 0; try { while ((length = in.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } } catch (IOException ioe) { /* ignore */ } } catch (FileNotFoundException fnfe) { /* ignore */ } finally { try { in.close(); } catch (IOException ioe) { /* ignore */ } try { outputStream.close(); } catch (IOException ioe) { /* ignore */ } } }
2.访问保存的图片
// 创建分享跳转,向其中加入分享图片的地址,这个地址不是SD卡中的 // getFileStreamPath()方法是android提供的,通过name获得刚刚存储的文件绝对路径,并加入分享中。 mBase_intent = new Intent(Intent.ACTION_SEND); mBase_intent.setType("image/*"); mBase_intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(getFileStreamPath(mName))); provide.setShareIntent(mBase_intent);
3.上面的代码就决解了分享时,图片不能获取的问题,因为文件名字一直是一个,所以应用生成的图片始终是一个,不用担心浪费内存。
下面讲解怎么将图片放入SD卡中。
这个工具类,会判断是否有SD卡,有的话就优先SD卡中建立保存图片的文件夹,若是没有SD卡,就在内存建立:
/** * 保存图片到本地 * * @param is * 图片的is流 * @param imageUri * 图片的网络地址 * @param context * @param filename * 文件的名称 */ public static HashMap<String, Object> saveBitmap_From_Is(InputStream is, String imageUri, Context context, String filename, final Handler handler) { final HashMap<String, Object> map = new HashMap<String, Object>(); File cache = getCache(imageUri, context, filename); if (cache == null) { return null; } FileOutputStream os = null; try { os = new FileOutputStream(cache); byte[] data = new byte[is.available()]; is.read(data); os.write(data); os.close(); is.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 通知系统增加了一个图片,有的手机不能刷新,导致相册中不能及时显示图片。 MediaScannerConnection.scanFile(context, new String[] { cache.getAbsolutePath() }, null, new MediaScannerConnection.OnScanCompletedListener() { @Override public void onScanCompleted(String path, Uri uri) { Message age = new Message(); Bundle bundle = new Bundle(); bundle.putString("uri", uri.toString()); bundle.putString("path", path); age.setData(bundle); handler.sendMessage(age); Show_Log("通知系统增加了一个图片URI" + uri.toString()); Show_Log("通知系统增加了一个图片PATH" + path); } }); map.put("path", cache.getAbsolutePath()); map.put("file", cache.getAbsoluteFile()); return map; }
建立缓存文件夹的工具类:
/** * 创建文件的缓存文件路径,判断是否有SD卡,有就在其中建立,没有就在内存中建立。 这个文件夹是直接在SD/filename形式的。 * * @param imageUri * 图片的网络路径,一般/后边就是图片的名字,也可以直接写图片的名字,需要加上.png * @param context * 上下文,用于创建文件夹 * @param filename * 文件夹的名字,SD卡中的文件的名字使用了系统提供的Environment.DIRECTORY_PICTURES,而 * 内存中的文件的名字使用了filename,其实随意就可以。 * @return */ public static File getCache(String imageUri, Context context, String filename) { String imagename = imageUri.substring(imageUri.lastIndexOf("/") + 1); File cache = null; if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState())) { File file = Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); if (file.exists()) { file.mkdirs(); } cache = new File(file, imagename); Show_Log("建立SD卡缓存=" + cache); } else { if (context.getFileStreamPath(filename).exists()) { context.getFileStreamPath(filename).mkdirs(); } cache = new File(context.getFileStreamPath(filename), imagename); Show_Log("建立内存卡缓存=" + cache); } if (cache.exists()) { Toast.makeText(context, "文件已保存", Toast.LENGTH_LONG).show(); return null; } return cache; }