android - porque - Visualización de imágenes de la tarjeta SD en un widget de MarshMallow
no me aparecen los widgets android (4)
¿Tuviste esta autorización en tu archivo de Manifiesto?
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
En un widget muestro imágenes de la tarjeta SD usando remoteView.setImageViewUri()
. Esta estrategia funciona correctamente excepto con MarshMallow:
El error es:
Unable to open content: file:///storage/emulated/0/Android/data/applicaitonPackage/files/file.png
open failed: EACCESS (Permission denied)
Está claro que este es un problema de permisos, pero no sé cómo otorgar permisos al contenedor de widgets y, en teoría (ver Nota 1) las imágenes ya están almacenadas en un almacenamiento compartido.
Nota 1 : El directorio donde se almacenan las imágenes es almacenamiento compartido en Environment.getExternalStorageDirectory()
Nota 2 : la aplicación no está adaptada a MarshMallow y utiliza targetSdkVersion = 15
Nota 3 : No solo responda explicando sobre los nuevos permisos de tiempo de ejecución en MarshMallow. Ya sé que los cambios de permisos y ese no es el problema porque la aplicación está dirigida a SDKVersion 15 y la aplicación no tiene ningún problema para acceder al almacenamiento externo, el problema está en el contenedor de widgets que sospecho que no tiene el permisos
@Docs dice
Solicitando permisos en tiempo de ejecución
A partir de Android 6.0 (nivel de API 23), los usuarios otorgan permisos a las aplicaciones mientras la aplicación se está ejecutando, no cuando la instalan. Este enfoque agiliza el proceso de instalación de la aplicación, ya que el usuario no necesita otorgar permisos cuando instala o actualiza la aplicación. También le da al usuario más control sobre la funcionalidad de la aplicación;
Por lo tanto, esto tiene sentido, aunque usted declara el permiso en el manifiesto pero sigue recibiendo el permiso denegado
Le sugiero que lea cómo obtener permiso de tiempo de ejecución
http://developer.android.com/training/permissions/requesting.html
Aquí está el ejemplo proporcionado por Docs
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''s 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.
}
}
Cambie el permiso según su requisito
Espero que te lleve a la dirección correcta
Hola, aquí hay algunos pasos para el permiso de configuración de Android M y recuerde que también debe declarar el mismo permiso en el archivo de manifiesto.
Paso 1. Declarar variable global:
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 0;
Paso 2. Usa este código en tu actividad principal.
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''s 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
}
}
Paso 3. Llama a este método en tu método oncreate,
locationpermission (); Y cualquier persona que tenga permiso puede llamar desde aquí y cada resultado que pueda obtener en el método de anulación onRequestPermissionsResulte este.
gracias
Espero que esto te ayude (Y).
por favor refiérase desde aquí ejemplo
https://www.dropbox.com/s/w29sljy0zpwwm61/MyApplication.zip?dl=0
Si configuro targetSdkVersion
en 15 en lugar de 23, ¿los usuarios de Android M verán la aplicación y podrán descargarla (otorgando todos los permisos en tiempo de ejecución)?
Sí, la aplicación estará disponible para usuarios M y cada permiso se otorga en el momento de la instalación.
`targetSdkVersion=15`
que es menos de 23. El usuario podrá descargar la aplicación y usarla, otorga todos los permisos en tiempo de ejecución. Si desea verificar el permiso, vaya a la configuración y conceda el permiso. Si desea utilizar el módulo de permisos de Android M en el tiempo de ejecución, debe configurar la versión del SDK de destino en 23. Si configura targetSdkVersion=15
en la aplicación de dispositivos Android M y superior, se targetSdkVersion=15
.
Si desea admitir a los usuarios de Android M, establezca
targetSdkVersion=23
y maneje el tiempo de ejecución de permisos.