2012-01-31 28 views
23

我試圖從以下短信的例子: http://mobiforge.com/developing/story/sms-messaging-android 但我收到以下例外,如果我嘗試發送消息。IntentRecieverLeakedException,您是否缺少對unregisterReceiver()的調用?在android

Exception: 
    02-07 12:38:15.447: ERROR/ActivityThread(839): Activity com.micro.MyTest has leaked IntentReceiver [email protected] 
that was originally registered here. Are you missing a call to 
unregisterReceiver()? 
    02-07 12:38:15.447: ERROR/ActivityThread(839): android.app.IntentReceiverLeaked: Activity com.test.SendSMS has leaked 
IntentReceiver com.test.SendSMS [email protected] that was originally 
registered here. Are you missing a call to unregisterReceiver()? 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:707) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:535) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ApplicationContext.registerReceiverInternal(ApplicationContext.java:748) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:735) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:729) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:278) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at com.micro.MyTest.sendSMS(SendSMS .java:98) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at com.micro.MyTest.onCreate(SendSMS .java:42) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ActivityThread.access$1800(ActivityThread.java:112) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.os.Handler.dispatchMessage(Handler.java:99) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.os.Looper.loop(Looper.java:123) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at android.app.ActivityThread.main(ActivityThread.java:3948) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at java.lang.reflect.Method.invokeNative(Native Method) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at java.lang.reflect.Method.invoke(Method.java:521) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540) 
    02-07 12:38:15.447: ERROR/ActivityThread(839):  at dalvik.system.NativeStart.main(Native Method) 
    02-07 12:38:15.496: ERROR/ActivityThread(839): Activity com.micro.MyTest has leaked IntentReceiver [email protected] 
that was originally registered here. Are you missing a call to 
unregisterReceiver()? 
    02-07 12:38:15.496: ERROR/ActivityThread(839): android.app.IntentReceiverLeaked: Activity com.test.SendSMS has leaked 
IntentReceiver com.test.SendSMS [email protected] that was originally 
registered here. Are you missing a call to unregisterReceiver()? 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:707) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:535) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ApplicationContext.registerReceiverInternal(ApplicationContext.java:748) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:735) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:729) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:278) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at com.micro.MyTest.sendSMS(SendSMS .java:129) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at com.micro.MyTest.onCreate(SendSMS .java:42) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ActivityThread.access$1800(ActivityThread.java:112) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.os.Handler.dispatchMessage(Handler.java:99) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.os.Looper.loop(Looper.java:123) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at android.app.ActivityThread.main(ActivityThread.java:3948) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at java.lang.reflect.Method.invokeNative(Native Method) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at java.lang.reflect.Method.invoke(Method.java:521) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540) 
    02-07 12:38:15.496: ERROR/ActivityThread(839):  at dalvik.system.NativeStart.main(Native Method) 

它發送sms的方法:

publicvoid sendSMS(String phoneNumber, String message) { 
    String SENT = "SMS_SENT"; 
    String DELIVERED = "SMS_DELIVERED"; 

    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0); 
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0); 

    // When the SMS has been sent, the following line (line 98) throws Exception 

    registerReceiver(
    new BroadcastReceiver(){ 

     public void onReceive(Context arg0, Intent arg1) { 
     switch (getResultCode()) { 
      case Activity.RESULT_OK: 
      Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show(); 
      break; 
      case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
      Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show(); 
      break; 
      case SmsManager.RESULT_ERROR_NO_SERVICE: 
      Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show(); 
      break; 
      case SmsManager.RESULT_ERROR_NULL_PDU: 
      Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show(); 
      break; 
      case SmsManager.RESULT_ERROR_RADIO_OFF: 
      Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show(); 
      break; 
      } 
     } 

     }, new IntentFilter(SENT)); 

    // when the SMS has been delivered 

    registerReceiver(
    new BroadcastReceiver() { 

     public void onReceive(Context arg0, Intent arg1) { 
     switch (getResultCode()) { 
      case Activity.RESULT_OK: 
      Toast.makeText(getBaseContext(), "SMS Delivered",Toast.LENGTH_SHORT).show(); 
      break; 
     case Activity.RESULT_CANCELED: 
      Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show(); 
      break; 
     } 
     } 
    },new IntentFilter(DELIVERED)); 

    SmsManager sms = SmsManager.getDefault(); 
    sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI); 

} 

回答

47

在你的活動類,聲明這些全局變量:

private BroadcastReceiver sendBroadcastReceiver; 
private BroadcastReceiver deliveryBroadcastReceiver; 
String SENT = "SMS_SENT"; 
String DELIVERED = "SMS_DELIVERED"; 

覆蓋的onCreate您的活動並註冊您的接收器:

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    sendBroadcastReceiver = new BroadcastReceiver() 
    { 

     public void onReceive(Context arg0, Intent arg1) 
     { 
      switch (getResultCode()) 
      { 
      case Activity.RESULT_OK: 
       Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
       Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_NO_SERVICE: 
       Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_NULL_PDU: 
       Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_RADIO_OFF: 
       Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show(); 
       break; 
      } 
     } 
    }; 

    deliveryBroadcastReceiver = new BroadcastReceiver() 
    { 
     public void onReceive(Context arg0, Intent arg1) 
     { 
      switch (getResultCode()) 
      { 
      case Activity.RESULT_OK: 
       Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show(); 
       break; 
      case Activity.RESULT_CANCELED: 
       Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show(); 
       break; 
      } 
     } 
    }; 
registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED)); 
registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT)); 
} 

接下來,您發送短信的方式只留下了6行代碼:

public void sendSMS(String phoneNumber, String message) 
{ 
    String SENT = "SMS_SENT"; 
    String DELIVERED = "SMS_DELIVERED"; 
    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0); 
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0); 
    SmsManager sms = SmsManager.getDefault(); 
    sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI); 
} 

最後,註銷您的活動的一站,接收器:

@Override 
protected void onStop() 
{ 
    unregisterReceiver(sendBroadcastReceiver); 
    unregisterReceiver(deliveryBroadcastReceiver); 
    super.onStop(); 
} 
+0

好thanq ...在哪裏我應該爲registerReceiver添加代碼? – user2012 2012-02-03 06:42:49

+0

對不起,我錯過了。我已經更新了我的答案。 (在'onCreate'方法中調用註冊接收器) – 2012-02-03 15:07:26

+0

沒有工作? – 2012-02-05 13:08:56

0

的錯誤是你的問題很明確。您註冊registerReceiver()BroadcastReceiver的電話號碼不是unregisterReceiver()

+0

:好的謝謝你的回覆。如果我使用[鏈接](http://code.google.com/p/krvarma-android-samples/source/browse/trunk/SMSDemo/src/com/varma/samples/smsdemo/MainActivity。JAVA)本實施例中,我發現了以下異常未捕獲的處理程序:線程退出主要由於未捕獲的異常 了java.lang.RuntimeException:在[email protected] 錯誤接收廣播意圖{行動= SMS_SENT}。 。 。 引起:java.lang.NullPointerException ----------->在這裏我註銷接收器,然後也來了。 – user2012 2012-02-02 07:19:44

0

而註冊:

rec = new BroadcastReceiver() 
{ 
.... 
} 

防止接收器泄漏:

onStop() 
{ 
super.onStop(); 
unregisterReciever(rec); 
} 
+0

感謝您的回覆, 我可以使用相同的broadcastReceiver名稱發送和交付意圖?像 registerReceiver(REC =新的BroadcastReceiver() ........ ..... },新的IntentFilter(SENT));和 registerReceiver(REC =新的BroadcastReceiver() ........ ..... },新的IntentFilter(交付)); – user2012 2012-02-02 07:00:25

+1

我們已經差不多了。它應該是這樣的: 'rec = new BroadcastReceiver();IntentFilter filter = new IntentFilter(); filter.addAction(「ACTION1」); filter.addAction(「ACTION2」); registerReceiver(REC,過濾器);' 你必須問這是另外一個問題。 (也請標記你的原始問題的答案) – 2012-02-02 08:10:56

+0

好的..你可以告訴我,我應該在上面的代碼做修改。 – user2012 2012-02-02 11:36:59

1

使用以下兩類爲了避免這個問題

import android.app.Activity; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.util.Log; 

public class SmsDeliveredReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent arg1) { 
     switch (getResultCode()) { 
     case Activity.RESULT_OK: 
      Log.d("httpmon", "SMS delivered"); 
      break; 
     case Activity.RESULT_CANCELED: 
      Log.d("httpmon", "SMS not delivered"); 
      break; 
     } 
    } 
} 

和這一個用於短信發送接收器

import java.util.Collections; 
import java.util.HashMap; 
import android.app.Activity; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.os.PowerManager; 
import android.os.PowerManager.WakeLock; 
import android.telephony.gsm.SmsManager; 
import android.util.Log; 

public class SmsSentReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent arg1) { 
     switch (getResultCode()) { 
     case Activity.RESULT_OK: 
      Log.d("httpmon", "SMS sent"); 
      break; 
     case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
      Log.d("httpmon", "SMS generic failure"); 
      break; 
     case SmsManager.RESULT_ERROR_NO_SERVICE: 
      Log.d("httpmon", "SMS no service"); 
      break; 
     case SmsManager.RESULT_ERROR_NULL_PDU: 
      Log.d("httpmon", "SMS null PDU"); 
      break; 
     case SmsManager.RESULT_ERROR_RADIO_OFF: 
      Log.d("httpmon", "SMS radio off"); 
      break; 
     } 
    } 
} 

最後定接收器在您的清單文件

<receiver android:name=".SmsSentReceiver"> 
      <intent-filter> 
       <action android:name="SMS_SENT" /> 
      </intent-filter> 
     </receiver> 
     <receiver android:name=".SmsDeliveredReceiver"> 
      <intent-filter> 
       <action android:name="SMS_DELIVERED" /> 
      </intent-filter> 
     </receiver> 
+0

thanq ...你能告訴我如何通過發送函數來調用這些類嗎? – user2012 2012-02-17 10:34:01

+1

您不必調用這些類。這些課程將收到廣播的消息。您可以接收爲這些未決意圖設置的意向附加功能。 String SENT =「SMS_SENT」; String DELIVERED =「SMS_DELIVERED」; PendingIntent sentPI = PendingIntent.getBroadcast(this,0,new Intent(SENT),0); PendingIntent deliveredPI = PendingIntent.getBroadcast(this,0,new Intent(DELIVERED),0); SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage(phoneNumber,null,message,sentPI,deliveredPI); – 2012-03-26 09:13:07

+0

@VinothkumarArputharaj我實施了你的解決方案,效果很好。但我遇到了一個奇怪的行爲。如果我在循環中設置,我將繼續爲所有循環獲取相同的ID 0,1,2,3,4意向額外總是0任何想法? – eddwinpaz 2017-10-08 04:57:59

0

我解決了這一點:

@Override 
public void onReceive(Context arg0, Intent arg1) { 
    switch (getResultCode()) { 
... 
    unregisterReceiver(this); 
} 

的最後一件事做的是取消註冊的廣播中的onReceive

全:

BroadcastReceiver smsReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context arg0, Intent arg1) { 
       switch (getResultCode()) { 
       case Activity.RESULT_OK: 
        if (Settings.registrarSucesso) { 
         ... 
        } 
        break; 
       case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
        ... 
        } 
        break; 
       case SmsManager.RESULT_ERROR_NO_SERVICE: 
        ... 
        break; 
       case SmsManager.RESULT_ERROR_NULL_PDU: 
        ... 
        break; 
       case SmsManager.RESULT_ERROR_RADIO_OFF: 
        ... 
        break; 
       } 
       unregisterReceiver(this); 
       adapter.notifyDataSetChanged(); 
      } 
     }; 
0

嘗試

private void sendSMS() 
{ 
    String SENT = "SMS_SENT"; 
    String DELIVERED = "SMS_DELIVERED"; 
    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0); 
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0); 
    SmsManager sms = SmsManager.getDefault(); 
    sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI); 
    sendBroadcastReceiver = new BroadcastReceiver() 
    { 

     public void onReceive(Context arg0, Intent arg1) 
     { 
      switch (getResultCode()) 
      { 
      case Activity.RESULT_OK: 
       Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
       Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_NO_SERVICE: 
       Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_NULL_PDU: 
       Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_RADIO_OFF: 
       Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show(); 
       break; 
      } 
    unregisterReceiver(sendBroadcastReceiver);//add here 
     } 
    }; 

    deliveryBroadcastReceiver = new BroadcastReceiver() 
    { 
     public void onReceive(Context arg0, Intent arg1) 
     { 
      switch (getResultCode()) 
      { 
      case Activity.RESULT_OK: 
       Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show(); 
       break; 
      case Activity.RESULT_CANCELED: 
       Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show(); 
       break; 
      } 
    unregisterReceiver(deliveryBroadcastReceiver);//add here 
     } 

    }; 
registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED)); 
registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT)); 
} 
+0

如果用戶打開「活動」,但不發送短信,會發生什麼情況?此外,並非所有運營商都提供送達報告,如果設備未收到送達報告,則送達Receiver將永不運行。最好是在「Activity」生命週期方法中取消註冊Receiver。 – 2016-06-10 13:21:03

+0

將此代碼添加到sendSMS或sendMMS功能 – 2016-06-11 02:05:53

+0

如果其中任何一個Receiver未運行,您仍然會遇到同樣的問題。正如我所說的,特別是「PendingIntent」的交付可能不會觸發,並且最終會出現問題中描述的完全相同的問題。 – 2016-06-11 02:11:50

0

onCreate & onStop並不總是當你不斷的活動歷史register & unregister最好的地方。您應該將registerReceiver & unregisterReceiver放入onResume & onPause

@Override 
protected void onResume() { 
    registerReceiver(deliveryBroadcastReceiver, new IntentFilter(DELIVERED)); 
    registerReceiver(sendBroadcastReceiver , new IntentFilter(SENT)); 
    super.onResume(); 
} 

@Override 
protected void onPause() { 
    try { 
     unregisterReceiver(sendBroadcastReceiver); 
     unregisterReceiver(deliveryBroadcastReceiver); 
    } catch (IllegalArgumentException ex) { 
     // If Receiver not registered 
    } 
    super.onPause(); 
} 
相關問題