android programmatically update apk y ver el resultado de la instalación
android-intent android-install-apk (3)
En primer lugar, no puede instalar sin preguntar, a menos que esté rooteado o tenga privilegios del sistema. No creo que estuvieras preguntando eso, pero uno de tus párrafos no está claro.
En segundo lugar, si está instalando una versión de actualización de una aplicación en ejecución, se espera el comportamiento que está viendo: la aplicación se cierra forzosamente y se actualiza. No puedes actualizar en el lugar. Puede detectar cuándo se canceló la instalación, ya que se reanudará la actividad que invoca al instalador.
Para actualizar una aplicación en ejecución Y mantenerla en ejecución, necesitará un proceso separado (aplicación) para monitorear la instalación y reiniciar su aplicación.
Estoy escribiendo un actualizador de aplicación para mi aplicación. Después de asegurarme de tener mi apk en el dispositivo, esto es lo que hago desde la aplicación que intento actualizar:
Intent promptInstall = new Intent(Intent.ACTION_VIEW);
File f = new File(apkLocation);
promptInstall.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive");
_context.startActivity(promptInstall);
Esto inicia mi instalador que muestra los permisos de la aplicación y puedo hacer clic en "Instalar". Pero desde aquí la aplicación simplemente se cierra, no recibo ningún mensaje (esperaba el diálogo que me decía que la instalación había sido exitosa, dándome la opción de presionar "Cerrar" o "Abrir"). Simplemente va a la pantalla principal del dispositivo sin previo aviso.
En una nota lateral, la aplicación se actualiza cuando la abro manualmente. ¿Cómo puedo hacer que el instalador funcione como se espera? ¿Hay algo para establecer en la intención?
Mientras escribo esto, me pregunto si la razón por la que esto sucede es que la aplicación actual simplemente se sobrescribe en el dispositivo, cerrándola y, en cierta medida, no obteniendo el resultado de la intención porque se mató a la fuente.
Todo lo que puede hacer es registrar un receptor con filtros de intención como android.intent.action.PACKAGE_INSTALL
o android.intent.action.PACKAGE_REPLACED
desde donde puede reiniciar su aplicación nuevamente.
<receiver android:enabled="true" android:exported="true" android:label="BootService" android:name="com.project.services.BootService">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<data android:scheme="package"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<data android:scheme="package"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_CHANGED"/>
<data android:scheme="package"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
</application>
Y
public class BootService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
Intent serviceIntent = new Intent();
serviceIntent.setClass(context,Controller.class);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(serviceIntent);
} else if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
Intent serviceIntent = new Intent();
serviceIntent.setClass(context, Controller.class);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(serviceIntent);
}
}
}
Para actualizar correctamente necesita iniciar el intento con URI que indica a su aplicación de actualización como una nueva tarea.
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(PATH_TO_APK));
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Mi publicación a continuación: