1

How to delete a gallery image after camera intent photo taken with Delphi Android? My application requires me to call an intent to take a photo. The photo cannot be in the gallery but instead must be in a specific my custom directory.

If you're using action TakePhotoFromCameraAction property NeedSaveToAlbum := false is not working.

Here is a quote from one of the question from stackoverflow:

Originally user must use the EXTRA_OUTPUT, but I soon discovered the following: - Some devices use it completely and skip the gallery. - Some devices ignore it completely and ONLY use the gallery. - Some devices really suck and save a full sized image to the gallery, and save a thumbnail only to the location I wanted. (HTC you know who you are...)

I found solution on Java, the idea is:

  1. When user pressed capture button the intent is sent, go and get the last id from image mediastore and store it.

  2. Then when the activity returns, checks for the last image id before capture, then queries for images after capture have an id larger then recorded -

  3. Get a path of that new image and copy (or better move) jpg file to your own path. If you delete a file from CameraSharedPath - image still will be in Android Gallery, so

  4. Delete image from Gallery by its ID.
Community
  • 1
  • 1
alitrun
  • 1,127
  • 8
  • 14
  • `The photo cannot be in the gallery but instead must be in a specific directory.` That is nonsense. The Gallery app is no storage place but just an app that shows all images on your device. Every image file will be in a directory. Where should a file be else? Please rephrase your problem. – greenapps Mar 25 '17 at 20:34
  • Android Gallery is a virtual storage, Android's MediaScanner scans folders on SD card, and add them to a Gallery. Android usually saves photo in TPath.GetSharedCameraPath , but if you delete file from that place - it still be in a Gallery - I already checked - I do not know maybe it is a cached file. I fixed phrase to `The photo cannot be in the gallery but instead must be in a specific my custom directory.` – alitrun Mar 25 '17 at 20:42
  • No storage at all. The Gallery app can use a thumbnail from the MediaStore that is still there. You have to inform the media store that the file is gone. Or restart your device. – greenapps Mar 25 '17 at 21:04

1 Answers1

1

Here is how I did it with Delphi. If you're using action TakePhotoFromCameraAction remember to set NeedSaveToAlbum to true. Now NeedSaveToAlbum does not work, because of Android problems, but it can work in future. You also can capture images calling native Android Camera Intent manually (how to do it with Delphi - described here)

unit Misc.Android;

interface

uses
  SysUtils,
  Androidapi.JNI.GraphicsContentViewText, Androidapi.Helpers, Androidapi.JNI.JavaTypes,
  Androidapi.JNIBridge, Androidapi.JNI.Provider;

type
  TGallery = class
  public
    class function GetLastImageID: integer;
    class function GetNextImageIDFromID(aFromID: integer; out aImagePath: string): integer;
    class function DeleteImageByID(aID: integer): boolean;
  end;


implementation

const
  _ID = '_id'; //  TJBaseColumns.JavaClass._ID   // uri in Androidapi.JNI.Provider

{ TGallery }

{If you're using action TakePhotoFromCameraAction remember to set NeedSaveToAlbum to true.
 It does not work, because of Android problems, but it can work in future.}

class function TGallery.GetLastImageID: integer;
var
  vContent: JContentResolver;
  vValues: TJavaObjectArray<JString>;
  vOrderBy: JString;
  vCursor: JCursor;
begin
  Result := -1;
  vContent := TAndroidHelper.Activity.getContentResolver;

  vValues := TJavaObjectArray<JString>.Create(1);
  vValues[0] := TJBaseColumns.JavaClass._ID;

  vOrderBy := StringToJString(_ID + ' DESC');

  vCursor := vContent.query(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI,
      vValues, nil, nil, vOrderBy);
  try
    if vCursor.moveToFirst then
      Result := vCursor.getInt( vCursor.getColumnIndex(TJBaseColumns.JavaClass._ID) );
  finally
    vCursor.close;
  end
end;

// Result is next Image ID and its aImagePath - is path to jpg image
class function TGallery.GetNextImageIDFromID(aFromID: integer; out aImagePath: string): integer;
var
  vContent: JContentResolver;
  vValues: TJavaObjectArray<JString>;
  vFilter: JString;
  vOrderBy: JString;
  vArgs : TJavaObjectArray<JString>;
  vCursor: JCursor;
begin
  Result := -1;
  aImagePath := '';
  vContent := TAndroidHelper.Activity.getContentResolver;
  vValues := TJavaObjectArray<JString>.Create(2);
  vValues[0] := TJMediaStore_MediaColumns.JavaClass.DATA;
  vValues[1] := TJBaseColumns.JavaClass._ID;
   // vValues[1] := TJMediaStore_MediaColumns.JavaClass.SIZE;
   // vValues[1] := TJImages_ImageColumns.JavaClass.DATE_TAKEN;

  vOrderBy := StringToJString(_ID + ' DESC');
  vFilter := StringToJString(_ID + '>?');
  vArgs := TJavaObjectArray<JString>.Create(1);  
  vArgs[0] := StringToJString(aFromID.ToString);

  vCursor := vContent.query(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI,
     vValues, vFilter, vArgs, vOrderBy);
  try
    if (vCursor.getCount > 0) and vCursor.moveToFirst then
    begin
      Result := vCursor.getInt( vCursor.getColumnIndex(TJBaseColumns.JavaClass._ID) );
      // vCursor.getLong(imageCursor.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN));
      //vSize := wCursor.getLong(wCursor.getColumnIndex(TJMediaStore_MediaColumns.JavaClass.SIZE));
      aImagePath := JStringToString(vCursor.getString(
          vCursor.getColumnIndex(TJMediaStore_MediaColumns.JavaClass.DATA) ));
    end;
  finally
    vCursor.close;
  end;
end;

class function TGallery.DeleteImageByID(aID: integer): boolean;
var
  vContent: JContentResolver;
begin
  vContent := TAndroidHelper.Activity.getContentResolver;
  Result := vContent.delete(TJImages_Media.JavaClass.EXTERNAL_CONTENT_URI,
        StringToJString(_ID + '=' + aID.ToString), nil) = 1;
end;

end.
alitrun
  • 1,127
  • 8
  • 14