2012-06-06 14 views
5

को अनधिकृत करने की आवश्यकता है मैंने हाल ही में भेजे गए एसएमएस की स्थिति की जांच करने के बारे में एक प्रश्न पूछा और उत्तर दिया गया एक कोड स्निपेट था जो दो 'अज्ञात आंतरिक' पंजीकृत था (कृपया गलत होने पर मेरी शब्दावली को सही करें) BroadcastReceivers एसएमएस भेजे गए/वितरित प्रसारण सुनने के लिए। इन रिसीवरों को केवल मेरे आवेदन को भेजे गए एसएमएस के बारे में डेटा प्राप्त करने की आवश्यकता थी, इसलिए स्थायी रूप से सुनने की आवश्यकता नहीं थी।क्या मुझे 'अज्ञात' ब्रॉडकास्ट रिसीवर

मेरा तत्काल विचार था "ठीक है, मुझे उनके साथ समाप्त होने के बाद उन्हें पंजीकरण रद्द करने की आवश्यकता होगी", लेकिन क्या यह सही है? मैंने पोस्टर से यह पूछा क्योंकि उसने कोई पंजीकरण रद्द नहीं किया था, लेकिन कोई जवाब नहीं मिला। यह कोड ऐसा करने का एक सुंदर मानक तरीका प्रतीत होता है जो मैं चाहता हूं क्योंकि यह कई एंड्रॉइड देव साइटों पर दिखाई देता है। यहां यह है:

//---sends an SMS message to another device--- 
private 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); 

    //---when the SMS has been sent--- 
    registerReceiver(new BroadcastReceiver(){ 
     @Override 
     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(){ 
     @Override 
     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); 

कोड ठीक काम करता है।

और भी, यह मेरे ऐप के बाहर होने वाले किसी भी एसएमएस भेजे गए/वितरित ईवेंट की अधिसूचना नहीं दी जाती है। जैसे मैं BroadcastReceivers पंजीकृत होने के बाद एक एसएमएस भेज सकता हूं और Toast संदेशों को नहीं देख सकता हूं।

  1. मैं इन BroadcastReceivers अपंजीकृत करने की जरूरत है:

    तो, मैं दो प्रश्न हैं?

  2. यदि नहीं, तो क्यों नहीं?

उत्तर

0

आपको पंजीकरण रद्द करने की आवश्यकता होगी। अन्यथा, यह शायद सबसे अधिक दुर्घटनाग्रस्त हो जाएगा। मुझे इसके बारे में काफी यकीन है। लेकिन अगर आप कहते हैं कि यह क्रैश नहीं हो रहा है, तो, इसे देखने की आवश्यकता है :)

क्योंकि, एंड्रॉइड सोचता है कि आप पंजीकरण रद्द करना भूल गए हैं। यह आपको अपंजीकृत करने की उम्मीद करता है। "नोट: यदि आपकी गतिविधि में रिसीवर पंजीकृत करना है .ऑन्यूज़्यूम() कार्यान्वयन, आपको इसे Activity.onPause() में अनियंत्रित करना चाहिए। (जब आप रोके गए हैं तो आपको इरादे प्राप्त नहीं होंगे, और यह अनावश्यक सिस्टम ओवरहेड पर कट जाएगा)। Activity.onSaveInstanceState() में पंजीकरण रद्द करें, क्योंकि उपयोगकर्ता को इतिहास स्टैक में वापस ले जाने पर यह नहीं कहा जाएगा। " डॉक्स

+0

आपको ऐसा क्यों लगता है कि इसे दुर्घटनाग्रस्त होना चाहिए? – barry

+0

मेरा जवाब अपडेट किया गया। –

+0

ठीक है, कोड एक अलग ब्रॉडकास्ट रिसीवर (अलार्ममेनगर द्वारा जागृत) में है, इसलिए मेरे पास अपंजीकरण करने के लिए कोई जीवन चक्र विधि नहीं है। यदि आवश्यक हो तो मैं अनियंत्रित iReceive() को समाप्त कर दूंगा, यदि आवश्यक हो तो – barry

1

से < ===== बस अपने BroadcastReceiver एक उदाहरण के लिए सहेजें ताकि आप ;-)

बस से इस लाइन को बदलने का पंजीकरण रद्द करने में सक्षम हैं:

registerReceiver(new BroadcastReceiver(){ 

रहे हैं:

BroadcastReceiver smsReceiver=new BroadcastReceiver(){...} 
registerReceiver(smsReceiver); 

बाद में आप निष्पादित कर सकते हैं की तुलना में:

unregisterReceiver(smsReceiver); 

बस वर्ग सदस्य के रूप में smsReceiver को सहेजना याद रखें।

+0

मुझे नहीं लगता कि मुझे ब्रॉडकास्ट रिसीवर को एक उदाहरण में सहेजने की आवश्यकता होगी - यदि आवश्यक हो तो मैं ऑनसेसिव() के अंत में पंजीकरण रद्द कर सकता हूं। मैं सिर्फ यह जानना चाहता हूं कि यह आवश्यक है या नहीं। जैसा कि मैंने कहा, यह कोड इंटरनेट के चारों ओर बिखरा हुआ है, बिना पंजीकरण के चल रहा है! – barry

0

तो अगर मैं समझता हूँ कि तुम क्या लिखा है सही ढंग से, ऐसा लगता है BroadcastReceiver केवल sendSMS() कॉल के भीतर मौजूद होना चाहिए, इसलिए भले ही वे SENT या DELIVERED उद्देश्य के लिए पंजीकृत हैं, वे चारों ओर उन्हें प्राप्त करने के लिए नहीं हो सकता है लग रहा है। साथ ही, मेरा मानना ​​है कि जब आप उनके साथ काम करते हैं तो आप हमेशा रिसीवर को अपंजीकृत करना चाहते हैं, मैंने डीबगर को रिसीवर लीक करने के बारे में चेतावनी दी है।

यह अगर तुम sent_broadcast_receiver और delivered_broadcast_receiver कि रिसीवर आप पंजीकृत कर रहे हैं के लिए एक संदर्भ है, इस तरह की वस्तुओं जारी रहती शामिल की तरह के लिए वर्ग मानकों था बेहतर काम करेंगे, और अपंजीकृत हो सकता है के बाद वे किया जाता है।

संपादित करें: जो भी वस्तु SENT और DELIVERED के लिए BroadcastReceivers रखती जारी रहती है चाहिए जब तक उद्देश्य लौटने, या उद्देश्य (क्योंकि वे PendingIntents कर रहे हैं) कुछ है कि, उठ जा सकता है अगर है कि तुम क्या इच्छा है के लिए भेजा जाना चाहिए।

+0

एसएमएस ब्रॉडकास्ट रिसीवर एक अलग ब्रॉडकास्ट रिसीवर में बनाए जाते हैं जिसे अलार्ममेनगर द्वारा कहा जाता है - यानी एक अलार्म होता है और मैं एक एसएमएस भेजना चाहता हूं ताकि ब्रॉडकास्ट रिसीवर में कोड स्निपेट निष्पादित कर सकें जो अलार्ममेनर के साथ पंजीकृत था। आप रिसीवर को इस रिसीवर में चर के रूप में संग्रहीत करने का सुझाव देते हैं ताकि वे बने रहें, लेकिन अगर प्रसारण होता है तो अलार्म रिसीवर आसपास नहीं होता है? क्या मुझे एक सेवा चाहिए? – barry

+0

मैं अलार्ममेनगर के साथ पंजीकरण करने के लिए, लेकिन "नए ब्रॉडकास्ट रिसीवर" रचनाकारों के लिए पंजीकरण नहीं कर रहा था। असल में, आपके कोड में अलार्ममेनर के साथ कोई पंजीकरण नहीं प्रतीत होता है। यह एसईएनटी और डिलीवर के लिए दो लंबित संकेत बनाता है, उन उद्देश्यों के लिए रजिस्ट्रार विधि स्कोप ब्रॉडकास्ट रिसीवर प्रदान करता है और फिर SmsManager का उपयोग करता है। –

+0

मुझे खेद है, लेकिन आपका संपादन मुझे समझ में नहीं आता है - "... या इरादे (क्योंकि वे लंबित हैं) इसलिए ऐसा कुछ भी है जो जागृत हो सकता है, अगर आप यही चाहते हैं।" क्या आप आगे बता सकते हैं? – barry

1

और भी, यह मेरे ऐप के बाहर होने वाले किसी भी एसएमएस भेजे गए/वितरित ईवेंट की अधिसूचना नहीं दी जाती है।

आप गतिशील रूप से रिसीवर पंजीकृत कर रहे हैं। यदि आप अन्य अनुप्रयोगों से इरादों को सुनना चाहते हैं, तो आपको अपने रिसीवर को मैनिफेस्ट फ़ाइल में पंजीकृत करना होगा। इस तरह यह हमेशा सक्रिय रहेगा। और आपको इसे अपंजीकृत करने की आवश्यकता नहीं होगी।

संबंधित मुद्दे