Начните умывать "тихо"
В ответ на этот вопрос, есть ли способ начать намерение в андроиде, не запрашивая у пользователя ничего?
Прямо сейчас, я получаю изображение следующим образом:
public void changeImage(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, getResources().getString(R.string.select_picture)),
PICK_IMAGE);
}
Затем я сохраняю Uri и при необходимости просматриваю изображение (я на самом деле сначала изменяю его размер, но это не имеет значения):
Uri _uri = Uri.parse(_path);
InputStream imageStream = null;
try {
imageStream = getContentResolver().openInputStream(_uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap b = BitmapFactory.decodeStream(imageStream);
iv.setImageBitmap(b);
Я хотел бы получить данные изображения, учитывая его Uri, "молча", ссылаясь на намерение, чтобы получить соответствующее разрешение. Поэтому мне нужно что-то вроде:
Edit:
Я попробовал метод setPackage()
. Этот код имеет следующее поведение:
-
Если используется намерение ACTION_VIEW, открывается галерея и показывает конкретное изображение.
-
Если используется намерение ACTION_GET_CONTENT, мне будет предложено выбрать изображение из галереи, даже если я поставлю конкретный Uri.
<Р →
Uri _uri = Uri.parse(_path);
InputStream imageStream = null;
Bitmap b = null;
try {
imageStream = getContentResolver().openInputStream(_uri);
b = BitmapFactory.decodeStream(imageStream);
ImageView iv = (ImageView) findViewById(R.id.playerImage);
iv.setImageBitmap(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
Intent dummyIntent = new Intent(Intent.ACTION_GET_CONTENT);
//Intent dummyIntent = new Intent(Intent.ACTION_VIEW);
dummyIntent.setDataAndType(_uri,"image/*");
dummyIntent.setPackage("com.google.android.gallery3d");
startActivityForResult(dummyIntent, PICK_IMAGE);
}
Любые идеи?
Ответы
Ответ 1
У вас есть разные типы намерений, тихие - это трансляции и услуги. И молчанием я подразумеваю, что по умолчанию ничего не происходит для пользователя (никаких действий не запускается).
Намерение просто спросит систему: есть ли что-то способное справиться с этим?
Если есть, он передаст его этому (или в случае нескольких вариантов спросит у пользователя). И после этого у вас нет контроля, если только это не ваш код.
Ваша проблема связана с Picasa.
Когда пользователь выбирает изображение из Picasa, вы получаете Uri. Вы можете использовать этот Uri с ContentResolver, чтобы получить изображение.
Что на самом деле происходит, когда вы делаете, так это то, что ContentProvider из Picasa обрабатывает Uri и возвращает вам InputStream для изображения.
Из другого вопроса я понял, что вы не сразу получаете изображение, вместо этого вы сохраняете Uri в базе данных, а затем обрабатываете его.
Поскольку Picasa использует механизм разрешений для предоставления вам изображения, и поскольку это разрешение истекло, когда вы пытаетесь использовать Uri, вы хотите снова получить Uri (вместе с разрешением) из Picasa, не спрашивая пользователя снова.
Проблема заключается в том, что Picasa контролирует это разрешение, и поэтому, если Picasa не предоставляет вам намерения получить разрешение, зная, что Uri ничего не может сделать.
Это даже не ошибка, на мой взгляд: у вас есть разрешение на доступ к изображению, когда пользователь это решит, вы автоматически не получаете разрешение на доступ к каждому изображению из Picasa. Служба, которая "молча" предоставляет вам разрешение на доступ к каждому изображению Picasa, зная, что его Uri просто позволит вам получить любое изображение от пользователя, не зная его. Вероятно, это не то, что хотят разработчики Picasa.
Лучшее предложение, которое я могу вам дать, - это то же самое, что вы получили в другом вопросе: когда пользователь выбрал изображение, немедленно его получите и сохраните локально, а затем используйте локальный Uri для доступа к изображению.
Ответ 2
Вместо попытки отправить "молчаливое" намерение возможным решением может быть сохранение URI файла с помощью "" Общие настройки". - вы можете сохранить пользователя и URI в качестве пары ключ/значение (например).
Если вы хотите открыть файл позже, его можно будет открыть без отправки намерения.
Ответ 3
Вы можете получить "реальный" uri (тот, который не изменится) следующим образом:
Это делается для аудиофайла, поэтому используйте "MediaStore.Images.Media.EXTERNAL_CONTENT_URI" и измените другие данные в соответствии с вашим случаем.
Pre kit-kat:
String songName = "";
Cursor cursor = getContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Audio.Media.TITLE}, MediaStore.MediaColumns.DATA + " =?", new String[]{uri.toString()}, null);
if (cursor != null && cursor.moveToNext()) {
songName = cursor.getString(0);
}
if (cursor != null) {
cursor.close();
}
return songName;
После Kitkat происходит изменение из-за поставщика документов, этот код должен сделать трюк:
Cursor cursor = null;
String songName = "";
try {
String[] column = new String[]{MediaStore.Audio.Media.TITLE};
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
// where id is equal to
String sel = MediaStore.Images.Media._ID + " =?";
cursor = getContext().getContentResolver().
query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{id}, null);
if (cursor != null && cursor.moveToNext()) {
songName = cursor.getString(0);
}
}
catch (Exception e){
Logger.log(e);
}
finally {
if (cursor != null) {
cursor.close();
}
}
return songName;
Снова измените детали в соответствии с вашим случаем и сохраните реальный uri, взятый из курсора, который вы получаете (вероятно, получите это поле в своих прогнозах: MediaStore.Images.Media.DATA).