¿Por qué sendTextMessage requiere el permiso READ_PHONE_STATE?

Mi aplicación envió a casa este rastro de pila que parece como si algo muy mal está pasando bajo el capó.

Phone_model = SKY IM-A630K, android_version = 2.1-update1

java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10089 nor current process has android.permission.READ_PHONE_STATE. at android.os.Parcel.readException(Parcel.java:1218) at android.os.Parcel.readException(Parcel.java:1206) at com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy.getLine1Number(IPhoneSubInfo.java:223) at android.telephony.TelephonyManager.getLine1Number(TelephonyManager.java:764) at android.telephony.SmsManager.sendTextMessage(SmsManager.java:129) at android.telephony.SmsManager.sendTextMessage(SmsManager.java:108) at com.emergency.button.SMSSender.safeSendSMS(SMSSender.java:91) at com.emergency.button.EmergencyActivity$EmergencyThread.sendSMS(EmergencyActivity.java:294) at com.emergency.button.EmergencyActivity$EmergencyThread.sendMessages(EmergencyActivity.java:386) at com.emergency.button.EmergencyActivity$EmergencyThread.run(EmergencyActivity.java:266) 

Entonces, ¿debería simplemente capturar todas y cada una de las excepciones alrededor de sendTextMessage? ¿Quién es culpa es esto?

Mi aplicación envió a casa este rastro de pila que parece como si algo muy mal está pasando bajo el capó.

La forma en que usted dice esto, supongo que esta es la primera vez que ve este problema y no sucede en otros teléfonos.

Es posible que en la implementación de Android en este modelo de teléfono, el SmsManager intente comprobar el estado del teléfono antes de intentar enviar un mensaje SMS. Eso es puramente una suposición, pero no parece una cosa irrazonable a hacer, aunque los documentos de API de telefonía para SMS Manager no lo mencionan. Tal vez no, no estoy seguro.

Como enviar un mensaje SMS es bastante crítico en tu aplicación, entonces sí, ciertamente deberías estar haciendo todo lo posible para detectar cualquier excepción posiblemente relacionada con el envío de los mensajes (y la recuperación del estado de excepción si es posible).

Como parece que este problema en particular no se puede recuperar, ¿por qué no declarar uses-permission para READ_PHONE_STATE en su manifiesto?

Ahora veo que en Lollipop (API 21), incluso usando una función benigna como SmsManager.getDefault().divideMessage(String) – requiere el permiso READ_PHONE_STATE . Estoy seguro de que no era necesario antes, y que es un problema de SO, ya que lo probé en dispositivos Nexus 5 antes, y después de la actualización a Lollipop. Antes, al ejecutar KitKat, SMS funcionaba bien sin el permiso READ_PHONE_STATE . Y después, fue necesario.

La razón es que, supongo, las funciones de telefonía tratan de tomar decisiones sabias sobre, bueno, todo. Así que una tarea sencilla como dividir un SMS (ni siquiera enviarlo) se ejecuta todo el camino hasta el SmsManager para consultarlo sobre el estado del teléfono.

Creo que es un error de diseño. Y como usted dijo anteriormente, puede, y debe asustar a los usuarios. ¿Por qué diablos tienen tantos permisos ambiguos en Android?

Éste es mi rastro de la pila, apenas para la diversión:

 java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10078 nor current process has android.permission.READ_PHONE_STATE. at android.os.Parcel.readException(Parcel.java:1540) at android.os.Parcel.readException(Parcel.java:1493) at com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy.getGroupIdLevel1(IPhoneSubInfo.java:465) at android.telephony.TelephonyManager.getGroupIdLevel1(TelephonyManager.java:1666) at android.telephony.SmsMessage.hasEmsSupport(SmsMessage.java:776) at com.android.internal.telephony.gsm.SmsMessage.calculateLength(SmsMessage.java:808) at android.telephony.SmsMessage.fragmentText(SmsMessage.java:322) at android.telephony.SmsManager.divideMessage(SmsManager.java:328) at mobi.chatfish.utils.CFCommunications.sendSMSDirect(CFCommunications.java:138) 

Tuve el mismo problema con un teléfono HTC (Desire 728G) Dual Sim y tuve que incluir "READ_PHONE_STATE", pero ahora Google está pidiendo una política de privacidad, y porque soy demasiado perezoso para hacerlo 🙂 Hice algunas investigaciones y me Encontró una mejor manera sin el uso de "READ_PHONE_STATE". El problema es que algunos dispositivos (principalmente dual sim) necesitan el permiso "READ_PHONE_STATE" para buscar el "SubscriptionId" por defecto que es lo que sucede cuando llamas a "SmsManager.getDefault ()". A continuación se muestra el código que estoy utilizando para evitar este problema asignando el valor (1) a SubscriptionId si alguna excepción se acumuló:

  SmsManager smsManager = SmsManager.getDefault(); if (android.os.Build.VERSION.SDK_INT >= 22){ Log.e("Alert","Checking SubscriptionId"); try { Log.e("Alert","SubscriptionId is " + smsManager.getSubscriptionId()); } catch (Exception e) { Log.e("Alert",e.getMessage()); Log.e("Alert","Fixed SubscriptionId to 1"); smsManager = SmsManager.getSmsManagerForSubscriptionId(1); } } smsManager.sendTextMessage(mobileNumber, null, msgStr, null, null); 
  • Bloquear llamadas entrantes y sms en android
  • Interceptar mensaje SMS entrante y modificarlo
  • Diálogo de confirmación de Android SMS
  • El envío de SMS mediante Intent no incluye destinatarios en algunos dispositivos
  • Android - Consultando el ContentProvider de SMS?
  • ¿Cómo supervisar cada estado de SMS enviado?
  • Obtener número de teléfono para varios destinatarios en android
  • Clase 0 SMS (SMS flash) en Android
  • Android Market dice que mi aplicación "no está en el grupo de destino" o que "no se puede instalar en este dispositivo"
  • Estado de sms de Android
  • SMS no se puede prevenir usando abortBroadcast ()?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.