zoukankan      html  css  js  c++  java
  • 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;
        }

     

  • 相关阅读:
    Promise原理实现(一):前置知识点
    移动端禁用缩放
    多条命令同时执行的包concurrently
    通过面试题学JavaScript知识(1)
    移动设备适配
    css 文本溢出显示省略号
    变量对象的理解
    7.10 日志
    7.9 日志
    JMETER接口测试之自动化环境的配置
  • 原文地址:https://www.cnblogs.com/qinghuaideren/p/3180850.html
Copyright © 2011-2022 走看看