Spanish [B4A] [Información] Runtime Permissions (Android 6+ , android:targetSdkVersion 23+)

rscheel

Well-Known Member
Licensed User
Desde hace poco me he estado enfrentando a un problema de permisos que afecta al colocar el android:targetSdkVersion sobre SDK 23+, estuve leyendo el tutorial de @Erel sobre los Runtime Permissions aunque no logre entender al 100%, así que realice una consulta sobre este tema en el foro en ingles, lo cual me ayudaron a entender como funcionaban los permisos en android 6 hacia arriba.

Bueno sin mas vueltas les comparto un pequeño código que da permisos para acceder al almacenamiento externo de nuestro teléfono, este ejemplo carga una imagen que esta almacenada en la carpeta Download, que se encuentra en la memoria externa de todos los android.

* Usar la librería RuntimePermissions

Captura.PNG


Primero que nada en Manifest Editor establecer android:targetSdkVersion="23" como muestra el código de ejemplo

B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.
Ahora en nuestro Activity Main nuestro código quedaría de la siguiente manera.

B4X:
Sub Process_Globals
    Dim rp As RuntimePermissions
    Dim sdcardEnabled As Boolean
End Sub

Sub Globals
    Private ImageView1 As ImageView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Activity.LoadLayout("Layout1")
    sdcardEnabled = False
End Sub

Sub Activity_Resume
    If sdcardEnabled = False Then
        rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Activity_PermissionResult (Permission As String, Result As Boolean)
  If Permission = rp.PERMISSION_WRITE_EXTERNAL_STORAGE Then
        If Result Then
            sdcardEnabled = True 'Gracias a bgsoft por corregir esta linea.
            Log("You NOW can write to File.DirRootExternal")
            'File.WriteString(File.DirRootExternal, "String.txt", _
            '"This is some string" & CRLF & "and this is another one.")
            MuestraImagen
        End If
  End If
End Sub

Sub MuestraImagen
    ImageView1.Initialize("ImageView1")
    ImageView1.Bitmap = LoadBitmap(File.DirRootExternal & "/Download", "alexandra.gif" )
    ImageView1.Gravity = Gravity.FILL
    Activity.AddView(ImageView1,10dip, 10dip, 100%x, 100%y)
End Sub
Este código lo pueden mejorar y probar diferentes permisos, en este caso solo se prueba el permiso para poder acceder al almacenamiento externo.

Si tienen dudas de como funciona dejen sus preguntas, estaré encantado de poder ayudarlos.
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Hola Rscheel:

En la parte que el resultado es positivo, tendrias que poner la variable sdcardEnabled a True

B4X:
If Result Then
     sdcardEnabled = False  ' ESTE VALOR TIENE QUE SER TRUE
      Log("You NOW can write to File.DirRootExternal")
      'File.WriteString(File.DirRootExternal, "String.txt", _
       '"This is some string" & CRLF & "and this is another one.")
        MuestraImagen
End If
Como tu has dicho esto lo sacaste del tutorial de Erel, pero hay cosas en ese código que se pueden mejorar:

Al poner esto:
B4X:
Sub Activity_Resume
If sdcardEnabled = False Then 
  rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
EndIf
End Sub
Cada vez que entres en la aplicación consultaras el estado, a menos que guardes en un archivo ese estado para no volver a consultarlo en caso afirmativo. Solo es útil esa variable si no te conceden el permiso y entonces en otra parte del código vas a acceder a leer o escribir para no permitirlo, ya que si no daria un error el programa.
Si no se quiere guardar ese estado en un fichero, se puede hacer esto:

B4X:
If rp.Check(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) = false Then rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
Android se encarga de almacenar los permisos, asi que tanto si lo aceptan como si no podras saber su estado.
Por otro lado esa consulta se puede hacer desde un modulo (no la llamada al permiso), asi que no hay necesidad de tener una variable para saber el estado real actual.

Saludos


Saludos
 

rscheel

Well-Known Member
Licensed User
Hola Rscheel:

En la parte que el resultado es positivo, tendrias que poner la variable sdcardEnabled a True

B4X:
If Result Then
     sdcardEnabled = False  ' ESTE VALOR TIENE QUE SER TRUE
      Log("You NOW can write to File.DirRootExternal")
      'File.WriteString(File.DirRootExternal, "String.txt", _
       '"This is some string" & CRLF & "and this is another one.")
        MuestraImagen
End If
Como tu has dicho esto lo sacaste del tutorial de Erel, pero hay cosas en ese código que se pueden mejorar:

Al poner esto:
B4X:
Sub Activity_Resume
If sdcardEnabled = False Then
  rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
EndIf
End Sub
Cada vez que entres en la aplicación consultaras el estado, a menos que guardes en un archivo ese estado para no volver a consultarlo en caso afirmativo. Solo es útil esa variable si no te conceden el permiso y entonces en otra parte del código vas a acceder a leer o escribir para no permitirlo, ya que si no daria un error el programa.
Si no se quiere guardar ese estado en un fichero, se puede hacer esto:

B4X:
If rp.Check(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) = false Then rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
Android se encarga de almacenar los permisos, asi que tanto si lo aceptan como si no podras saber su estado.
Por otro lado esa consulta se puede hacer desde un modulo (no la llamada al permiso), asi que no hay necesidad de tener una variable para saber el estado real actual.

Saludos


Saludos
Gracias por complementar el tema, es muy importante hacer este tipo de correcciones y acotaciones para que el día de maña cuando visiten esta información no contenga errores.

Saludos.
 

bgsoft

Well-Known Member
Licensed User
Gracias por complementar el tema, es muy importante hacer este tipo de correcciones y acotaciones para que el día de maña cuando visiten esta información no contenga errores.

Saludos.


Te has equivocado al corregir :D (era facil, las dos lineas se parecen)

has cambiado esta linea:
B4X:
If sdcardEnabled = True Then 'Gracias a bgsoft por corregir esta linea.
Y estaba bien, tiene que ser a false, la que te dije que cambiara es la de mas abajo:

B4X:
If Result Then
 sdcardEnabled = False ' ESTE VALOR TIENE QUE SER TRUE
De ahí a decir que esa variable, al llevar el SO el control de permisos la puedes suplir por:
B4X:
If rp.Check(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) = false  Then rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)

Saludos
 

rscheel

Well-Known Member
Licensed User
Te has equivocado al corregir :D (era facil, las dos lineas se parecen)

has cambiado esta linea:
B4X:
If sdcardEnabled = True Then 'Gracias a bgsoft por corregir esta linea.
Y estaba bien, tiene que ser a false, la que te dije que cambiara es la de mas abajo:

B4X:
If Result Then
sdcardEnabled = False ' ESTE VALOR TIENE QUE SER TRUE
De ahí a decir que esa variable, al llevar el SO el control de permisos la puedes suplir por:
B4X:
If rp.Check(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) = false  Then rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)

Saludos
Gracias por corregir, me confundí como el editor acá muestra todo del mismo color es fácil confundirse.
 
Top