Ambos mensajes de error en la pregunta incluyen un mensaje en el siguiente formato:
java.lang.SecurityException: [ID de la app] from uid [ID de usuario] not allowed to perform [ID de permiso]
Recordé que para las aplicaciones afectadas, una vez deshabilité algunos permisos usando la función "Permisos de la app" de OxygenOS 2/Lollipop. En OxygenOS 3/Marshmallow, "Permisos de la app" ha sido reemplazado por el sistema de gestión de permisos de Android 6. Aunque la interfaz de usuario desapareció después de la actualización, el back-end no lo hizo y causó fallos cuando la página de configuración intentaba verificar el permiso.
Para solucionar los problemas, limpié algunos permisos de appops, de la siguiente manera:
- En el teléfono: Habilitar "Depuración USB" (Configuración > Opciones de desarrollador > Depuración USB).
- Conecta tu teléfono a tu computadora (donde está instalado ADB).
- En la computadora: Inicia
adb logcat
para obtener un flujo continuo de mensajes de registro (también puedes usar Logcat en el teléfono, pero usar la computadora es más fácil ya que necesitarás el espacio de la pantalla del teléfono en un paso posterior).
- En la computadora: Usa
adb shell
para obtener un shell (probablemente no se necesite ser root).
-
Ahora repite los siguientes pasos para cada app en Configuración > Aplicaciones:
-
Toca el icono de la app para ver su configuración.
-
Si la sección de "Permisos" no está vacía, salta los siguientes pasos y continúa con la siguiente app (por ejemplo, cuando muestra "No se han otorgado permisos" o "No se han solicitado permisos" o un permiso específico como "Ubicación").
-
De lo contrario (la sección de "Permisos" está en blanco), toca en "Permisos".
-
Ahora verás “El instalador de paquetes dejó de funcionar”.
-
Mira la salida de logcat y busca el siguiente mensaje:
java.lang.RuntimeException: Unable to start receiver com.android.packageinstaller.permission.model.PermissionStatusReceiver: java.lang.SecurityException: com.google.android.talk from uid 10100 not allowed to perform WRITE_CONTACTS
En los ejemplos a continuación, utilizaré com.google.android.talk como ID de la app y WRITE_CONTACTS como ID de la operación/permiso.
-
OPCIONAL: Primero mira la operación existente, en caso de que quieras restaurar el valor original (en este caso, la salida es "WRITE_CONTACTS: deny"), ejecuta lo siguiente en adb shell
:
appops get com.google.android.talk WRITE_CONTACTS
(ejecuta "appops" sin argumentos para más opciones/ayuda.)
-
Permite la operación, ejecutando el siguiente comando en el adb shell
(si no funciona, prueba con "allow" en lugar de "default"):
appops set com.google.android.talk WRITE_CONTACTS default
-
Si obtienes "No operations", entonces es probable que el nombre del permiso sea diferente. Ejecuta appops get com.google.android.talk
(sin el permiso específico) para ver todos los permisos existentes. Por ejemplo, logcat muestra "READ_ICC_SMS", pero el ID de operación real como se muestra en el comando appops
es "READ_SMS"
-
En tu teléfono, toca en "Permisos". Si se bloquea nuevamente, repite los pasos anteriores (Mira la salida de logcat, ...). Si no se bloquea, se mostrarán los Permisos para la app seleccionada y puedes revocar los permisos si lo deseas.
Después de seguir todos los pasos, no obtuve ningún fallo de "El instalador de paquetes dejó de funcionar" en el menú de configuración, y también pude usar Configuración > Aplicaciones > Icono de engranaje > Permisos de acceso.
PD: no todos los permisos de appops son problemáticos. Algunas de las operaciones que tuve que permitir para algunas apps son: COARSE_LOCATION, CALL_PHONE, CAMERA, READ_CONTACTS, READ_SMS, RECEIVE_SMS, SEND_SMS, WRITE_CONTACTS. Por ejemplo, para Hangouts, negar las siguientes operaciones no evita que la pantalla de configuración funcione: WRITE_SMS, WRITE_WALLPAPER.