使用内置摄像头时,最终解决方法对复制照片画廊Android的错误 [英] Definitive Fix for Android's bug of duplicating photo on gallery when using the internal camera

查看:142
本文介绍了使用内置摄像头时,最终解决方法对复制照片画廊Android的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是复制照片的Andr​​oid的问题最终解决。测试了2.3(有错误),4.x版(这可是没有错误)和5.x(其中有错误太)。

This is definitive fix for the Android's problem of duplicating a photo. Tested it on 2.3 (which has the bug), 4.x (which doesnt have the bug) and 5.x (which has the bug too).

的问题是,在照片保存在两种格式:通常一个是timestamp.jpg,另一种是full_date_and_time.jpg;有时在同一个文件夹中,有时在不同的文件夹。例如,1430910805600.jpg和2015年5月6日11.14.00.jpg。 Worstly,人们不能转换到另

The problem is that the photo is saved in two formats: usually one is the timestamp.jpg, and the other one is the full_date_and_time.jpg; sometimes in the same folder, sometimes in different folders. For example, "1430910805600.jpg" and "2015-05-06 11.14.00.jpg". Worstly, one cannot be converted to the other.

推荐答案

的固定采用code,我发现在一些问题在这里StackOverflow的,也是我自己的一种改进。

The fix uses code that i found in some questions here in StackOverflow, and also an improvement of my own.

首先,你得到的URI的图像用于创建的意图,获取其添加的日期,并将其删除。然后,你添加到库中的最后一个图像,并与原图像的上架日期进行比较。予删除,如果差小于一秒钟(其通常小于10ms)。

First, you get the image with the URI you used to create the intent, get its added date, and delete it. Then, you get the last image added to the gallery, and compare with the added date of the original image. I delete it if difference is less than one second (its usually less than 10ms).

这是用来拍照的code:

This is the code used to take the photo:

private static final int EXTCAMERA_RETURN = 1234324334;
private String imageFN; // stored globally but could be a parameter
...
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "tctemp.jpg");
values.put (MediaStore.Images.Media.IS_PRIVATE, 1);
capturedImageURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
intent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageURI);  
startActivityForResult(intent, EXTCAMERA_RETURN);

这是一个抢拍摄的照片:

And this is the one to grab the taken photo:

 String[] projection = {MediaStore.Images.Media.DATA, BaseColumns._ID, MediaStore.Images.Media.DATE_ADDED}; 
 Cursor cursor = managedQuery(capturedImageURI, projection, null, null, null); 

 cursor.moveToFirst();
 String capturedImageFilePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
 long date = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));
 if (capturedImageFilePath == null || !AndroidUtils.copyFile(capturedImageFilePath,imageFN,cameraType == CAMERA_NATIVE_NOCOPY))
    resultCode = RESULT_OK+1; // error
 else
 {
    autoRotatePhoto(imageFN);
    getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, BaseColumns._ID + "=" + cursor.getString(cursor.getColumnIndexOrThrow(BaseColumns._ID)), null);
    try {new File(capturedImageFilePath).delete();} catch (Exception e) {} // on android 2.3 the code above does not work, so we just ensure that we delete the file
    removeLastImageFromGallery(date);
 }

这code是用来清除画廊的最后一张照片如果差值小于一秒

This code is used to remove the last photo of the gallery IF the difference is less than one second

 private void removeLastImageFromGallery(long orig)
 {
    try
    {
       final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATE_ADDED };
       final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
       Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
       if (imageCursor.moveToFirst())
       {
          long last = imageCursor.getLong(imageCursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));
          int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
          long dif = Math.abs(orig-last);
          if (dif < 1000) // 1 second - usually is less than 10ms
             getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media._ID + "=?", new String[]{ Long.toString(id) } );
       }
    }
    catch (Exception e)
    {
       AndroidUtils.handleException(e, false);
    }
}

最后,自动旋转code是:

Finally, the autorotate code is:

public static void autoRotatePhoto(String imagePath)
{
   try
   {
      File f = new File(imagePath);
      ExifInterface exif = new ExifInterface(f.getPath());
      int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
      AndroidUtils.debug(imagePath+" -> "+orientation);

      int angle = 0;
      switch (orientation)
      {
         case ExifInterface.ORIENTATION_ROTATE_90: angle  = 90;  break;
         case ExifInterface.ORIENTATION_ROTATE_180: angle = 180; break;
         case ExifInterface.ORIENTATION_ROTATE_270: angle = 270; break;
         default: return;
      }

      Matrix mat = new Matrix();
      mat.postRotate(angle);
      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inSampleSize = 2;

      Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
      Bitmap bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
      FileOutputStream out = new FileOutputStream(f);
      bitmap.compress(Bitmap.CompressFormat.JPEG, 85, out);
      out.close();
      AndroidUtils.debug("auto-rotated "+imagePath);
   }
   catch (Exception e)
   {
      AndroidUtils.handleException(e, false);
   }
}

在AndroidUtils.debug和handleException用于转储日志并打印异常。该的CopyFile如下所示:

The AndroidUtils.debug and handleException are used to dump the Log and print the exception. The copyFile is shown here:

public static boolean copyFile(String in, String out, boolean deleteOriginal)
{
   try
   {
      byte[] buf = new byte[4096];
      FileInputStream fin = new FileInputStream(in);
      FileOutputStream fout = new FileOutputStream(out);
      int r;
      while ((r=fin.read(buf,0,buf.length)) > 0)
         fout.write(buf,0,r);
      fin.close();
      fout.close();
      if (deleteOriginal)
         new File(in).delete();
      return true;
   }
   catch (Exception e)
   {
      handleException(e,false);
      return false;
   }
}

这篇关于使用内置摄像头时,最终解决方法对复制照片画廊Android的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆