今天要做一个保存图片到系统图库的功能,自身能力较浅,所以只能搜索了但发现网上的方法有几处bug,所以自己总结一下防止以后忘掉也想和大家分享一下.首页网上保存图片并插入系统图库的方法:
// 首先保存图片 File appDir = new File(SAMPLE_DEFAULT_DIR) if (!appDir.exists()) { appDir.mkdir() } String fileName = System.currentTimeMillis() + ".jpg" File file = new File(appDir, fileName) try { FileOutputStream fos = new FileOutputStream(file) bmp.compress(CompressFormat.JPEG, 100, fos) fos.flush() fos.close() } catch (FileNotFoundException e) { e.printStackTrace() } catch (IOException e) { e.printStackTrace() } // 其次把文件插入到系统图库 try { MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null) } catch (FileNotFoundException e) { e.printStackTrace() }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
我之前也用这种方法保存,但是我发现图片过大时 调用MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(), fileName, null);方法会出现oom异常,很讨厌.所以我又在网上找了一个方法:
public boolean saveImageToGallery(Context context, Bitmap bitmap) { File dir = new File(SAMPLE_DEFAULT_DIR); if (!dir.exists()) { dir.mkdirs(); } long dateTaken = System.currentTimeMillis(); final String filename = DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken) .toString() + ".jpg"; try { HexOneToOneBitmapUtil.insertImage(getActivity().getContentResolver(), filename, dateTaken, SAMPLE_DEFAULT_DIR,filename, bitmap, null); } catch (Exception e) { HexLog.e(e.getMessage()); return false; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
public static Uri insertImage(ContentResolver cr, String name, long dateTaken, String directory, String filename, Bitmap source, byte[] jpegData) { OutputStream outputStream = null String filePath = directory + filename try { File dir = new File(directory) if (!dir.exists()) { dir.mkdirs() } File file = new File(directory, filename) if (file.createNewFile()) { outputStream = new FileOutputStream(file) if (source != null) { source.compress(Bitmap.CompressFormat.JPEG, 100, outputStream) } else { outputStream.write(jpegData) } } } catch (FileNotFoundException e) { HexLog.e(e.getMessage()) return null } catch (IOException e) { HexLog.e(e.getMessage()) return null } finally { if (outputStream != null) { try { outputStream.close() } catch (Throwable t) { } } } ContentValues values = new ContentValues(7) values.put(MediaStore.Images.Media.TITLE, name) values.put(MediaStore.Images.Media.DISPLAY_NAME, filename) values.put(MediaStore.Images.Media.DATE_TAKEN, dateTaken) values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") values.put(MediaStore.Images.Media.DATA, filePath) return cr.insert(IMAGE_URI, values) }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
这样就可以完美解决oom异常了.
虽然咱们把图片保存到本地了,但是咱们得发通知从新检索一遍,才能在图库中看到咱们的图片.通常有两种
try { context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(file.getPath())))); }catch (Exception e){ return false; }
final MediaScannerConnection msc = new MediaScannerConnection(mContext, new MediaScannerConnectionClient() { public void onMediaScannerConnected() { msc.scanFile(SAMPLE_DEFAULT_DIR,filename); } public void onScanCompleted(String path, Uri uri) { Log.v(TAG, "scan completed"); msc.disconnect(); } });
网上说第一种发广播的方法在4.4以后就会出现异常,因为4.4以后只有系统软件才可以有扫描SD卡的权限,咱们的app肯定得适配不同的操作系统吧,所以只能用第二种方法了.但是把第二种方法拷到代码中会报错,根本不能这样用.所以咱们可以这样用
private MediaScannerConnection mMediaonnection; try { mMediaonnection = new MediaScannerConnection(context, new MediaScannerConnection.MediaScannerConnectionClient() { @Override public void onMediaScannerConnected() { mMediaonnection.scanFile(SAMPLE_DEFAULT_DIR,filename); } @Override public void onScanCompleted(String path, Uri uri) { mMediaonnection.disconnect(); } }); mMediaonnection.connect(); }catch (Exception e){ return false; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
这样就解决了第二种方法的问题,到这你就可以保存图片并可以到系统图库中看到了
PS:SAMPLE_DEFAULT_DIR 这只是我自己定义的文件夹路径,大家可以自行定义.
另外我也只是一个菜鸟,代码的搬运工.所以太高深的问题我也不知道 不好意思.但是我相信你遇到的问题 肯定别人也遇到过 也肯定被解决过 所以不要急 慢慢来 多在网上找找.