Added MediaScanner abilities to camera launcher plugin. Now images saved to SD card should show up in the android gallery app right away

This commit is contained in:
Fil Maj 2012-06-19 17:14:05 -07:00
parent 56acd2953b
commit b339330592

View File

@ -42,6 +42,8 @@ import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Bitmap.CompressFormat; import android.graphics.Bitmap.CompressFormat;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri; import android.net.Uri;
import android.os.Environment; import android.os.Environment;
import android.provider.MediaStore; import android.provider.MediaStore;
@ -52,7 +54,7 @@ import android.util.Log;
* and returns the captured image. When the camera view is closed, the screen displayed before * and returns the captured image. When the camera view is closed, the screen displayed before
* the camera view was shown is redisplayed. * the camera view was shown is redisplayed.
*/ */
public class CameraLauncher extends Plugin { public class CameraLauncher extends Plugin implements MediaScannerConnectionClient {
private static final int DATA_URL = 0; // Return base64 encoded string private static final int DATA_URL = 0; // Return base64 encoded string
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android) private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
@ -82,6 +84,8 @@ public class CameraLauncher extends Plugin {
public String callbackId; public String callbackId;
private int numPics; private int numPics;
private MediaScannerConnection conn; // Used to update gallery app with newly-written files
//This should never be null! //This should never be null!
//private CordovaInterface cordova; //private CordovaInterface cordova;
@ -330,13 +334,13 @@ public class CameraLauncher extends Plugin {
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it) // (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = null;
try { try {
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); this.imageUri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
LOG.d(LOG_TAG, "Can't write to external media storage."); LOG.d(LOG_TAG, "Can't write to external media storage.");
try { try {
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values); this.imageUri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException ex) { } catch (UnsupportedOperationException ex) {
LOG.d(LOG_TAG, "Can't write to internal media storage."); LOG.d(LOG_TAG, "Can't write to internal media storage.");
this.failPicture("Error capturing image - no media storage found."); this.failPicture("Error capturing image - no media storage found.");
@ -366,24 +370,28 @@ public class CameraLauncher extends Plugin {
bitmap = scaleBitmap(getBitmapFromResult(intent)); bitmap = scaleBitmap(getBitmapFromResult(intent));
// Add compressed version of captured image to returned media store Uri // Add compressed version of captured image to returned media store Uri
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri); OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(this.imageUri);
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os); bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
os.close(); os.close();
// Restore exif data to file // Restore exif data to file
if (this.encodingType == JPEG) { if (this.encodingType == JPEG) {
exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.cordova)); exif.createOutFile(FileUtils.getRealPathFromURI(this.imageUri, this.cordova));
exif.writeExifData(); exif.writeExifData();
} }
// Scan for the gallery to update pic refs in gallery
this.scanForGallery();
// Send Uri back to JavaScript for viewing image // Send Uri back to JavaScript for viewing image
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId); this.success(new PluginResult(PluginResult.Status.OK, this.imageUri.toString()), this.callbackId);
} }
bitmap.recycle(); bitmap.recycle();
bitmap = null; bitmap = null;
System.gc(); System.gc();
checkForDuplicateImage(FILE_URI); checkForDuplicateImage(FILE_URI);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
this.failPicture("Error capturing image."); this.failPicture("Error capturing image.");
@ -584,4 +592,26 @@ public class CameraLauncher extends Plugin {
public void failPicture(String err) { public void failPicture(String err) {
this.error(new PluginResult(PluginResult.Status.ERROR, err), this.callbackId); this.error(new PluginResult(PluginResult.Status.ERROR, err), this.callbackId);
} }
private void scanForGallery() {
if(this.conn!=null) this.conn.disconnect();
this.conn = new MediaScannerConnection(this.ctx.getActivity().getApplicationContext(), this);
conn.connect();
}
@Override
public void onMediaScannerConnected() {
try{
this.conn.scanFile(this.imageUri.toString(), "image/*");
} catch (java.lang.IllegalStateException e){
e.printStackTrace();
LOG.d(LOG_TAG, "Can;t scan file in MediaScanner aftering taking picture");
}
}
@Override
public void onScanCompleted(String path, Uri uri) {
this.conn.disconnect();
}
} }