Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 515|回复: 0

解决Android拍照保存在系统相册不显示的问题

[复制链接]
  • TA的每日心情
    奋斗
    前天 12:49
  • 签到天数: 789 天

    [LV.10]以坛为家III

    2049

    主题

    2107

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    722638
    发表于 2021-6-3 02:36:09 | 显示全部楼层 |阅读模式

    可能大家都知道我们保存相册到Android手机的时候,然后去打开系统图库找不到我们想要的那张图片,那是因为我们插入的图片还没有更新的缘故,先讲解下插入系统图库的方法吧,很简单,一句代码就能实现

     

    [java]  view plain  copy
     
     在CODE上查看代码片派生到我的代码片
    1. MediaStore.Images.Media.insertImage(getContentResolver(), mBitmap, "", "");  

    通过上面的那句代码就能插入到系统图库,这时候有一个问题,就是我们不能指定插入照片的名字,而是系统给了我们一个当前时间的毫秒数为名字,有一个问题郁闷了很久,我还是先把insertImage的源码贴出来吧

     

     

    [java]  view plain  copy
     
     在CODE上查看代码片派生到我的代码片
    1. /** 
    2.             * Insert an image and create a thumbnail for it. 
    3.             * 
    4.             * @param cr The content resolver to use 
    5.             * @param source The stream to use for the image 
    6.             * @param title The name of the image 
    7.             * @param description The description of the image 
    8.             * @return The URL to the newly created image, or <code>null</code> if the image failed to be stored 
    9.             *              for any reason. 
    10.             */  
    11.            public static final String insertImage(ContentResolver cr, Bitmap source,  
    12.                                                   String title, String description) {  
    13.                ContentValues values = new ContentValues();  
    14.                values.put(Images.Media.TITLE, title);  
    15.                values.put(Images.Media.DESCRIPTION, description);  
    16.                values.put(Images.Media.MIME_TYPE, "image/jpeg");  
    17.   
    18.                Uri url = null;  
    19.                String stringUrl = null;    /* value to be returned */  
    20.   
    21.                try {  
    22.                    url = cr.insert(EXTERNAL_CONTENT_URI, values);  
    23.   
    24.                    if (source != null) {  
    25.                        OutputStream imageOut = cr.openOutputStream(url);  
    26.                        try {  
    27.                            source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);  
    28.                        } finally {  
    29.                            imageOut.close();  
    30.                        }  
    31.   
    32.                        long id = ContentUris.parseId(url);  
    33.                        // Wait until MINI_KIND thumbnail is generated.  
    34.                        Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id,  
    35.                                Images.Thumbnails.MINI_KIND, null);  
    36.                        // This is for backward compatibility.  
    37.                        Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F,  
    38.                                Images.Thumbnails.MICRO_KIND);  
    39.                    } else {  
    40.                        Log.e(TAG, "Failed to create thumbnail, removing original");  
    41.                        cr.delete(url, null, null);  
    42.                        url = null;  
    43.                    }  
    44.                } catch (Exception e) {  
    45.                    Log.e(TAG, "Failed to insert image", e);  
    46.                    if (url != null) {  
    47.                        cr.delete(url, null, null);  
    48.                        url = null;  
    49.                    }  
    50.                }  
    51.   
    52.                if (url != null) {  
    53.                    stringUrl = url.toString();  
    54.                }  
    55.   
    56.                return stringUrl;  
    57.            }  

    上面方法里面有一个title,我刚以为是可以设置图片的名字,设置一下,原来不是,郁闷,哪位高手知道title这个字段是干嘛的,告诉下小弟,不胜感激!

     

    当然Android还提供了一个插入系统相册的方法,可以指定保存图片的名字,我把源码贴出来吧

     

    [java]  view plain  copy
     
     在CODE上查看代码片派生到我的代码片
    1. /** 
    2.           * Insert an image and create a thumbnail for it. 
    3.           * 
    4.           * @param cr The content resolver to use 
    5.           * @param imagePath The path to the image to insert 
    6.           * @param name The name of the image 
    7.           * @param description The description of the image 
    8.           * @return The URL to the newly created image 
    9.           * @throws FileNotFoundException 
    10.           */  
    11.          public static final String insertImage(ContentResolver cr, String imagePath,  
    12.                  String name, String description) throws FileNotFoundException {  
    13.              // Check if file exists with a FileInputStream  
    14.              FileInputStream stream = new FileInputStream(imagePath);  
    15.              try {  
    16.                  Bitmap bm = BitmapFactory.decodeFile(imagePath);  
    17.                  String ret = insertImage(cr, bm, name, description);  
    18.                  bm.recycle();  
    19.                  return ret;  
    20.              } finally {  
    21.                  try {  
    22.                      stream.close();  
    23.                  } catch (IOException e) {  
    24.                  }  
    25.              }  
    26.          }  

    啊啊,贴完源码我才发现,这个方法调用了第一个方法,这个name就是上面方法的title,晕死,这下更加郁闷了,反正我设置title无效果,求高手为小弟解答,先不管了,我们继续往下说

     

    上面那段代码插入到系统相册之后还需要发条广播

     

    [java]  view plain  copy
     
     在CODE上查看代码片派生到我的代码片
    1. sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));    

    上面那条广播是扫描整个sd卡的广播,如果你sd卡里面东西很多会扫描很久,在扫描当中我们是不能访问sd卡,所以这样子用户体现很不好,用过微信的朋友都知道,微信保存图片到系统相册并没有扫描整个SD卡,所以我们用到下面的方法

     

     

    [java]  view plain  copy
     
     在CODE上查看代码片派生到我的代码片
    1. Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);     
    2.  Uri uri = Uri.fromFile(new File("/sdcard/image.jpg"));     
    3.  intent.setData(uri);     
    4.  mContext.sendBroadcast(intent);    

    或者用MediaScannerConnection

     

     

    [java]  view plain  copy
     
     在CODE上查看代码片派生到我的代码片
    1. final MediaScannerConnection msc = new MediaScannerConnection(mContext, new MediaScannerConnectionClient() {     
    2.   public void onMediaScannerConnected() {     
    3.    msc.scanFile("/sdcard/image.jpg", "image/jpeg");     
    4.   }     
    5.   public void onScanCompleted(String path, Uri uri) {     
    6.    Log.v(TAG, "scan completed");     
    7.    msc.disconnect();     
    8.   }     
    9.  });     

    也行你会问我,怎么获取到我们刚刚插入的图片的路径?呵呵,这个自有方法获取,insertImage(ContentResolver cr, Bitmap source,String title, String description),这个方法给我们返回的就是插入图片的Uri,我们根据这个Uri就能获取到图片的绝对路径

     

     

    [java]  view plain  copy
     
     在CODE上查看代码片派生到我的代码片
    1. private  String getFilePathByContentResolver(Context context, Uri uri) {  
    2.         if (null == uri) {  
    3.             return null;  
    4.         }  
    5.         Cursor c = context.getContentResolver().query(uri, null, null, null, null);  
    6.         String filePath  = null;  
    7.         if (null == c) {  
    8.             throw new IllegalArgumentException(  
    9.                     "Query on " + uri + " returns null result.");  
    10.         }  
    11.         try {  
    12.             if ((c.getCount() != 1) || !c.moveToFirst()) {  
    13.             } else {  
    14.                 filePath = c.getString(  
    15.                         c.getColumnIndexOrThrow(MediaColumns.DATA));  
    16.             }  
    17.         } finally {  
    18.             c.close();  
    19.         }  
    20.         return filePath;  
    21.     }  

    根据上面的那个方法获取到的就是图片的绝对路径,这样子我们就不用发送扫描整个SD卡的广播了,呵呵,写到这里就算是写完了,写的很乱,希望大家将就的看下,希望对你有帮助!

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-9-8 22:30 , Processed in 1.001380 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表