una studio otra open llamar intent instalar gestor desde como archivos app aplicacion another abrir android android-intent android-fileprovider android-7.0-nougat viewaction

otra - open another app android studio



El apk de instalaciĆ³n de Android con Intent.VIEW_ACTION no funciona con el proveedor de archivos (4)

Debe tener en cuenta que para API <24 debe usar:

setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")

en lugar de configurar datos y escribir por separado:

data = Uri.fromFile(apkFile) type = "application/vnd.android.package-archive"

de lo contrario, obtendrá ActivityNotFoundException

Mi aplicación tiene una función de actualización automática que descarga un APK y cuando finaliza la descarga, Intent.VIEW_ACTION para abrir la aplicación y permitir que el usuario instale el apk descargado

Uri uri = Uri.parse("file://" + destination); Intent install = new Intent(Intent.ACTION_VIEW); install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); install.setDataAndType(uri, manager.getMimeTypeForDownloadedFile(downloadId)); activity.startActivity(install);

Esto funciona muy bien para todos los dispositivos <24

Ahora, con Android 24, aparentemente ya no se nos permite iniciar intentos con el archivo: /// y después de buscar en Google se recomienda utilizar un proveedor de archivos

nuevo código:

Intent install = new Intent(Intent.ACTION_VIEW); install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri apkUri = FileProvider.getUriForFile(AutoUpdate.this, BuildConfig.APPLICATION_ID + ".provider", file); install.setDataAndType(apkUri, manager.getMimeTypeForDownloadedFile(downloadId)); activity.startActivity(install);

Ahora activity.startActivity (instalar); arroja un error

No se encontró actividad para manejar la intención {act = android.intent.action.VIEW dat = content: //com.xxxx.xx.provider/MyFolder/Download/MyApkFile.apk typ = application / vnd.android.package-archive flg = 0x4000000}

¿Hay alguna forma de abrir el visor de APK en Android 7 (24)?


Después de mucho intentarlo, pude resolver esto creando diferentes intenciones para algo más bajo que Nougat, ya que usando FileProvider para crear una intención de instalación con versiones de Android antes de que Nougat produzca el error:

ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSTALL_PACKAGE dat=content://XXX.apk flg=0x1 }

Al usar un Uri normal en Android Nougat crea el siguiente error:

FileUriExposedException: file:///XXX.apk exposed beyond app through Intent.getData()

Mi solución que funciona para mí con Android N en el emulador y un teléfono con Android M.

File toInstall = new File(appDirectory, appName + ".apk"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Uri apkUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", toInstall); Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); intent.setData(apkUri); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); activity.startActivity(intent) } else { Uri apkUri = Uri.fromFile(toInstall); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.startActivity(intent); }

ACTUALIZACIÓN PARA Android Nougat 7.1:

También debe agregar el permiso REQUEST_INSTALL_PACKAGES en su manifiesto. Está disponible desde el nivel 23 de Api (Android 6.0 Marshmallow) y desde el nivel 25 (Android 7.1 Nougat).

ACTUALIZAR:

Recuerde solicitar los permisos de lectura y escritura en el almacenamiento externo si el archivo que intenta instalar está en el almacenamiento externo. Y también para configurar un FileProvider correcto para Android Nougat y superior.

Primero verifique si tiene permiso de escritura llamando a canReadWriteExternal() continuación, si no, llame a requestPermission() antes:

private static final int REQUEST_WRITE_PERMISSION = 786; @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) Toast.makeText(this, "Permission granted", Toast.LENGTH_LONG).show(); } private void requestPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION); } private boolean canReadWriteExternal() { return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED; }

Aquí hay un ejemplo de un proveedor de archivos para la carpeta Descargar en el almacenamiento externo. AndroidManifest.xml :

<application ... > ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider> </application>

recursos / xml / filepaths.xml :

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

Si recibe un error al instalar el .apk diciendo algo como "Hay un problema al analizar el paquete". puede ser que no haya solicitado el permiso de lectura / escritura o que el archivo que intenta instalar no exista o esté dañado.


Este podría ser el problema, tienes

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

en tu ejemplo debería ser

install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

como instalar es el nombre de la intención.


Tuve este problema al llamar a la actividad de inicio. Después de pausar mi actividad actual, de repente volvió y llamó a Resume. como si nada hubiera pasado mi problema fue con este permiso en manifiesto:

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

casi nadie mencionó eso. así que recuerda esto. en sdk> = 24 necesita usar el proveedor porque necesita una intención que comience con el archivo: /// debajo de sdk 24, debe dar uri que comience con el contenido: /// por eso necesitamos un proveedor de archivos para sdk 24 y superior. No creo que necesite escribir ningún código para esto ya que @just_user ha escrito la respuesta correcta.