Отображение изображений с SDCard в виджете от MarshMallow

В виджетах я показываю изображения с SDCard с помощью remoteView.setImageViewUri(). Эта стратегия работает правильно, за исключением MarshMallow:

Ошибка:

Unable to open content:  file:///storage/emulated/0/Android/data/applicaitonPackage/files/file.png
open failed: EACCESS (Permission denied)

Понятно, что это проблема разрешений, но я не знаю, как предоставить разрешения для контейнера виджета и теоретически (см. Примечание 1), изображения уже хранятся в общем хранилище.

Примечание 1. Каталог, в котором хранятся изображения, является общим хранилищем в Environment.getExternalStorageDirectory()

Примечание 2: приложение не адаптировано к MarshMallow и использует targetSdkVersion = 15

Примечание 3. Не просто ответьте на вопрос о новых разрешениях времени выполнения в MarshMallow. Я уже знаю изменения прав доступа, и это не проблема, потому что приложение нацелено на SDKVersion 15, и у приложения нет никаких проблем с доступом к внешнему хранилищу, проблема заключается в контейнере виджетов, который является тем, который, как я подозреваю, не имеет разрешения.

Ответы

Ответ 1

hi здесь несколько шагов для разрешения на установку для android M и помните, что вы должны объявить одно и то же разрешение в файле манифеста.

Шаг 1. Объявите глобальную переменную:

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 0;

Шаг 2. Используйте этот код в своем основном действии

private void locationpermission() {
// Here, thisActivity is the current activity
 if (ContextCompat.checkSelfPermission(activity
    ,
    Manifest.permission.ACCESS_COARSE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
        Manifest.permission.ACCESS_COARSE_LOCATION)) {

    // Show an expanation to the user *asynchronously* -- don't block
    // this thread waiting for the user response! After the user
    // sees the explanation, try again to request the permission.

} else {

    // No explanation needed, we can request the permission.

    ActivityCompat.requestPermissions(activity,
            new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
            MY_PERMISSIONS_REQUEST_LOCATION);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant. The callback method gets the
    // result of the request.
}
}
 }

  @Override
  public void onRequestPermissionsResult(int requestCode,
                               String permissions[], int[] grantResults)         {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
    // If request is cancelled, the result arrays are empty.
    if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

        // permission was granted, yay! Do the
        // contacts-related task you need to do.

    } else {

        // permission denied, boo! Disable the
        // functionality that depends on this permission.
    }
    return;
}

// other 'case' lines to check for other
// permissions this app might request
}
}

Шаг 3. Вызовите этот метод в методе oncreate,

locationpermission(); И любое разрешение, на которое вы можете позвонить отсюда, и каждый результат, который вы можете получить в методе переопределения onRequestPermissionsResult, этот.

Thankyou

надеюсь, что это поможет вам (Y).

см. здесь пример

https://www.dropbox.com/s/w29sljy0zpwwm61/MyApplication.zip?dl=0

Ответ 2

@Docs говорит

Запрос разрешений во время выполнения

Начиная с Android 6.0 (уровень API 23), пользователи предоставляют разрешения для приложений во время работы приложения, а не при установке приложения. Этот подход упрощает процесс установки приложения, поскольку пользователю не нужно предоставлять разрешения при установке или обновлении приложения. Он также дает пользователю больше контроля над функциональностью приложения;

Поэтому это имеет смысл, хотя вы объявляете разрешение в манифесте, но все еще получаете отказ в доступе

Я предлагаю вам прочитать, как получить разрешение времени выполнения

http://developer.android.com/training/permissions/requesting.html

Вот пример, предоставленный документами

    if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
    != PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
        Manifest.permission.READ_CONTACTS)) {

    // Show an expanation to the user *asynchronously* -- don't block
    // this thread waiting for the user response! After the user
    // sees the explanation, try again to request the permission.

} else {

    // No explanation needed, we can request the permission.

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE is an
    // app-defined int constant. The callback method gets the
    // result of the request.
}

}

Измените разрешение по требованию

Надеюсь, это приведет вас в правильное направление.

Ответ 3

У вас есть это разрешение в файле манифеста?

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Ответ 4

Если я установил targetSdkVersion в 15 вместо 23 - пользователи андроида M увидят приложение и смогут его загрузить (предоставление всех разрешений во время выполнения)?

Да, приложение будет доступно для пользователей M, и каждое разрешение предоставляется во время установки.

`targetSdkVersion=15` 

который меньше 23.User сможет загрузить приложение и использовать его, он предоставляет все разрешения во время выполнения. Если вы хотите проверить разрешение, перейдите в настройки и предоставите разрешение. Если вы хотите использовать модуль разрешения android M во время выполнения, вы должны установить целевую версию SDK на 23. Если установлено повреждение targetSdkVersion=15 на устройстве Android и более высоких устройствах.

Если вы хотите поддерживать пользователей Android Android, установите targetSdkVersion=23 и обрабатывать время выполнения справки.