java android android-intent directory

java - FileUriExposedException en Android



android-intent directory (3)

¿Es posible usar la aplicación Mis archivos de forma predeterminada para abrir cierta carpeta?

Sí y no. No está 100% garantizado de que funcione en todos los dispositivos.

Editar 1:

Seguir es una de las formas en que se puede hacer. He probado en algunos emuladores (ejecutando Android N y Android O) y carga el explorador de archivos predeterminado:

MainActivity.java

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(Intent.ACTION_VIEW); Uri dirUri = FileProvider.getUriForFile(this,getApplicationContext().getPackageName() + ".com.example.myapplication",Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //intent.setDataAndtType(); I will change this value in the alternatives below }

AndroidManifest.xml

<provider android:name=".GenericFileProvider" android:authorities="${applicationId}.com.example.myapplication" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>

GenericFileProvider.java

public class GenericFileProvider extends FileProvider { }

file_paths.xml

<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="."/> </paths>

El enfoque anterior no funciona en grandes jugadores como Samsung

Alternativas

1. Usando el tipo DocumentsContract.Document.MIME_TYPE_DIR

intent.setDataAndType(dirUri,DocumentsContract.Document.MIME_TYPE_DIR);

Este enfoque funciona en varios emuladores y un conjunto limitado de dispositivos. No funciona con grandes jugadores como Samsung o Huawei.

2. Usando type resource/folder

intent.setDataAndType(dirUri,"resource/folder");

Este enfoque solo funciona si el usuario ha instalado la aplicación ES File Explorer.

Si elige usar, entonces debe verificar si hay alguna intención disponible para manejarlo usando:

PackageManager packageManager = getActivity (). GetPackageManager ();

if (intent.resolveActivity(packageManager) != null) { startActivity(intent); } else { // either display error or take necessary action }

3. Usando el tipo */*

intent.setDataAndType(dirUri,"*/*");

Este enfoque funciona si el usuario elige la aplicación Administrador de archivos del Selector de intención y la marca como aplicación predeterminada para manejar */* . Sin embargo, tiene algunos inconvenientes (Gracias a @CommonsWare por sacar algunos de ellos):

  • Este tipo cargará todas las aplicaciones en el dispositivo y permitirá al usuario elegir una de ellas para completar la acción.
  • Si no hay un explorador de archivos y el usuario elige otras aplicaciones para cargar su intención, la otra aplicación se bloqueará o simplemente mostrará la pantalla en negro. Por ejemplo, utiliza Gallery u otra aplicación para iniciarlo en lugar del explorador de archivos, luego la aplicación Gallery se bloqueará o mostrará una pantalla en negro.
  • Incluso si hay un explorador de archivos pero el usuario decide usar otras aplicaciones, las otras aplicaciones podrían fallar

4. Usando tipo text/csv

intent.setDataAndType(uri, "text/csv")

Esto limitará el número de aplicaciones que se mostrarán al usuario pero las mismas limitaciones cuando se aplica */* utilizado. Se mostrarán las aplicaciones que pueden manejar csv y si el usuario lo elige, las aplicaciones se bloquearían.

Hay algunas implementaciones específicas del dispositivo disponibles here como lo menciona @Academy of Programmer, que requieren identificar la intención del administrador de archivos predeterminado y la necesidad adicional de este.

Conclusión:

No hay un tipo estándar disponible para lograrlo, ya que no existe un estándar seguido por los administradores de archivos para admitir un tipo específico en este momento. En el futuro puede que Google presente algún enfoque. La mejor alternativa sería implementar su propio administrador de archivos al igual que Dropbox o Google Drive. Hay varias bibliotecas disponibles que proporcionan esta función.

Necesito abrir la carpeta en el almacenamiento interno que contiene imágenes.

Yo uso el siguiente código.

Java

File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyPhotos"); Intent intent = new Intent(Intent.ACTION_VIEW); String path =folder.getPath(); Uri myImagesdir = Uri.parse("file://" + path ); intent.setDataAndType(myImagesdir,"*/*"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent);

CAMINOS

<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="images" path="Pictures" /> <external-path name="external_files" path="."/> <external-path name="files_root" path="Android/data/${applicationId}"/> </paths>

Manifiesto

<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.android.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>

xml / file_paths

<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="images" path="Pictures" /> <external-path name="external_files" path="."/> <external-path name="files_root" path="Android/data/${applicationId}"/> </paths>

ERROR

EXCEPCIÓN FATAL: Proceso principal: android.apps.bnb.company.myphotos, PID: 22482 android.os.FileUriExposedException: archivo: /// storage / emulated / 0 / Pictures / MyPhotos expuesto más allá de la aplicación a través de Intent.getData ()

¿Hay alguna otra forma de abrir la carpeta en el almacenamiento interno? ¡Gracias!

ACTUALIZACIÓN # 1

Usando este artículo https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en reemplacé

Uri myImagesdir = Uri.parse("file://" + path );

con

Uri myImagesdir = Uri.parse("content://" + path );

Y el error desapareció.

De todos modos, tengo que elegir siempre la aplicación para abrir esta carpeta.

¿Es posible usar la aplicación Mis archivos de forma predeterminada para abrir cierta carpeta?


Encontré la solución aquí, here here

Este código funciona perfectamente en mi Samsung J7 para abrir la carpeta Imágenes (y otras) desde la memoria interna usando la aplicación predeterminada de Samsung Mis archivos .

File path = new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES); Uri uri = Uri.fromFile(path); Intent intent = getPackageManager().getLaunchIntentForPackage("com.sec.android.app.myfiles"); intent.setAction("samsung.myfiles.intent.action.LAUNCH_MY_FILES"); intent.putExtra("samsung.myfiles.intent.extra.START_PATH", path.getAbsolutePath()); startActivity(intent);

Parece que tenemos que descompilar el Administrador de archivos de cada fabricante para ver cómo llamarlo correctamente. :( Y es demasiado trabajo. Bueno ... asumí que hay una solución genérica para hacerlo.


Utilizo el siguiente código para abrir una imagen desde Almacenamiento:

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); File path = new File(Environment.getExternalStorageDirectory() + "/" + "ParentDirectory" + "/" + "ChildDirectory"); File filepath = new File(path + "/" + yourImageName.png); Uri uri = Uri.fromFile(filepath); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri, "image/jpeg"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);

Respuesta editada:

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); File path = new File(Environment.getExternalStorageDirectory() + "/" + "ParentDirectory" + "/" + "ChildDirectory"); Uri uri = Uri.fromFile(path); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri, "image/jpeg"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);