locked
Problems with Camera activity saving photos to the gallery RRS feed

  • Question

  • User1280 posted

    I did post this to the chat room but seems as though no-one is/was about...

    I'd like some help please with a problem with the camera. I have noticed that on some devices, even though I pass the required file name to the camera intent, that it creates the photograph in the folder specified but also creates a copy in the Camera roll / gallery. On my Samsung Galaxy Ace 2 I have been able to identify the last photo taken and simply delete the file however on my HTC even though I delete the physical file I then see a 'placeholder' in the gallery application which suggests that the gallery has a record of the photograph and does not like me deleting the physical file.

    Is there a more 'supported' way of removing a photograph from the gallery or even better a way to prevent the extra file being created in the first place?

    Tuesday, April 23, 2013 3:27 PM

All replies

  • User9600 posted

    Some devices insist on saving it to the default gallery, furthermore other weird behaviours exist. Like returning a thumbnail to your specified path and saving full size image in the default gallery.

    Take a look at this stackoverflow question for workarounds and more detailed explanations

    Tuesday, April 23, 2013 6:46 PM
  • User1280 posted

    Thanks for the suggestion - looks as though I need to delete the photograph from the Gallery using the ContentResolver - I already have the file name but cannot quite see how to use this with the COntentResolver directly. Do I need to query the MediaStore to get something which can be used to delete the photograph or is there a better way given that I already have the fully qualified file name?

    Thursday, April 25, 2013 11:26 AM
  • User1280 posted

    Just in case anyone else searches this is what I have come up with. Prior to invoking the camera activity I save the current date / time and then recover it in the OnActivityResult handler. Note that on my phone I don not get an Intent passed back to this function so can't use it.

    try { String[] proj = { MediaStore.MediaColumns.Data.ToString(), BaseColumns.Id }; var qry = ManagedQuery(MediaStore.Images.Media.ExternalContentUri, proj, null, null, "date_added DESC"); qry.MoveToFirst();

    // Get the media ID and date of this photograph and delete if taken after we took the photo as this
    // would indicate that the camera has saved the photo taken by SWS to the Gallery which we do not want. 
    string lastPhotoID = qry.GetString(qry.GetColumnIndexOrThrow(MediaStore.MediaColumns.Id));
    long mediaID = long.Parse(lastPhotoID);
    DateTime lastGalleryPhotoDate = DateTime.Parse(qry.GetString(qry.GetColumnIndexOrThrow(MediaStore.MediaColumns.DateAdded)));
    
    // If this was taken AFTER the date of last photo which we have stored then we can safely delete the photograph
    if (lastGalleryPhotoDate >= lastPhotographDate)
    {
        ContentResolver cr = this.ContentResolver;
        Android.Net.Uri contentUri = MediaStore.Images.Media.ExternalContentUri;
        Android.Net.Uri itemUri = ContentUris.WithAppendedId(contentUri, mediaID);
        int rows = cr.Delete(itemUri, null, null);
    }
    

    }

    Thursday, April 25, 2013 12:35 PM
  • User122934 posted

    Thanks @ChrisDrew for the code. I have not tested it yet but appreciate the help. I also wanted to add, for anyone that comes across this, that ManagedQuery is now deprecated and ContentResolver should be used instead. For me I changed ChrisDrew's code above, to the following, in order to make it at least build on the latest Xamarin Android version and without being in an activity (this is in a class called NativeHelper_Android, which inherits from INativeHelper from within my PCL shared project, and gets called using the DependencyService):

    public async Task RemovePhotoGalleryImageAsync(DateTime savedPhotoDate) {
    
        await Task.Run(() => {
            ContentResolver cr = Forms.Context.ApplicationContext.ContentResolver;
    
            try {
                ICursor qry = cr.Query(MediaStore.Images.Media.ExternalContentUri, new[] { MediaStore.MediaColumns.Data, BaseColumns.Id }, null, null, "date_added DESC");
                qry.MoveToFirst();
    
                // Get the media Id and date of this photograph and delete if taken after we took the photo as this
                //  would indicate that the camera has saved the photo taken by SWS to the Gallery which we do not want.
                string lastPhotoId            = qry.GetString(qry.GetColumnIndexOrThrow(MediaStore.MediaColumns.Id));
                long mediaId                  = long.Parse(lastPhotoId);
                DateTime lastGalleryPhotoDate = DateTime.Parse(qry.GetString(qry.GetColumnIndexOrThrow(MediaStore.MediaColumns.DateAdded)));
    
                if(lastGalleryPhotoDate >= savedPhotoDate) {    // If this was taken AFTER the date of last photo which we have stored then we can safely delete the photograph
    
                    Uri contentUri = MediaStore.Images.Media.ExternalContentUri;
                    Uri itemUri    = ContentUris.WithAppendedId(contentUri, mediaId);
                    int rows       = Forms.Context.ApplicationContext.ContentResolver.Delete(itemUri, null, null);
                    Console.WriteLine("\nNativeHelper_Android.RemovePhotoGalleryImageAsync() - Deleted {0} items.\n", rows);
                }
            } catch(Exception ex) { Console.WriteLine("\nNativeHelper_Android.RemovePhotoGalleryImageAsync() - Exception:\n{0}\n", ex); //TODO: Do something more useful here }
        }).ConfigureAwait(false);
    

    But again, I have not yet been able to find the correct Android version/device to test this on. I am sure I will get a bug report sooner or later to actually try it out on, but if you know what Android API version / device type that I can use to try it on, please let me know. Thanks.

    Thursday, September 3, 2015 10:47 PM