1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.example.rscamera; 18 19import java.io.FileNotFoundException; 20import java.io.IOException; 21import java.io.OutputStream; 22 23import android.content.ContentResolver; 24import android.content.ContentUris; 25import android.content.ContentValues; 26import android.graphics.Bitmap; 27import android.graphics.Matrix; 28import android.net.Uri; 29import android.provider.MediaStore; 30import android.provider.MediaStore.Images; 31 32/** 33 * Utility class to save images into android image database 34 */ 35public class MediaStoreSaver { 36 public static interface StreamWriter { 37 void write(OutputStream imageOut) throws IOException; 38 } 39 40 public static final String insertImage(ContentResolver contentResolver, 41 Bitmap image, 42 String title, 43 String description) { 44 final Bitmap source = image; 45 StreamWriter streamWriter = new StreamWriter() { 46 public void write(OutputStream imageOut) { 47 source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut); 48 } 49 }; 50 return insertImage(contentResolver, streamWriter, title, description); 51 } 52 53 54 public static final String insertImage(ContentResolver cr, 55 StreamWriter source, 56 String title, 57 String description) { 58 59 ContentValues values = new ContentValues(); 60 values.put(Images.Media.TITLE, title); 61 values.put(Images.Media.DISPLAY_NAME, title); 62 values.put(Images.Media.DESCRIPTION, description); 63 values.put(Images.Media.MIME_TYPE, "image/jpeg"); 64 // Add the date meta data to ensure the image is added at the front of the gallery 65 values.put(Images.Media.DATE_ADDED, System.currentTimeMillis()); 66 values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis()); 67 68 Uri url = null; 69 String stringUrl = null; /* value to be returned */ 70 71 try { 72 url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 73 74 if (source != null) { 75 OutputStream imageOut = cr.openOutputStream(url); 76 try { 77 source.write(imageOut); 78 } finally { 79 imageOut.close(); 80 } 81 82 long id = ContentUris.parseId(url); 83 // Wait until MINI_KIND thumbnail is generated. 84 Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null); 85 // This is for backward compatibility. 86 storeThumbnail(cr, miniThumb, id, 50F, 50F, Images.Thumbnails.MICRO_KIND); 87 } else { 88 cr.delete(url, null, null); 89 url = null; 90 } 91 } catch (Exception e) { 92 if (url != null) { 93 cr.delete(url, null, null); 94 url = null; 95 } 96 } 97 98 if (url != null) { 99 stringUrl = url.toString(); 100 } 101 102 return stringUrl; 103 } 104 105 /** 106 * A copy of the Android internals StoreThumbnail method, it used with the insertImage to 107 * populate the android.provider.MediaStore.Images.Media#insertImage with all the correct 108 * meta data. The StoreThumbnail method is private so it must be duplicated here. 109 * 110 * @see android.provider.MediaStore.Images.Media (StoreThumbnail private method) 111 */ 112 private static final Bitmap storeThumbnail( 113 ContentResolver cr, 114 Bitmap source, 115 long id, 116 float width, 117 float height, 118 int kind) { 119 120 // create the matrix to scale it 121 Matrix matrix = new Matrix(); 122 123 float scaleX = width / source.getWidth(); 124 float scaleY = height / source.getHeight(); 125 126 matrix.setScale(scaleX, scaleY); 127 128 Bitmap thumb = Bitmap.createBitmap(source, 0, 0, 129 source.getWidth(), 130 source.getHeight(), matrix, 131 true 132 ); 133 134 ContentValues values = new ContentValues(4); 135 values.put(Images.Thumbnails.KIND, kind); 136 values.put(Images.Thumbnails.IMAGE_ID, (int) id); 137 values.put(Images.Thumbnails.HEIGHT, thumb.getHeight()); 138 values.put(Images.Thumbnails.WIDTH, thumb.getWidth()); 139 140 Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values); 141 142 try { 143 OutputStream thumbOut = cr.openOutputStream(url); 144 thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut); 145 thumbOut.close(); 146 return thumb; 147 } catch (FileNotFoundException ex) { 148 return null; 149 } catch (IOException ex) { 150 return null; 151 } 152 } 153 154 155} 156