No sé qué significa "cargador dinámico, dependiente del entorno del usuario actual". La respuesta proporcionada por @Lie Ryan muestra cómo puede instalar un APK descargado por cualquier medio que elija.
CommonsWare
Respuestas:
241
Puede iniciar fácilmente un enlace de Play Store o un mensaje de instalación:
Buena respuesta, pero no codifique /sdcard, ya que está mal en Android 2.2+ y otros dispositivos. Usar en su Environment.getExternalStorageDirectory()lugar.
CommonsWare
3
El directorio / asset / solo existe en su máquina de desarrollo, cuando la aplicación se compila en un APK, el directorio / asset / ya no existe ya que todos los activos están comprimidos dentro del APK. Si desea instalar desde su directorio / asset /, primero deberá extraerlo en otra carpeta.
Lie Ryan
2
@LieRyan. Es bueno ver tu respuesta. Tengo el dispositivo rooteado con ROM personalizada. Quiero instalar temas dinámicamente sin pedirle al usuario que presione el botón de instalación. Puedo hacer eso.
Sharanabasu Angadi
1
Esto ya no parece funcionar cuando targetSdk es 25. da una excepción: "android.os.FileUriExposedException: ... apk expuesto más allá de la aplicación a través de Intent.getData () ...". ¿Cómo?
Desarrollador de Android el
44
Desarrollador de Android: no puedo probar esto, por el momento, pero en targetSdkVersion> = 24, se aplica lo siguiente: stackoverflow.com/questions/38200282/…, por lo que debe usar FileProvider.
Tuve el mismo problema y después de varios intentos, funcionó para mí de esta manera. No sé por qué, pero configurar los datos y el tipo por separado arruinó mi intención.
No puedo votar esta respuesta lo suficiente. Por alguna razón, establecer los datos de intención y el tipo MIME por separado provoca ActivityNotFoundException en el nivel 17 de API.
Brent M. Spell
Acabo de votar esto también. Este formulario fue el único que pude poner a trabajar. Aún años después ... ¿qué es este bicho raro? Horas desperdiciadas. Estoy usando Eclipse (Helios), por cierto.
Tam
10
@ BrentM.Spell y otros: mire la documentación, verá que cada vez que configura solo datos O tipo, el otro se anula automáticamente, por ejemplo: setData()causaría la eliminación del parámetro tipo. DEBE usar setDataAndType()si desea dar valores para ambos. Aquí: developer.android.com/reference/android/content/…
Bogdan Alexandru
41
Las soluciones proporcionadas a esta pregunta son aplicables a los targetSdkVersions de 23 y menos. Sin embargo, para Android N, es decir, el nivel de API 24 y superior, 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, la Uridirección del archivo descargado ha cambiado. Por ejemplo, un archivo de instalación denominado appName.apkalmacenado en el sistema de archivos externo primario de la aplicación con el nombre del paquete com.example.testsería
El pathNamees el que se muestra en el ejemplo de contenido de uri anterior y pathValuees la ruta real en el sistema. Sería una buena idea poner un "." (sin comillas) para pathValue en lo anterior si no desea agregar ningún subdirectorio adicional.
Escriba el siguiente código para instalar el apk con el nombre appName.apken el sistema de archivos externo primario:
Seguí este método. Sin embargo, dice que el archivo está dañado cuando presiono el botón de instalación. Soy capaz de instalar el mismo archivo transfiriéndolo a través de bluetooth. ¿porque?
HI Cuando recibes un error de archivo dañado, ¿cuál es el modo de transporte que le diste a tu aplicación para traer el APK? Supongo que desde la instalación del APK que fue transferido por Bluetooth funcionando, ese es el problema.
Sridhar S
2
java.lang.NullPointerException: intento de invocar el método virtual 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData (android.content.pm.PackageManager, java.lang.String)' en una referencia de objeto nulo
Makvin
Su biblioteca podría tener al fin un archivo léame simple con instrucciones simples sobre el uso ...;)
Renetik
2
¡Muchas gracias, después de una semana de lucha con esta respuesta, resolví mi problema! @SridharS, sé que hace mucho tiempo, como veo, pero si le interesa, en la línea 5, debe agregar .authorityStrdespués, context.getPackageName()entonces debería funcionar.
sehrob
30
Bueno, profundicé y encontré fuentes de la aplicación PackageInstaller de Android Source.
android.permission.INSTALL_PACKAGES está disponible solo para las aplicaciones firmadas del sistema. Así que esto no ayudaría mucho
Hubert Liberacki
21
Solo quiero compartir el hecho de que mi archivo apk se guardó en el directorio "Datos" de mi aplicación y que necesitaba cambiar los permisos en el archivo apk para que fuera legible en todo el mundo para permitir que se instale de esa manera, de lo contrario, el sistema estaba lanzando "Error de análisis: hay un problema al analizar el paquete"; entonces usando la solución de @Horaceman que hace:
Tercero: ¡ defina path.xml en la carpeta res / xml como se muestra a continuación! Estoy usando esta ruta para el almacenamiento interno si desea cambiarla a otra cosa, ¡hay algunas maneras! Puedes ir a este enlace:
FileProvider
Permite que una aplicación solicite paquetes de instalación. Las aplicaciones dirigidas a API mayores de 25 deben tener este permiso para usar Intent.ACTION_INSTALL_PACKAGE.
¡Asegúrese de que las autoridades del proveedor sean las mismas!
Gracias, el cuarto paso fue lo que faltaba en todos ellos.
Amin Keshavarzian
1
De hecho, el cuarto punto es absolutamente necesario. Todas las demás respuestas lo perdieron por completo.
whiteagle
¿No está disponible android.permission.REQUEST_INSTALL_PACKAGES solo para aplicaciones del sistema o aplicaciones firmadas con el almacén de claves del sistema o lo que sea?
pavi2410
@Pavitra Permite que una aplicación solicite la instalación de paquetes. Las aplicaciones dirigidas a API mayores de 25 deben tener este permiso para usar Intent.ACTION_INSTALL_PACKAGE. Nivel de protección: firma
Hadi Note
Este código no usa Intent.ACTION_INSTALL_PACKAGE. Entonces, ¿por qué este permiso?
Alexander Dyagilev
5
Otra solución que no requiere codificar la aplicación receptora y que, por lo tanto, es más segura:
Si es posible. Pero para eso necesita el teléfono para instalar fuentes no verificadas. Por ejemplo, slideMe hace eso. Creo que lo mejor que puede hacer es verificar si la aplicación está presente y enviar una intención para Android Market. deberías usar algo del esquema de URL para Android Market.
market://details?id=package.name
No sé exactamente cómo iniciar la actividad, pero si comienzas una actividad con ese tipo de URL. Debería abrir el Android Market y darle la opción de instalar las aplicaciones.
Como veo, esta solución es la más cercana a la verdad :). Pero no es apropiado para mi caso. Necesito un cargador dinámico, que dependa del entorno de usuario actual y que vaya al mercado, no es una buena solución. Pero de todos modos, gracias.
Alkersan
4
Vale la pena señalar que si utiliza el DownloadManagerpara iniciar su descarga, asegúrese de guardarlo en una ubicación externa, por ejemplo setDestinationInExternalFilesDir(c, null, "<your name here>).apk";. La intención con un tipo de paquete-archivo no parece gustarle el content:esquema utilizado con las descargas a una ubicación interna, pero sí file:. (Intentar ajustar la ruta interna en un objeto File y luego obtener la ruta tampoco funciona, a pesar de que resulta en unfile: URL, ya que la aplicación no analizará el apk; parece que debe ser externo).
String filePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));String title = filePath.substring( filePath.lastIndexOf('/')+1, filePath.length());Intent intent =newIntent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(newFile(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 dentro de otra aplicación.
Simplemente puede 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 ya puede hacer algunas pruebas usted mismo.
Además de eso, UpdateNode también ofrece mostrar mensajes a través del sistema, bastante útil si desea contar algo importante para sus usuarios.
Soy parte del equipo de desarrollo del cliente y estoy usando al menos la funcionalidad de mensajes para mi propia aplicación de Android.
Respuestas:
Puede iniciar fácilmente un enlace de Play Store o un mensaje de instalación:
o
Sin embargo, no puede instalar .apks sin el permiso explícito del usuario ; no a menos que el dispositivo y su programa estén rooteados.
fuente
/sdcard
, ya que está mal en Android 2.2+ y otros dispositivos. Usar en suEnvironment.getExternalStorageDirectory()
lugar.Tuve el mismo problema y después de varios intentos, funcionó para mí de esta manera. No sé por qué, pero configurar los datos y el tipo por separado arruinó mi intención.
fuente
setData()
causaría la eliminación del parámetro tipo. DEBE usarsetDataAndType()
si desea dar valores para ambos. Aquí: developer.android.com/reference/android/content/…Las soluciones proporcionadas a esta pregunta son aplicables a los
targetSdkVersion
s de 23 y menos. Sin embargo, para Android N, es decir, el nivel de API 24 y superior, no funcionan y se bloquean con la siguiente excepción:Esto se debe al hecho de que a partir de Android 24, la
Uri
dirección del archivo descargado ha cambiado. Por ejemplo, un archivo de instalación denominadoappName.apk
almacenado en el sistema de archivos externo primario de la aplicación con el nombre del paquetecom.example.test
seríafile:///storage/emulated/0/Android/data/com.example.test/files/appName.apk
para
API 23
y debajo, mientras que algo comopara
API 24
y encima.Más detalles sobre esto se pueden encontrar aquí y no voy a pasar por ello.
Para responder a la pregunta
targetSdkVersion
de24
y más arriba, uno tiene que seguir estos pasos: Agregue lo siguiente al AndroidManifest.xml:2. Agregue el siguiente
paths.xml
archivo a laxml
carpetares
en src, main:El
pathName
es el que se muestra en el ejemplo de contenido de uri anterior ypathValue
es la ruta real en el sistema. Sería una buena idea poner un "." (sin comillas) para pathValue en lo anterior si no desea agregar ningún subdirectorio adicional.Escriba el siguiente código para instalar el apk con el nombre
appName.apk
en el sistema de archivos externo primario:Tampoco se necesita 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.
fuente
.authorityStr
después,context.getPackageName()
entonces debería funcionar.Bueno, profundicé y encontré fuentes 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
fuente
Solo quiero compartir el hecho de que mi archivo apk se guardó en el directorio "Datos" de mi aplicación y que necesitaba cambiar los permisos en el archivo apk para que fuera legible en todo el mundo para permitir que se instale de esa manera, de lo contrario, el sistema estaba lanzando "Error de análisis: hay un problema al analizar el paquete"; entonces usando la solución de @Horaceman que hace:
fuente
¡Esto puede ayudar mucho a otros!
Primero:
Segundo: para Android 7 y superior, debe definir un proveedor en manifiesto como a continuación.
Tercero: ¡ defina path.xml en la carpeta res / xml como se muestra a continuación! Estoy usando esta ruta para el almacenamiento interno si desea cambiarla a otra cosa, ¡hay algunas maneras! Puedes ir a este enlace: FileProvider
Adelante: debe agregar este permiso en manifiesto:
fuente
Otra solución que no requiere codificar la aplicación receptora y que, por lo tanto, es más segura:
fuente
Si es posible. Pero para eso necesita el teléfono para instalar fuentes no verificadas. Por ejemplo, slideMe hace eso. Creo que lo mejor que puede hacer es verificar si la aplicación está presente y enviar una intención para Android Market. deberías usar algo del esquema de URL para Android Market.
No sé exactamente cómo iniciar la actividad, pero si comienzas una actividad con ese tipo de URL. Debería abrir el Android Market y darle la opción de instalar las aplicaciones.
fuente
Vale la pena señalar que si utiliza el
DownloadManager
para iniciar su descarga, asegúrese de guardarlo en una ubicación externa, por ejemplosetDestinationInExternalFilesDir(c, null, "<your name here>).apk";
. La intención con un tipo de paquete-archivo no parece gustarle elcontent:
esquema utilizado con las descargas a una ubicación interna, pero sífile:
. (Intentar ajustar la ruta interna en un objeto File y luego obtener la ruta tampoco funciona, a pesar de que resulta en unfile:
URL, ya que la aplicación no analizará el apk; parece que debe ser externo).Ejemplo:
fuente
No olvides solicitar permisos:
Agregue en AndroidManifest.xml el proveedor y el permiso:
Crear proveedor de archivos XML res / xml / provider_paths.xml
Utilice el siguiente código de ejemplo:
fuente
Solo una extensión, si alguien necesita una biblioteca, esto podría ayudar. Gracias a Raghav
fuente
prueba esto
fuente
Primero agregue la siguiente línea a AndroidManifest.xml:
Luego use el siguiente código para instalar apk:
fuente
UpdateNode proporciona una API para Android para instalar paquetes APK desde dentro de otra aplicación.
Simplemente puede 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 ya puede hacer algunas pruebas usted mismo.
Además de eso, UpdateNode también ofrece mostrar mensajes a través del sistema, bastante útil si desea contar algo importante para sus usuarios.
Soy parte del equipo de desarrollo del cliente 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
fuente
Prueba esto: escribe en el manifiesto:
Escribe el código:
fuente