Spanish Abrir Excel .xls

TheFalcon

Active Member
Licensed User
Longtime User
Buenas como siempre, Espero que estén todos bien.
Recurro a vosotros por que estoy atrancado.
Estoy intentando ABRIR un Excel, el cual creo y muestro en un Table. pero no me va, pensaba que era por que lo abria justo despues de generar le Table, pero me he puesto un boton directamente para abrir el fichero y no hay manera, lo intento de dos modos.
El fichero esta en la ruta /storage/emulated/0/archivo_04-11-2022.xls"

Los dos modos que uso son

[CODE lang="b4x" title="PROVIDER"]
Dim ruta As String ="/storage/emulated/0"
Dim archivo As String ="archivo_04-11-2022.xls"

Dim uri As String
Dim ik As Intent
uri = File.Combine(ruta,"/" & archivo)
Log(uri)
ik.Initialize(ik.ACTION_VIEW, uri)
ik.SetType("application/vnd.ms-excel")
ik.WrapAsIntentChooser("Escoge Programa para Abrir")
StartActivity(ik)

'-------------- 2 MODO --------------------------------


Dim archivo As String ="archivo_04-11-2022.xls"

provider.Initialize

File.Copy(File.DirRootExternal&"/", archivo, provider.SharedFolder, archivo)
'File.Copy(ruta, archivo, provider.SharedFolder, archivo)
Dim in As Intent
provider.SetFileUriAsIntentData(in, archivo)
'Type must be set after calling SetFileUriAsIntentData
in.SetType("application/xls")
StartActivity(in)

[/CODE]

Con el primer método escojo el programa con el que abrir, pero me dice que he de cerrar el EXCEL y guardarlo antes. de hay que pensara que el error era al abrirlo al crear el table.
Pero incluso poniéndolo en un botón directamente y el exel ya existiendo me lo dice


con el 2º me da java.lang.RuntimeException: Object should first be initialized (Intent).

Os pongo el Manifest, resumido los permisos de almacenamiento

[CODE lang="b4x" title="Manifest"]AddManifestText(
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="29"/>
<supports-screens android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>)

SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
'End of default text.



CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)



'**** instalar apk
AddApplicationText(
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="$PACKAGE$.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
)

CreateResource(xml, provider_paths,
<files-path name="name" path="shared" />
)

SetApplicationAttribute(android:requestLegacyExternalStorage, true) ' de sdk 28 para abajo

AddPermission(android.permission.READ_EXTERNAL_STORAGE) ' Allows an application to read from external storage.

'AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)
[/CODE]


gracias por vuestro tiempo
 
en vez de la librería fileprovider , estoy usando un modulo fileprovider

[CODE lang="b4x" title="Modulo"]'v1.00
Sub Class_Globals
Public SharedFolder As String
Public UseFileProvider As Boolean
Private rp As RuntimePermissions
End Sub

Public Sub Initialize
Dim p As Phone
If p.SdkVersion >= 24 Or File.ExternalWritable = False Then
UseFileProvider = True
SharedFolder = File.Combine(File.DirInternal, "shared")
File.MakeDir("", SharedFolder)
Else
UseFileProvider = False
SharedFolder = rp.GetSafeDirDefaultExternal("shared")
End If
Log($"Using FileProvider? ${UseFileProvider}"$)
End Sub

'Returns the file uri.
Public Sub GetFileUri (FileName As String) As Object

If UseFileProvider = False Then
Dim uri As JavaObject
Return uri.InitializeStatic("android.net.Uri").RunMethod("parse", Array("file://" & File.Combine(SharedFolder, FileName)))
Else
Dim f As JavaObject
f.InitializeNewInstance("java.io.File", Array(SharedFolder, FileName))
Dim fp As JavaObject
Dim context As JavaObject
context.InitializeContext
fp.InitializeStatic("android.support.v4.content.FileProvider")
Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
End If
End Sub

'Replaces the intent Data field with the file uri.
'Resets the type field. Make sure to call Intent.SetType after calling this method
Public Sub SetFileUriAsIntentData (Intent As Intent, FileName As String)
Dim jo As JavaObject = Intent
jo.RunMethod("setData", Array(GetFileUri(FileName)))
Intent.Flags = Bit.Or(Intent.Flags, 1) 'FLAG_GRANT_READ_URI_PERMISSION
End Sub[/CODE]

En principio el modo me es indiferente, lo que necesito es poder abrir desde la APP el excel que genero, ya sea en Excel o con cualquier otro programa compatible
 
Si pongo el archivo en la tarjeta SD , si me funciona poniendo la ruta a mano.

B4X:
Dim ruta As String ="/storage/5893-BF29"
    Dim archivo As String ="archivo_04-11-2022.xls"

    Dim uri As String
    Dim ik As Intent
    uri = File.Combine(ruta,"/" & archivo)
    Log(uri)
    ik.Initialize(ik.ACTION_VIEW, uri)
    ik.SetType("application/vnd.ms-excel")
    ik.WrapAsIntentChooser("Escoge Programa para Abrir")
    StartActivity(ik)

Con lo cual puede ser de permisos de File.DirRootExternal.

ese mismo código si la ruta es File.DirRootExternal , al escoger abrir con Excel me dice "No puede abrir el archivo" Intente Guardar el archivo en el dispositivo y a continuación abrirlo."
 
Y si antes de abrir el archivo lo copias a la carpeta xui.defaultfolder y lo abres desde ahí
 
¿Qué librería estás utilizando?
No tampoco, me he asegurado que lo copia bien, haciendo un
B4X:
If File.Exists(xui.DefaultFolder, archivo) = True Then ToastMessageShow("EXISTE",True)

B4X:
    Dim uri As String
    Dim ik As Intent
    
    File.Copy(File.DirRootExternal,archivo,xui.DefaultFolder,archivo)
'    uri = File.Combine(File.DirRootExternal,"/" & archivo)
    uri = xui.DefaultFolder &"/" & archivo
    Log(uri)
    If File.Exists(xui.DefaultFolder, archivo) = True Then ToastMessageShow("EXISTE",True)
    ik.Initialize(ik.ACTION_VIEW, uri)
    ik.SetType("application/vnd.ms-excel")
    ik.WrapAsIntentChooser("Escoge Programa para Abrir")
    StartActivity(ik)
después de copiar para verificar que lo copia, y antes de abrirlo.
 
Hola TheFalcon

Como siempre, creo que la forma más fácil en la que te podemos ayudar, es que subas un pequeño proyecto de ejemplo.

saludos,
 
Hola TheFalcon:

No veo en tu app que pidas ningún permiso para acceder a File.dirdefaultexternal.
Tienes que leer un poco sobre los permisos y las distintas carpetas a las que puedes acceder.

Este hilo te puede aclarar un poco las cosas, lee los enlaces a Runtime Permissions, targetSDKVersion, Save as...

Necesitas realmente acceder a DirDefaultExternal?
En tu programa simplemente sustituyendo las dos apariciones de File.DirDefaultExternal por xui.DefaultFolder ya funciona (bueno, el intent no llega a funcionar del todo, pero aparece lo de existe y me empieza a abrir excel

Por cierto, en tu proyecto estás usando la clase FileProvider, que ya se convirtió en una librería interna. Por tanto, deberías eliminar la clase de tu proyecto y seleccionar en su lugar la librería.

saludos,
 
Gracias José como siempre.
Me es indiferente donde acceda la aplicación la verdad, tanto me da que sea DirRootExternal , como dirdefaultexternal. ya que la aplicación lo que le da al usuario es la posibilidad de abrir el Excel al generarlo.

Eliminare el fileprovider y lo cargare desde la librería.
Mañana miro el enlace que me mandas y lo pruebo y te digo.
Muchas Gracias y Buenas Noches
 
nada, He probado varias cosas.

con xui.DefaultFolder NO me lo crea en la ruta

/data/user/0/com.Fjo.Citius/files/archivo.xls


con File.DirRootExternal SI lo crea, pero no lo abre

/storage/emulated/0/archivo.xls



con File.DirDefaultExternal SI lo crea pero no lo abre.

/storage/emulated/0/Android/data/com.Fjo.Citius/files/archivo.xls


Luego elimine el Modulo de File provider, y use la libreria y con el codigo
B4X:
Dim archivo As String ="archivo.xls"

    provider.Initialize
 
    File.Copy(File.DirRootExternal, archivo, provider.SharedFolder, archivo)
    Log(provider.SharedFolder)
    Dim in As Intent
 
    provider.SetFileUriAsIntentData(in, archivo)
    'Type must be set after calling SetFileUriAsIntentData
in.SetType("application/xls")
    StartActivity(in)

Tanto si uso DirRoot o dir default, no me lo abre.

No se que permiso me falta he leido los Hilos y los tengo todo, a lo mejor lo que no tengo bien es

B4X:
Sub CanWriteToSystemSettings As Boolean
    Dim p As Phone
    If p.SdkVersion >= 23 Then
        Dim ctxt As JavaObject
        ctxt.InitializeContext
        Dim settings As JavaObject
        settings.InitializeStatic("android.provider.Settings.System")
        Return settings.RunMethod("canWrite", Array(ctxt))
    End If
    Return True
End Sub

O

B4X:
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result Then
        Dim dir As String = File.DirRootExternal
   
        If CanWriteToSystemSettings = True Then
            Dim in As Intent
            in.Initialize("android.settings.action.MANAGE_WRITE_SETTINGS", "package:" & Application.PackageName)
            StartActivity(in)
            Wait For Activity_Resume
            If CanWriteToSystemSettings = False Then
                Log("no permission...")
                Return
            End If
        End If
       
    End If
 
Hola:

prueba este proyecto

Code:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private fp As FileProvider
    Dim archivo As String
End Sub

Public Sub Initialize
    B4XPages.GetManager.LogEvents = True
    fp.Initialize
    archivo = "archivo.xls"
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    If File.Exists(fp.SharedFolder,archivo) = False Then
        File.Copy(File.DirAssets,archivo,fp.SharedFolder,archivo)
    End If
    Log("shared: " & fp.SharedFolder)
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.

Private Sub Button1_Click
    Dim uri As String
    Dim i As Intent

    uri = fp.GetFileUri(archivo)
    Log(uri)
    i.Initialize(i.ACTION_VIEW, "")
    fp.SetFileUriAsIntentData(i, archivo)
    'Type must be set after calling SetFileUriAsIntentData
    i.SetType("application/vnd.ms-excel")
    i.WrapAsIntentChooser ("Escoge Programa para Abrir")
    StartActivity(i)
End Sub

Tras varias pruebas, ha sido este hilo el que me ha dado la solución
 

Attachments

Last edited:
Back
Top