Solución:
Para empezar, su aplicación debe declarar un targetSdkVersion
de 26 (nivel de API de Android Oreo) o superior en su build.gradle o AndroidManifest.xml para que todo esto funcione.
Luego, responda las preguntas anteriores:
- ¿Cómo comprobar si puedo solicitar la instalación de un paquete?
Puede verificar esto usando getPackageManager().canRequestPackageInstalls()
en cualquier lugar del código de su actividad. Tenga en cuenta que este método siempre devuelve false
, si no declara el permiso apropiado o apunta a la versión incorrecta del SDK.
- ¿Qué permiso exacto tengo que solicitar?
Tienes que declarar Manifest.permission.REQUEST_INSTALL_PACKAGES
en su AndroidManifest.xml, así:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
- ¿Cómo puedo pedirle al usuario que otorgue este permiso?
Puede enviar al usuario al destino apropiado, con Intención ACTION_MANAGE_UNKNOWN_APP_SOURCES
:
startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES));
También puede enviar al usuario más directamente a la configuración específica de su aplicación, con:
startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:your.application.package")));
- ¿Cómo le pido al usuario que instale un .apk específico?
Una vez que se haya asegurado de que se le haya otorgado el permiso apropiado, puede solicitar al usuario que instale su archivo .apk en cualquier lugar del código de su actividad (donde this
se refiere a tu actividad Context
), utilizando:
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setDataAndType(FileProvider.getUriForFile(this, "your.application.package.fileprovider", new File("/path/to/your/apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
También puede agregar intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
y empezar con startActivityForResult(Intent, int)
, si desea saber si la instalación se realizó correctamente, se canceló o falló.
Para obtener información sobre cómo obtener correctamente el Uri de su archivo .apk, consulte FileProvider
.
Desde adb shell puede administrar permisos específicos de la aplicación usando appops
. Ejemplo:
# To get a list of packagenames that is allowed to install from other sources
appops query-op REQUEST_INSTALL_PACKAGES allow
# To allow an app install packages from other sources
appops set <package name> REQUEST_INSTALL_PACKAGES deny
Texto de ayuda impreso durante la ejecución adb shell appops help
:
AppOps service (appops) commands:
help
Print this help text.
set [--user <USER_ID>] <PACKAGE | UID> <OP> <MODE>
Set the mode for a particular application and operation.
get [--user <USER_ID>] <PACKAGE | UID> [<OP>]
Return the mode for a particular application and optional operation.
query-op [--user <USER_ID>] <OP> [<MODE>]
Print all packages that currently have the given op in the given mode.
reset [--user <USER_ID>] [<PACKAGE>]
Reset the given application or all applications to default modes.
write-settings
Immediately write pending changes to storage.
read-settings
Read the last written settings, replacing current state in RAM.
options:
<PACKAGE> an Android package name.
<OP> an AppOps operation.
<MODE> one of allow, ignore, deny, or default
<USER_ID> the user id under which the package is installed. If --user is not
specified, the current user is assumed.