我的应用程序要求我调用拍照的意图。照片不能在图库中,而必须在 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;
我从不直接设置这些,我只在文件路径上调用一个设置器:
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());
}
}
}
}
}