2011-01-04 13 views
8

Mi aplicación envió a casa esta traza de pila que parece como si algo muy malo estuviera pasando debajo del capó.¿Por qué sendTextMessage requiere el permiso READ_PHONE_STATE?

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) 

Así debe acabo de coger cualquier y todas las excepciones alrededor sendTextMessage? ¿Quién es el culpable?

Respuesta

2

Mi aplicación envió a casa esta traza de pila que parece como si algo muy malo estuviera pasando debajo del capó.

La forma en que dices esto, supongo que es la primera vez que ves este problema y no ocurre en otros teléfonos.

Es posible que en la implementación de Android en este modelo de teléfono, el SmsManager intente verificar el estado del teléfono antes de intentar enviar un mensaje SMS. Eso es solo una suposición, pero no parece una cosa irracional, aunque los documentos API de Telefonía para SMS Manager no lo mencionan. Quizás no, no estoy seguro.

Como el envío de un mensaje SMS es bastante crítico en su aplicación, entonces sí debe hacer todo lo posible para detectar cualquier posible excepción relacionada con el envío de la mensajera (y recuperarse del estado de excepción si es posible).

Como parece que no se puede recuperar este problema en particular, ¿por qué no declarar permisos de uso para READ_PHONE_STATE en su manifiesto?

+1

pensé READ_PHONE_STATE podría asustar a los usuarios que no quieren que sepa su número de teléfono . Oh bien...Creo que simplemente atraparé e ignoraré esta excepción (informaré al usuario) ya que ocurrió exactamente una vez en la vida útil de toda la aplicación ... – ubershmekel

+2

@ubershmekel: Sí, entiendo que no use READ_PHONE_STATE si puede evitarlo . Tal vez esto fue solo una excepción y con suerte atrapar la excepción ayudará. – Squonk

7

Ahora veo que en Lollipop (API 21), incluso utilizando 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 sistema operativo, ya que lo probé en dispositivos Nexus 5 antes, y después de actualizar a Lollipop. Antes, al ejecutar KitKat, SMS funcionaba bien sin el permiso READ_PHONE_STATE. Y después, fue requerido.

La razón es que, supongo, las funciones de telefonía intentan tomar decisiones acertadas sobre, bueno, todo. Por lo tanto, una tarea simple como dividir un SMS (ni siquiera enviarlo) se ejecuta hasta el SmsManager para consultarlo sobre el estado del teléfono.

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

Ésta es mi seguimiento de la pila, sólo por 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) 
+2

Sí, estoy viendo un stacktrace similar (números de línea ligeramente diferentes) en un OnePlus One que ejecuta Loolipop. Informó como https://code.google.com/p/android/issues/detail?id=81758 Por favor, estrella :) – Flow

+1

Recibo este error en un Y550, pero mi aplicación TIENE READ_PHONE_STATE declarado como un permiso en el manifiesto ?? – LairdPleng

+1

Tengo exactamente el mismo problema con SmsManager.getDefault(). DivideMessage (String) que requiere READ_PHONE_STATE para Lollipop. ¡Es muy irritante! – goseib

0

que tenía el mismo problema con un teléfono HTC (Desire 728G) doble sim y he tenido que incluir "READ_PHONE_STATE" pero ahora Google es pidiendo una política de privacidad, y porque soy demasiado flojo para hacerlo :) Investigué un poco y encontré una manera mejor sin el uso de "READ_PHONE_STATE". El problema es que algunos dispositivos (principalmente los sim dual) necesitan el permiso "READ_PHONE_STATE" para buscar el "SubscriptionId" predeterminado, 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 ninguna excepción devenga:

  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); 
Cuestiones relacionadas