Instalar la aplicación programáticamente en Android

Me interesa saber si es posible instalar mediante progtwigción una aplicación apk descargada dinámicamente de una aplicación personalizada de Android.

Puede iniciar fácilmente un enlace de mercado o un indicador de instalación:

Intent promptInstall = new Intent(Intent.ACTION_VIEW) .setDataAndType(Uri.parse("file:///path/to/your.apk"), "application/vnd.android.package-archive"); startActivity(promptInstall); 

fuente

 Intent goToMarket = new Intent(Intent.ACTION_VIEW) .setData(Uri.parse("market://details?id=com.package.name")); startActivity(goToMarket); 

fuente

Sin embargo, no puede instalar .apks sin el permiso explícito del usuario; no, a menos que el dispositivo y su progtwig estén rooteados.

 File file = new File(dir, "App.apk"); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(intent); 

Tuve el mismo problema y después de varios bashs, funcionó para mí de esta manera. No sé por qué, pero configurar datos y escribirlos por separado arruinó mi intención.

Bueno, investigué más profundamente y encontré fonts de la aplicación PackageInstaller de Android Source.

https://github.com/android/platform_packages_apps_packageinstaller

De manifiesto encontré que requiere permiso:

   

Y el proceso real de instalación ocurre después de la confirmación

 Intent newIntent = new Intent(); newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mPkgInfo.applicationInfo); newIntent.setData(mPackageURI); newIntent.setClass(this, InstallAppProgress.class); String installerPackageName = getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME); if (installerPackageName != null) { newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName); } startActivity(newIntent); 

Las soluciones proporcionadas a esta pregunta son todas aplicables a targetSdkVersion s de 23 y siguientes. Para Android N, es decir, nivel API 24 y superior, sin embargo, no funcionan y se bloquean con la siguiente excepción:

 android.os.FileUriExposedException: file:///storage/emulated/0/... exposed beyond app through Intent.getData() 

Esto se debe al hecho de que a partir de Android 24, el Uri para abordar el archivo descargado ha cambiado. Por ejemplo, un archivo de instalación llamado appName.apk almacenado en el sistema de archivos externo primario de la aplicación con el nombre del paquete com.example.test sería como

file:///storage/emulated/0/Android/data/com.example.test/files/appName.apk

para API 23 y abajo, mientras que algo como

 content://com.example.test.authorityStr/pathName/Android/data/com.example.test/files/appName.apk 

para API 24 y superior.

Se pueden encontrar más detalles sobre esto aquí y no voy a revisarlo.

Para responder a la pregunta sobre targetSdkVersion de 24 y superior, debe seguir estos pasos: Agregue lo siguiente a AndroidManifest.xml:

      

2. Agregue el siguiente archivo paths.xml a la carpeta xml en res en src, main:

 < ?xml version="1.0" encoding="utf-8"?>    

pathName es el que se muestra en el ejemplo de ejemplo de uri de ejemplo anterior y pathValue es la ruta real en el sistema. Sería una buena idea poner un “.” (sin comillas) para pathValue en el cuadro anterior si no desea agregar ningún subdirectorio adicional.

  1. Escriba el siguiente código para instalar el apk con el nombre appName.apk en el sistema de archivos externo principal:

     File directory = context.getExternalFilesDir(null); File file = new File(directory, fileName); Uri fileUri = Uri.fromFile(file); if (Build.VERSION.SDK_INT >= 24) { fileUri = FileProvider.getUriForFile(context, context.getPackageName(), file); } Intent intent = new Intent(Intent.ACTION_VIEW, fileUri); intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true); intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); context.startActivity(intent); activity.finish(); 

No se requiere permiso al escribir en el directorio privado de su propia aplicación en el sistema de archivos externo.

He escrito una biblioteca de AutoUpdate aquí en la que he usado lo anterior.

Solo quiero compartir el hecho de que mi archivo apk se guardó en el directorio de “Datos” de mi aplicación y que necesitaba cambiar los permisos en el archivo apk para que sea legible a nivel mundial para permitir que se instale de esa manera; de lo contrario, el sistema lanzaba “Error de análisis: hay un problema al analizar el paquete”; entonces usando la solución de @Horaceman eso hace:

 File file = new File(dir, "App.apk"); file.setReadable(true, false); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(intent); 

Sigue estos pasos:

1 – Agregue lo siguiente a AndroidManifest.xml :

    

2 – Agregue el siguiente archivo paths.xml a la carpeta xml (si no existe, créelo) en res en src, main

 < ?xml version="1.0" encoding="utf-8"?>    

PathName es el que se muestra en el ejemplo de ejemplo de uri de ejemplo anterior y pathValue es la ruta real en el sistema. Sería una buena idea poner un “.” para pathValue en lo anterior si no desea agregar ningún subdirectorio adicional.

3 – Escribe el siguiente código para ejecutar tus archivos apk:

 File file = "path of yor apk file"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Uri fileUri = FileProvider.getUriForFile(getBaseContext(), getApplicationContext().getPackageName() + ".provider", file); Intent intent = new Intent(Intent.ACTION_VIEW, fileUri); intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true); intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); } else { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } 

Y gracias a Ali Nemati Hayati por ser la primera en escribir el perfil de la solución ali-nemati-hayati

Si es posible. Pero para eso necesita que el teléfono instale fonts no verificadas. Por ejemplo, slideMe hace eso. Creo que lo mejor que puedes hacer es comprobar si la aplicación está presente y enviar un bash para Android Market. deberías usar algo el esquema de url para Android Market.

 market://details?id=package.name 

No sé exactamente cómo comenzar la actividad, pero si comienzas una actividad con ese tipo de url. Debería abrir el mercado de Android y darle la opción de instalar las aplicaciones.

Vale la pena señalar que si utiliza el DownloadManager para iniciar la descarga, asegúrese de guardarlo en una ubicación externa, por ejemplo, setDestinationInExternalFilesDir(c, null, ").apk"; . Al bash con un tipo de paquete-archivo no parece gustarle el content: esquema utilizado con descargas en una ubicación interna, pero sí como file: (Intentar envolver la ruta interna en un objeto File y luego obtener la ruta tampoco funciona, a pesar de que da como resultado un file: url, ya que la aplicación no analiza el apk; parece que debe ser externo).

Ejemplo:

 int uriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI); String downloadedPackageUriString = cursor.getString(uriIndex); File mFile = new File(Uri.parse(downloadedPackageUriString).getPath()); Intent promptInstall = new Intent(Intent.ACTION_VIEW) .setDataAndType(Uri.fromFile(mFile), "application/vnd.android.package-archive") .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); appContext.startActivity(promptInstall); 

Otra solución que no requiere codificar la aplicación receptora y que, por lo tanto, es más segura:

 Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); intent.setData( Uri.fromFile(new File(pathToApk)) ); startActivity(intent); 

Solo una extensión, si alguien necesita una biblioteca, esto podría ayudar. Gracias a Raghav

prueba esto

 String filePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)); String title = filePath.substring( filePath.lastIndexOf('/')+1, filePath.length() ); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error! MainActivity.this.startActivity(intent); 

UpdateNode proporciona una API para Android para instalar paquetes APK desde otra aplicación.

Puede simplemente definir su actualización en línea e integrar la API en su aplicación, eso es todo.
Actualmente, la API está en estado Beta, pero usted mismo puede hacer algunas pruebas.

Además de eso, UpdateNode también ofrece mensajes a través del sistema, bastante útil si quieres contar algo importante a tus usuarios.

Soy parte del equipo de desarrollo de clientes y estoy usando al menos la funcionalidad de mensajes para mi propia aplicación de Android.

Vea aquí una descripción de cómo integrar la API

Prueba esto – Escribe en Manifiesto:

 uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions" 

Escribe el código:

 File sdCard = Environment.getExternalStorageDirectory(); String fileStr = sdCard.getAbsolutePath() + "/Download";// + "app-release.apk"; File file = new File(fileStr, "app-release.apk"); Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(promptInstall); 

Primero agregue la siguiente línea a AndroidManifest.xml:

  

A continuación, use el siguiente código para instalar apk:

 File sdCard = Environment.getExternalStorageDirectory(); String fileStr = sdCard.getAbsolutePath() + "/MyApp";// + "app-release.apk"; File file = new File(fileStr, "TaghvimShamsi.apk"); Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(promptInstall);