Начните умывать "тихо"

В ответ на этот вопрос, есть ли способ начать намерение в андроиде, не запрашивая у пользователя ничего?

Прямо сейчас, я получаю изображение следующим образом:

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).