android - 如何在使用 Delphi 拍摄相机 Intent 照片后从 Android Gallery 中删除图像

标签 android delphi android-camera android-gallery

如何删除使用 Delphi Android 拍摄的相机 Intent 照片后的图库图像? 我的应用程序要求我发出拍照 Intent 。照片不能在图库中,而必须在我的特定自定义目录中。

如果您正在使用操作 TakePhotoFromCameraAction 属性 NeedSaveToAlbum := false 则不起作用。

这里引用来自 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...)

我找到了 solution在 Java 上,想法是:

  1. 当用户按下捕获按钮时, Intent 被发送,从图像媒体存储中获取最后一个 ID 并存储它。

  2. 然后当 Activity 返回时,检查捕获前的最后一个图像 ID,然后在捕获后查询具有大于记录的 ID 的图像 -

  3. 获取新图像的路径并将 jpg 文件复制(或更好地移动)到您自己的路径。如果您从 CameraSharedPath 中删除文件 - 图像仍会在 Android Gallery 中,所以

  4. 按 ID 从图库中删除图片。

最佳答案

这是我用 Delphi 做的。 如果您正在使用 Action TakePhotoFromCameraAction,请记住将 NeedSaveToAlbum 设置为 true。现在 NeedSaveToAlbum 不起作用,因为 Android 问题,但它可以在未来工作。 您还可以手动捕获调用 native Android Camera Intent 的图像(如何使用 Delphi 执行此操作 - 描述 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.

关于android - 如何在使用 Delphi 拍摄相机 Intent 照片后从 Android Gallery 中删除图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43021519/

相关文章:

android - 工具栏中的色调导航图标

delphi - Windows 7 上的 WideChar 显示问题

delphi - 如何使 TVirtualStringTree 以更高的优先级处理按键?

javascript - Android 4.3 上使用 Phonegap 中的 FileTransfer 将文件上传到 S3 时的代码 3

android - 创建类似于 Google Fit 的圆环图

android - RecyclerView - 跳转到位置,然后平滑滚动到顶部

delphi - 在 Delphi 中使用 Outlook 与其他电子邮件客户端有何不同?

Android 11 (R) 在查询 ACTION_IMAGE_CAPTURE 的 Intent 时返回空列表

android - 多次运行 Activity 后,Camera.startPreview 崩溃并重启手机

java - 相机与抽屉导航重叠 - Android