【问题标题】:Deleting a gallery image after camera intent photo taken拍摄相机意图照片后删除图库图像
【发布时间】:2011-06-17 18:30:48
【问题描述】:

我知道这个问题已经以许多不同的方式提出,但我似乎仍然无法从默认文件夹中删除图库图像。我已将文件正确保存到 SD 卡,我可以正常删除该文件,但不会删除文件夹 Camera 下显示的默认图库图像文件。

我希望在返回活动后删除该图像,因为该文件已存储在 SD 卡上的 /Coupon2 下。

有什么建议吗?

public void startCamera() {
    Log.d("ANDRO_CAMERA", "Starting camera on the phone...");

    mManufacturerText = (EditText) findViewById(R.id.manufacturer);
    String ManufacturerText = mManufacturerText.getText().toString();
    String currentDateTimeString = new Date().toString();

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    File filedir = new File(Environment.getExternalStorageDirectory()+"/Coupon2");
    filedir.mkdirs();

    File file = new File(Environment.getExternalStorageDirectory()+"/Coupon2", ManufacturerText+"-test.png");
    outputFileUri = Uri.fromFile(file);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

    startActivityForResult(intent, CAMERA_PIC_REQUEST);
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_PIC_REQUEST && resultCode == -1) {  
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.putExtra("crop", "true");
        intent.putExtra("scale", "true");

        intent.putExtra("return-data", false);
        intent.setDataAndType(outputFileUri, "image/*");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        startActivityForResult(intent, CAMERA_CROP_REQUEST);
    }else { 
        SetImage();
        saveState();
    }
}

【问题讨论】:

  • 我想没有真正的好方法可以做到这一点,因为我使用的是 MediaStore.ACTION_IMAGE_CAPTURE 而不是自定义相机活动。如果有人有办法将输出文件保存到 EXTRA_OUTPUT 文件夹而不保存到库中,请告诉我。
  • 我们也发现了这种行为,但仅限于某些手机。 (尤其是 myTouch 3G。)其他手机只按预期保存到 EXTRA_OUTPUT 文件。
  • stackoverflow.com/questions/4515032/… 似乎是同样的问题,并表明它也发生在 LG Ally 手机上。
  • 还有更具体的设备可以显示这种行为吗?截至今日?还是模拟器配置?需要测试一下...

标签: android image android-camera-intent


【解决方案1】:

我的应用程序要求我调用意图拍照。照片不能在图库中,而必须在 SD 卡上的特定目录中。

最初我只是使用了 EXTRA_OUTPUT,但我很快发现了以下内容: - 有些设备完全使用它并跳过图库。 - 有些设备完全忽略它,只使用图库。 - 有些设备真的很糟糕,将全尺寸图像保存到画廊,只将缩略图保存到我想要的位置。 (HTC你知道你是谁......)

所以,我不能在完成后盲目地删除图库文件。最后添加的照片可能是也可能不是我要删除的照片。此外,我之后可能必须复制该文件替换我自己的文件。因为我的活动是 2000 行,而且我的公司不希望发布我们所有的代码,所以我只发布了执行此操作所涉及的方法。希望这会有所帮助。

另外,我要声明,这是我的第一个 Android 应用程序。如果有一个我不知道的更好的方法来做到这一点,我不会感到惊讶,但这对我有用!

所以,这是我的解决方案:

首先,在我的应用程序上下文中,我定义一个变量如下:

public ArrayList<String> GalleryList = new ArrayList<String>();

接下来,在我的活动中,我定义了一个方法来获取图库中所有照片的列表:

private void FillPhotoList()
{
   // initialize the list!
   app.GalleryList.clear();
   String[] projection = { MediaStore.Images.ImageColumns.DISPLAY_NAME };
   // intialize the Uri and the Cursor, and the current expected size.
   Cursor c = null; 
   Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
   //
   // Query the Uri to get the data path.  Only if the Uri is valid.
   if (u != null)
   {
      c = managedQuery(u, projection, null, null, null);
   }

   // If we found the cursor and found a record in it (we also have the id).
   if ((c != null) && (c.moveToFirst())) 
   {
      do 
      {
        // Loop each and add to the list.
        app.GalleryList.add(c.getString(0));
      }     
      while (c.moveToNext());
   }
}

这是为我的新图像返回唯一文件名的方法:

private String getTempFileString()
{
   // Only one time will we grab this location.
   final File path = new File(Environment.getExternalStorageDirectory(), 
         getString(getApplicationInfo().labelRes));
   //
   // If this does not exist, we can create it here.
   if (!path.exists())
   {
      path.mkdir();
   }
   //
   return new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg").getPath();
}

我的 Activity 中有三个变量为我存储有关当前文件的信息。字符串(路径)、文件变量和该文件的 URI:

public static String sFilePath = ""; 
public static File CurrentFile = null;
public static Uri CurrentUri = null;

我从不直接设置这些,我只在文件路径上调用一个setter:

public void setsFilePath(String value)
{
   // We just updated this value. Set the property first.
   sFilePath = value;
   //
   // initialize these two
   CurrentFile = null;
   CurrentUri = null;
   //
   // If we have something real, setup the file and the Uri.
   if (!sFilePath.equalsIgnoreCase(""))
   {
      CurrentFile = new File(sFilePath);
      CurrentUri = Uri.fromFile(CurrentFile);
   }
}

现在我调用意图拍照。

public void startCamera()
{
   Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
   // Specify the output. This will be unique.
   setsFilePath(getTempFileString());
   //
   intent.putExtra(MediaStore.EXTRA_OUTPUT, CurrentUri);
   //
   // Keep a list for afterwards
   FillPhotoList();
   //
   // finally start the intent and wait for a result.
   startActivityForResult(intent, IMAGE_CAPTURE);
}

完成后,活动返回,这是我的代码:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
   if (requestCode == IMAGE_CAPTURE)
   {
      // based on the result we either set the preview or show a quick toast splash.
      if (resultCode == RESULT_OK)
      {
         // This is ##### ridiculous.  Some versions of Android save
         // to the MediaStore as well.  Not sure why!  We don't know what
         // name Android will give either, so we get to search for this
         // manually and remove it.  
         String[] projection = { MediaStore.Images.ImageColumns.SIZE,
                                 MediaStore.Images.ImageColumns.DISPLAY_NAME,
                                 MediaStore.Images.ImageColumns.DATA,
                                 BaseColumns._ID,};
         //    
         // intialize the Uri and the Cursor, and the current expected size.
         Cursor c = null; 
         Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
         //
         if (CurrentFile != null)
         {               
            // Query the Uri to get the data path.  Only if the Uri is valid,
            // and we had a valid size to be searching for.
            if ((u != null) && (CurrentFile.length() > 0))
            {
               c = managedQuery(u, projection, null, null, null);
            }
            //   
            // If we found the cursor and found a record in it (we also have the size).
            if ((c != null) && (c.moveToFirst())) 
            {
               do 
               {
                  // Check each area in the gallary we built before.
                  boolean bFound = false;
                  for (String sGallery : app.GalleryList)
                  {
                     if (sGallery.equalsIgnoreCase(c.getString(1)))
                     {
                        bFound = true;
                        break;
                     }
                  }
                  //       
                  // To here we looped the full gallery.
                  if (!bFound)
                  {
                     // This is the NEW image.  If the size is bigger, copy it.
                     // Then delete it!
                     File f = new File(c.getString(2));

                     // Ensure it's there, check size, and delete!
                     if ((f.exists()) && (CurrentFile.length() < c.getLong(0)) && (CurrentFile.delete()))
                     {
                        // Finally we can stop the copy.
                        try
                        {
                           CurrentFile.createNewFile();
                           FileChannel source = null;
                           FileChannel destination = null;
                           try 
                           {
                              source = new FileInputStream(f).getChannel();
                              destination = new FileOutputStream(CurrentFile).getChannel();
                              destination.transferFrom(source, 0, source.size());
                           }
                           finally 
                           {
                              if (source != null) 
                              {
                                 source.close();
                              }
                              if (destination != null) 
                              {
                                 destination.close();
                              }
                           }
                        }
                        catch (IOException e)
                        {
                           // Could not copy the file over.
                           app.CallToast(PhotosActivity.this, getString(R.string.ErrorOccured), 0);
                        }
                     }
                     //       
                     ContentResolver cr = getContentResolver();
                     cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                        BaseColumns._ID + "=" + c.getString(3), null);
                     break;                        
                  }
               } 
               while (c.moveToNext());
            }
         }
      }
   }      
}

【讨论】:

  • 感谢这有助于解决那些愚蠢的缩略图返回设备上的问题。这也是数百万其他 stackoverflow 帖子都在抱怨“2.1 设备上的相机照片方向”的问题。
  • 考虑使用 HashMap,而不是保留画廊项目的 ArrayList。目前,您的代码嵌套循环两次图库中的图像,因此对于 N 图像,您正在运行 n^2 比较。这将导致具有许多图像的设备出现明显的延迟。如果您使用 HashMap,您将使用小写文件名作为键。然后您可以使用 containsKey 检查文件是否存在,将其转换为 O(n) 操作。
  • 嗨!我遵循了您的代码,但我面临着有线行为。我得到图片并将其保存到我的数据库中。在程序的另一点,我显示了我在数据库中的所有图片。但是,方向不对。我还检查了数据库,它也以错误的方向保存。你也有这种情况吗?
  • @Paul 为什么不使用 HashSet 代替?这不像您使用与字符串一起存储的整数
  • 我发现另一个问题会导致您的代码在 LG G2 上失败。我的设备将拍摄的每张图像保存到特定文件夹中。如果您调用意图拍照,拍摄一张,单击“取消”,拍摄另一张,然后单击“开始”,它将保存两张图像。因此,您可能会将分离的图像复制到目标文件中。
【解决方案2】:

这将从图库中删除文件:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) { 

        /* Copy the file to other directory or whatever you want */

        // mContext is the context of the activity
        mContext.getContentResolver().delete(data.getData(), null, null);
    }
 }

关于 EXTRA_OUTPUT 非标准行为。我认为这种伪算法应该适用于所有情况:

1) 不要使用 EXTRA_OUTPUT。图片/照片始终会转到图库位置。

2) 将文件从库位置复制到所需位置。

3) 从图库中删除(使用上面的代码)文件。

但当然它似乎太完美了……在某些设备中(例如带有 android 2.3 的原始 Galaxy Tab),您必须使用 EXTRA_OUTPUT 和 ACTION_IMAGE_CAPTURE,否则意图不起作用。

【讨论】:

  • 文档中没有任何内容表明 intent.getData() 将是图像的 URI。有基于 SO cmets 的轶事证据表明它未在某些手机上设置。
【解决方案3】:

如果有人正在寻找更简单的方法来解决这个问题,这就是我解决问题的方法。

我有一个捕获按钮,当按下它时会发送意图,我添加的是我还去从图像媒体存储中获取最后一个 id 并将其存储:

/**
 * Gets the last image id from the media store
 * @return
 */
private int getLastImageId(){
    final String[] imageColumns = { MediaStore.Images.Media._ID };
    final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
    final String imageWhere = null;
    final String[] imageArguments = null;
    Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, imageWhere, imageArguments, imageOrderBy);
    if(imageCursor.moveToFirst()){
        int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
        imageCursor.close();
        return id;
    }else{
        return 0;
    }
}

然后,当活动返回时,我运行此代码以检查捕获前的最后一个图像 ID,然后在捕获后查询图像的 ID 大于记录的 ID,如果大于则删除位于我为相机指定的保存位置。

/*
 * Checking for duplicate images
 * This is necessary because some camera implementation not only save where you want them to save but also in their default location.
 */
final String[] imageColumns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_TAKEN, MediaStore.Images.Media.SIZE, MediaStore.Images.Media._ID };
final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
final String imageWhere = MediaStore.Images.Media._ID+">?";
final String[] imageArguments = { Integer.toString(MyActivity.this.captureLastId) };
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, imageWhere, imageArguments, imageOrderBy);
if(imageCursor.getCount()>1){
    while(imageCursor.moveToNext()){
        int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
        String path = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
        Long takenTimeStamp = imageCursor.getLong(imageCursor.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN));
        Long size = imageCursor.getLong(imageCursor.getColumnIndex(MediaStore.Images.Media.SIZE));
        if(path.contentEquals(MyActivity.this.capturePath)){
            // Remove it
            ContentResolver cr = getContentResolver();
            cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media._ID + "=?", new String[]{ Long.toString(id) } );
            break;
        }
    }               
}
imageCursor.close();

对我来说,这是一个更简单的解决方案,我在遇到此问题的 HTC 上进行了测试。

另一边说明,我最初使用 *DATE_TAKEN* 而不是 *_ID* 作为参数,但似乎存在一些错误,即在模拟器上,通过 Intent 捕获的某些图像具有毫秒*DATE_TAKEN* 次乘以 1000,所以我切换到 *_ID*,这似乎更强大。

【讨论】:

  • @Xithias 将此伪代码视为您可以实现的方法的要点,不要只是复制代码并期望它工作。
  • @Emil 你的答案不是伪代码。如果我看到正常的代码,我希望它可以工作。如果您知道您的答案不完整或者需要更多代码,请在某处提出建议,并告诉读者他需要做什么才能使其工作。这将使您的回答更加完整和成功。
  • @Xithias 我简单描述了一个解决这个问题的简单方法,代码在那里指导你。我不会花时间警告人们代码可能不起作用或某些方法最终会被弃用,因为我不希望任何有能力的程序员只是复制代码的 sn-ps 并抱怨它不起作用。跨度>
  • @Emil 别担心,我用另一种方式解决了我的问题。但是你必须想到,在这里,在 StackOverflow 中,有称职的程序员,也有初学者。这就是为什么您在此答案中没有更多选票的原因。这类问题是初学者问的,是原生相机APP的常见问题,你的回答只针对“能干的程序员”。
  • @Xithias 我不在乎你的态度。这与初学者无关,如果您只想复制和粘贴代码 - 不要将您的工作与编程混淆。
【解决方案4】:

嗯,我认为整个问题来自这样一个事实,即您期望从另一个没有发生的应用程序中得到某个结果。哪个是(只是为了清楚) -

  • 启动一个可以拍照的 Activity,因为您的应用程序不捕获图像。
  • 告诉其他应用程序您要将图片保存在哪里
  • 在您指定的位置使用保存的图像。
  • 但问题是其他应用程序也将图像保存在不同的位置,这是您不希望的。

现在让我们从另一个应用程序的角度来看它,即捕获图像。让我们考虑两种情况(这是可能的) -

  • 首先,使用文件名或图像保存位置选项启动应用程序。
  • 其次,应用程序启动时没有任何额外信息,例如文件名或图像要保存的位置。(如果直接从菜单启动捕获应用程序,可能会发生这种情况)

现在理想情况下应该发生的是,如果有额外的信息,如文件名或位置,那么他应该使用那个位置,如果没有,那么他可以使用他自己的。但是很遗憾,我们来自一个理想的世界,因为对于启动相机应用程序时应该发生的事情并没有一成不变的规定,所以相机应用程序开发人员会有自己的解释。

由于不同的设备将不同的相机应用程序设置为默认设置(是的,通常会更换库存相机),因此获得的结果/将会有所不同。

因此,在某些相机中,它可能只保存在一个位置,而在其他位置,它也可能保存在 Camera 文件夹中(因为相机应用程序可能总是将捕获的图像保存在相机文件夹中并将其保存在不同的位置是应用程序给予的奖金)

如果您只是将文件名传递给相机应用程序,应用程序应该在拍摄一张照片后返回吗?我想不是。那么在这种情况下应该怎么做呢?这一切都非常模糊或灰色地带。

现在,如果您不希望将其保存在“相机”文件夹中,请查看是否可以获取最近拍摄的图像的文件名,然后从您的应用程序中删除。或者不要告诉相机应用程序需要将其保存在哪里,只需获取文件名并将其移动到您想要的位置即可。

如果您没有获得文件名,那么您将受到其他应用程序开发人员的摆布。 (嘿!这也不是他的错,他只是按照自己的方式设计!)

【讨论】:

    【解决方案5】:

    我认为你不能做你想做的事。很遗憾,但我找不到其他答案。

    如果您使用谷歌相机实现它工作正常。它只是不将照片存储到指定的 EXTRA_OUTPUT 中的画廊。

    但是当您面对其他一些设备时,它们可能会做一些完全不同的事情。那是因为 HTC、LG 和其他一些可能有自定义相机实现,而您对此无能为力。您可以保持原样,也可以编写您自己的相机,让它完全按照您的需要工作。

    其实和这个问题无关,但是有一天你会发现 CROP intent 在某些设备上不起作用(http://groups.google.com/group/android-developers/browse_frm/thread/2dd647523926192c/4b6d087073a39607?tvc=1&pli=1)。所以,如果你需要它,你必须自己写。

    【讨论】:

      【解决方案6】:

      这不是一项容易解决的任务,但可以采用一种棘手的方法。如果有人需要一个简单且有效的解决方案。试试下面的代码:

      1. 在调用相机意图之前以毫秒为单位保存当前时间。
      2. OnActivityResult 查询在step1中拍摄日期大于毫秒的图片uri。并删除文件。就是这样。
      String[] projection = {MediaStore.Images.ImageColumns.SIZE,
                      MediaStore.Images.ImageColumns.DISPLAY_NAME,
                      MediaStore.Images.ImageColumns.DATA,
                      BaseColumns._ID,MediaStore.Images.ImageColumns.DATE_ADDED};
              final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
              final String selection = MediaStore.Images.Media.DATE_TAKEN+" > "+mImageTakenTime;
              //// intialize the Uri and the Cursor, and the current expected size.
              Cursor c = null;
              Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
              c = getActivity().managedQuery(u, projection, selection, null, imageOrderBy);
              if(null != c && c.moveToFirst()){
                  ContentResolver cr = getActivity().getContentResolver();
                  cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                          BaseColumns._ID + "=" + c.getString(3), null);
              }
      

      【讨论】:

        【解决方案7】:

        Look here - 这是一段将图片保存到EXTRA_OUTPUT 文件夹而不将其保存到图库的代码。这样,在我的应用程序中,我曾经直接从相机中抓取照片,然后删除拍摄的照片。

        【讨论】:

        • 您的代码在功能上与提问者的代码和我的项目中的代码相同。它适用于某些手机。它不适用于写入EXTRA_OUTPUT 和其他地方的其他人。
        【解决方案8】:

        这是我使用的代码,它拍摄一张照片并将其保存在指定的位置

        Uri outputFileUri;
        
        public void takePhoto() {
            File directory = new File(Environment.getExternalStorageDirectory()
                    + "/HI-Tech" + "/");
        
            if (!directory.exists()) {
                directory.mkdir();
            }
        
            int count = 0;
            if (directory != null) {
                File[] files = directory.listFiles();
                if (files != null) {
                    count = files.length;
                }
            }
            count++;
            String imagePath = "IMAGE_" + count + ".jpg";
            File file = new File(directory, imagePath);
            outputFileUri = Uri.fromFile(file);
        
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            startActivityForResult(intent, JobActivity.TAKE_PIC);
        }
        

        然后我处理响应。

        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            try {
                if (resultCode == RESULT_OK) {
                    if (requestCode == JobActivity.TAKE_PIC) {
                        Bitmap bitmap = decodeFile(new File(outputFileUri.getPath()), 160, 120);
            } catch (Exception e) {
                Log.e("Error", "Unable to set thumbnail", e);
            }
        }
        

        我不得不将 outputFileUri 声明为全局变量,因为我发现无法获取保存的 onActivityResult 路径。通过传递 outputFileUri,您会注意到图像没有保存在 Camera 文件夹中,而是保存在指定的位置。我已经在我的 Nexus1 和一个便宜的三星设备上尝试过这段代码。

        希望对你有帮助

        【讨论】:

        • 您的代码在功能上与提问者的代码和我的项目中的代码相同。它适用于某些手机。它不适用于写入EXTRA_OUTPUT 和其他地方的其他人。
        【解决方案9】:

        我也在努力解决这个问题。顺便说一句,这个问题在Androidbug tracker中标记为Obsolete。出于某种原因,Android 团队不再认为这是一个错误。也许是因为这与制造商有关。

        似乎所有解决方案(来自此线程和其他博客文章等)都形成以下算法:

        1. 保存最后一张照片的唯一标识符;
        2. 使用Intent 和EXTRA_OUTPUT 启动相机活动;
        3. 拍照并检查图库中最后一张照片的 id 是否已更改,以决定是否应将其删除。

        在接受的答案中提出了类似的建议。

        但我发现这种方法不能用于生产代码。例如,让我们想象一个简单的情况:

        您将最后拍摄的照片的一些 id 存储在图库中并启动相机活动。当用户在某些设备上拍照时,相机活动会显示一个带有Cancel 和OK 按钮(或类似按钮)的对话框。而它们背后的逻辑如下:

        • 如果用户按下Cancel,他将返回相机活动并继续拍照。
        • 如果他/她(用户)按下OK 按钮,相机活动会将结果返回给您的应用程序。

        这里的重要说明:事实证明,在某些设备上(我在 LG 和 HTC 上测试过)图像可以在显示此对话框时保存。

        现在想象一下,如果用户出于某种原因决定点击Home 按钮并启动另一个应用程序(例如,另一个用户可以拍摄不同照片的相机应用程序!)。然后返回到仍然显示该对话框的应用程序并按下OK。显然,在这种情况下,您的应用程序将删除错误的文件......并让用户失望:(

        所以经过大量研究后,我决定解决这个问题的最佳方法是编写自己的相机引擎或只使用一些第三方库,例如:material camera。

        【讨论】:

        • 我认为使用自己的或 lib 相机实现是最好的选择,特别是从 4.​​4 开始,当无法删除/移动其他应用程序创建的文件时。
        【解决方案10】:

        您最好的选择可能是直接处理 Camera 类,然后将回调中返回的 jpeg 或 raw 存储在您想要的位置。

        或者,您可以尝试在添加后通过 _id 从媒体内容提供商删除拍摄的图像。只是通过查询找到它并通过ContentResolver.delete删除它,但不确定实现。

        【讨论】:

          【解决方案11】:

          在为此苦苦挣扎了一段时间后,我硬着头皮编写了自己的相机拍摄活动。我相信这比MediaStore.ACTION_IMAGE_CAPTURE 解决方案更便携、更安全。图像将存储在您存储它的地方,而不是其他地方,您不会有意外删除一些不相关文件的危险。此外,还可以根据要求调整实际的相机功能。

          出于便携性原因,我使用了Camera 类,而不是camera2。

          需要注意的是相机参数都要设置好,尤其是图片尺寸、对焦模式和闪光灯模式,在启动相机的时候都可能处于意外状态。

          将此作为答案发布,而不是作为评论发布,因为在我看来这是正确的答案,导致最少的努力。

          【讨论】:

            【解决方案12】:
            protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
                if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
            
                Bitmap photo = (Bitmap) data.getExtras().get("data");
                Uri tempUri = Utils.getUri(getActivity(), photo);
                File finalFile = new File(getRealPathFromURI(tempUri));
                finalFile.delete();
                }  
            }
            
            
            public String getRealPathFromURI (Uri contentUri) {
                String path = null;
                String[] proj = { MediaStore.MediaColumns.DATA };
                Cursor cursor = getActivity().getContentResolver().query(contentUri, proj, null, null, null);
                if (cursor.moveToFirst()) {
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                    path = cursor.getString(column_index);
                }
                cursor.close();
                return path;
            }
            

            【讨论】:

              【解决方案13】:

              下面的代码不仅删除了图像文件,还删除了删除filw时留下的0Byte文件。我在 Android 10 中观察到了这种 0Byte ghost 文件的行为。

                  val fileToDelete = File(photoUri.path)
                  if (fileToDelete.exists()) {
                      if (fileToDelete.delete()) {
                          if (fileToDelete.exists()) {
                              fileToDelete.canonicalFile.delete()
                              if (fileToDelete.exists()) {
                                  getApplicationContext().deleteFile(fileToDelete.name)
                              }
                          }
                          Log.e("File", "Deleted " + savedPhotoUri?.path)
                      } else {
                          Log.e("File", "not Deleted " + savedPhotoUri?.path)
                      }
                  }
              

              【讨论】:

                猜你喜欢
                • 2011-05-22
                • 2016-06-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多