Мое заявление требует, чтобы я позвонил с намерением сделать фотографию.Фотография не может быть в галерее, но вместо этого должна быть в определенном каталоге на 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();
}
В моей Деятельности есть три переменные, которые хранят для меня информацию о текущем файле.Строка (путь), файловая переменная и 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());
}
}
}
}
}