2011-01-04 12 views
8

La mia app ha inviato a casa questa traccia dello stack che sembra che qualcosa di molto sbagliato stia succedendo sotto il cofano.Perché sendTextMessage richiede un'autorizzazione 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) 

Quindi devo solo prendere qualsiasi e tutte le eccezioni intorno sendTextMessage? Chi è la colpa è questa?

risposta

2

La mia app ha inviato a casa questa traccia dello stack che sembra che qualcosa di molto sbagliato stia succedendo sotto il cofano.

Il modo in cui lo dici, presumo che questa è la prima volta che hai riscontrato questo problema e non succede su altri telefoni.

E 'possibile che nell'implementazione Android su questo modello di telefono, SmsManager tenti di controllare lo stato del telefono prima di tentare di inviare un messaggio SMS. Questo è puramente un tentativo, ma non sembra una cosa irragionevole da fare anche se i documenti API di telefonia per SMS Manager non lo menzionano. Forse no, non ne sono sicuro.

Poiché l'invio di un messaggio SMS è piuttosto critico nella tua app, allora sì dovresti certamente fare tutto il possibile per rilevare eventuali eccezioni eventualmente correlate all'invio del messaggio (e il ripristino dallo stato di eccezione se possibile).

Come sembra che questo particolare problema non possa essere ripristinato, perché non dichiarare usi-autorizzazione per READ_PHONE_STATE nel manifest?

+1

ho pensato READ_PHONE_STATE potrebbe spaventare gli utenti che non vorrebbe che io sappia il loro numero di telefono . Oh bene...Penso che catturerò e ignorerò questa eccezione (riferirò all'utente) come è accaduto esattamente una volta nell'intera vita dell'app ... – ubershmekel

+2

@ubershmekel: Sì, ho capito di non usare READ_PHONE_STATE se puoi evitarlo . Forse questo era solo un one-off e si spera che l'eccezione possa aiutare. – Squonk

7

Ora vedo che in Lollipop (API 21), anche utilizzando una funzione benigna come SmsManager.getDefault().divideMessage(String) - richiede l'autorizzazione READ_PHONE_STATE. Sono sicuro che non era necessario prima e che si tratta di un problema del sistema operativo, poiché l'ho testato su dispositivi Nexus 5 prima e dopo l'aggiornamento a Lollipop. Prima, quando si eseguiva KitKat, gli SMS funzionavano bene senza l'autorizzazione READ_PHONE_STATE. E dopo, è stato richiesto.

Il motivo è che, immagino, le funzioni di telefonia cercano di prendere decisioni sagge su, beh, tutto. Quindi, un'operazione semplice come la divisione di un SMS (nemmeno l'invio) raggiunge lo SmsManager per interrogarlo sullo stato del telefono.

Penso che sia un bug di progettazione. E come hai detto sopra, può e dovrebbe spaventare gli utenti. Perché mai hanno così tante autorizzazioni ambigue su Android?

Questa è la mia analisi dello stack, solo per divertimento:

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ì, sto vedendo uno stacktrace simile (numeri di linea leggermente diversi) su OnePlus One con Loolipop in esecuzione. Segnalato come https://code.google.com/p/android/issues/detail?id=81758 Please star :) – Flow

+1

Ricevo questo errore su un Y550, ma la mia app ha READ_PHONE_STATE dichiarato come autorizzazione nel manifest ?? – LairdPleng

+1

Ho lo stesso identico problema con SmsManager.getDefault(). DivideMessage (String) che richiede READ_PHONE_STATE per Lollipop. È molto irritante! – goseib

0

Ho avuto lo stesso problema con un telefono HTC (Desire 728G) Dual Sim e ho dovuto includere "READ_PHONE_STATE", ma ora Google è chiedere una politica sulla privacy, e perché sono troppo pigro per farlo :) Ho fatto qualche ricerca e ho trovato un modo migliore senza l'uso di "READ_PHONE_STATE". Il problema è che alcuni dispositivi (principalmente dual sim) necessitano dell'autorizzazione "READ_PHONE_STATE" per cercare il valore predefinito "SubscriptionId", ovvero ciò che accade quando si chiama "SmsManager.getDefault()". Di seguito è riportato il codice che sto usando per evitare questo problema assegnando il valore (1) per SubscriptionId se alcuna eccezione maturato:

  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); 
Problemi correlati