alitrun
alitrun

Reputation: 1218

How to delete an image from Android Gallery after camera intent photo taken with Delphi

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.

Upvotes: 2

Views: 1460

Answers (1)

alitrun
alitrun

Reputation: 1218

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.

Upvotes: 2

Related Questions