2013-05-01 6 views
8

एंड्रॉइड डिवाइस पर जीसीएम संदेशों के लिए पंजीकरण/पंजीकरण रद्द करते समय मैंने कुछ अजीब व्यवहार देखा है। ग्राहक डिवाइस के नजरिए से निम्नलिखित उपयोग के मामले का निरीक्षण करें:जीसीएम संदेशों के लिए पंजीकरण और पुन: पंजीकरण दो regId वैध होने का कारण बनता है। क्या यह इरादा है?

  1. GCM के लिए रजिस्टर - आईडी एक सौंपा
  2. अपंजीकृत
  3. रजिस्टर GCM के लिए - आईडी बी सौंपा

यदि, चरण 2 के बाद, सर्वर आईडी पर एक संदेश भेजने का प्रयास करता है, तो उसे NotRegistered त्रुटि,प्राप्त होगाऔर उम्मीद है।

लेकिन अब अजीब हिस्सा: चरण 3 के बाद, दोनों आईडी एक और बी मान्य आईडी कर रहे हैं! दोनों आईडी डिवाइस पर इरादे रिसीवर को ट्रिगर करेंगे, जिसके परिणामस्वरूप ऐप में दो संदेश होंगे।

क्या यह व्यवहार निष्पादित है या क्या मैं कुछ गलत कर रहा हूं?

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    unregister(getApplicationContext()); 
    register(getApplicationContext()); 
} 


/** Registers this device for GCM messages */ 
public static void register(Context context) { 
    GCMRegistrar.checkDevice(context); 
    GCMRegistrar.checkManifest(context); 
    String regId = GCMRegistrar.getRegistrationId(context); 
    if (regId.equals("")) { 
     GCMRegistrar.register(context, SENDER_ID); 
    } else { 
     storeRegId(regId); // Also notifies back-end 
    } 
} 

public void unregister(Context context) { 
    GCMRegistrar.unregister(context); 
} 

नोट 1:

यह रजिस्टर और अपंजीकृत करने मेरी कोड, पहली गतिविधि मेरे ऐप्स पर शुरू करने पर onCreate() से शुरू हो रहा है अपंजीकृत मैं केवल शामिल किया है() - डीबगिंग के लिए फोन प्रयोजनों। मेरा ऐप आमतौर पर "जीवन के लिए" के लिए पंजीकृत रहता है (मैं निलंबित और समाप्त होने पर जीसीएम संदेश भी प्राप्त करना चाहता हूं), लेकिन मैं अभी भी इस व्यवहार का कारण जानना चाहता हूं क्योंकि मुझे यकीन नहीं है कि अनियंत्रण एकमात्र मामला है जहां आईडी पुन: उत्पन्न होते हैं। क्या होगा यदि उपयोगकर्ता ऐप को अनइंस्टॉल और पुनर्स्थापित करता है? मुझे बुलेट प्रूफ सिस्टम चाहिए - मेरे उपयोगकर्ताओं को कभी भी एक ही जीसीएम संदेश दो बार प्राप्त नहीं होगा।

नोट 2: सिवाय इसके कि मैं वास्तव में getApplicationContext() के साथ पंजीयन कर रहा हूँ के रूप में इस सवाल का जवाब पता चलता है समस्या, सुंदर similar to this है।

+0

ऐसा लगता है कि ऐसा व्यवहार नहीं होना चाहिए, लेकिन आपके परीक्षण शो होने पर ऐसा होता है। शायद अगर आप प्रतिक्रिया की जांच करते हैं तो जब आप regid ए (अपने वेब पेज से) के साथ संदेश भेजते हैं तो यह क्या हो रहा है पर कुछ प्रकाश डाल सकता है, उदाहरण के लिए यदि एक canonical_id वापस आ गया है। वास्तव में आपको डिवाइस/ऐप संयोजन की पहचान करने के लिए अपनी प्राथमिक कुंजी के लिए कुछ अन्य विशेषता का उपयोग करना चाहिए और अपने डेटाबेस में या LUT केवल उन regIds को रखें जो ठीक प्रतिक्रिया देता है – NickT

+0

क्या आप कुछ पंजीकरण सर्वर पर अपनी पंजीकरण आईडी भेज रहे हैं? –

+0

@nickt ऐसा लगता है कि canonicalId (getCanonicalRegistrationId) यहां कुंजी है - मुझे इसके बारे में पता नहीं था। कॉल में से एक कॉल यहां शून्य लौटाता है जबकि अन्य आईडी आईडी लौटाता है। मैं दोबारा जांच करूँगा और – Nilzor

उत्तर

4
  1. जब आप पंजीकरण नहीं करते हैं, तो आपको अपने सर्वर पर पुरानी पंजीकरण आईडी भेजनी चाहिए और इसे अपने डीबी से हटा देना चाहिए।

  2. आपने चरण 1 करने में नाकाम रही मान लिया जाये, अगर दर्ज की और नए पंजीकरण आईडी प्राप्त करने के बाद आप पुराने पंजीकरण आईडी के साथ एक संदेश भेजने के लिए, Google से प्रतिक्रिया एक विहित पंजीकरण आईडी में शामिल होंगे (जो नए पंजीकरण आईडी है) । यह प्रतिक्रिया इंगित करती है कि आपके सर्वर को पुरानी पंजीकरण आईडी को हटा देना चाहिए और केवल नए का उपयोग करना चाहिए।

+0

वापस प्राप्त करूंगा आप एपीपी से सर्वर पर पुरानी पंजीकरण आईडी कैसे भेजते हैं? GoogleCoudMessaging में कोई तरीका नहीं है जो इसकी अनुमति देता है – Akshay

1

मुझे एक ही समस्या थी, और मेरा मानना ​​है कि मैंने क्या किया है और एक हाइब्रिड समाधान तैयार किया है। दुर्भाग्यवश, यह अभी भी बुलेटप्रूफ नहीं है, हालांकि यह मेरे मामले के लिए काम कर रहा है (बाद में इसके बारे में अधिक)।

यहाँ मैं क्या लगता है कि आप देख रहे हैं:

  • केस 1: आपका 3-पक्ष सर्वर पदों एक GCM पुश संदेश आपके चरण 2 के बाद परंतु चरण 3 से पहले (अर्थातवह मामला जहां आपके सर्वर ने डिवाइस आईडी-ए के लिए एक संदेश भेजा है और प्राप्त नहीं किया गया है)। Google के दस्तावेज़ के अनुसार, आपके जीसीएम डिवाइस क्लाइंट ने बताया है कि संदेश के लिए कॉन्फ़िगर किया गया कोई प्रसारण रिसीवर नहीं है (क्योंकि यह वर्तमान में अनइंस्टॉल किया गया है)। जीसीएम सेवा से यूआर-ए को अपंजीकृत करने का असर पड़ता है, जैसा कि आपने उम्मीद की थी।

    यहां एक SO post है जो इस मामले के लिए जीसीएम अनियंत्रण प्रक्रिया का वर्णन करता है।

  • केस 2: आपका ऐप अनइंस्टॉल किया गया है और अंतराल में जीसीएम पुश संदेश के बिना डिवाइस पर पुनर्स्थापित किया गया है। इस मामले में, एक नई जीसीएम आईडी असाइन की जाती है, लेकिन जीसीएम सेवा को प्रसारण रिसीवर की कमी के बारे में कभी भी सतर्क नहीं किया जाता है, इसलिए दोनों आईडी वैध रहते हैं, और वे दोनों डिवाइस को वितरित करने योग्य होते हैं। यह जीसीएम सेवा द्वारा डुप्लिकेट पंजीकरण_आईडी के रूप में रिपोर्ट किया गया है।

दोनों मामलों में, GCM सेवा समस्या रिपोर्ट कर रहा है, और सफाई के बाद-तथ्य संभाला जा सकता है।

जीसीएम सेवा प्रतिक्रिया के बहुत अच्छे स्पष्टीकरण के लिए यह SO post देखें।

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

अब, मुझे विशेष रूप से उस समाधान को क्यों पसंद नहीं है? कई कारण:

  1. उदाहरण के लिए जो जंगली में पहले से बाहर हैं, वहां कोई माइग्रेशन पथ नहीं है - हमें यह मानना ​​होगा कि जब तक हम अन्यथा नहीं खोज सकें तब तक उन आईडी मान्य रहेंगी। मैं उन्हें अपने जीसीएम आईडी को अपने तृतीय-पक्ष सर्वर के साथ फिर से पंजीकृत करने के लिए मजबूर नहीं कर सकता हूं, ऐप अपडेट (जिसे मैं मजबूर नहीं कर सकता) के अलावा।
  2. उन उपकरणों कि एक ऐप अपडेट से गुजरते हैं लिए, वे अपने DeviceID और मेरे 3-पक्ष सर्वर पर वर्तमान GCM आईडी संचारित कर सकते हैं, लेकिन वे किसी भी आईडी कि हो सकता है की स्थापना रद्द करें के माध्यम से खो दिया गया है पता नहीं है/चक्र फिर से स्थापित करें। यह वास्तव में उन "खोए" आईडी हैं जो भविष्य में परेशानी पैदा कर सकते हैं - लेकिन केवल एक बार यदि आप उपरोक्त उस SO लिंक में वर्णित सेवा फ़ीडबैक का उपयोग करते हैं।
  3. एक अद्वितीय डिवाइस निर्धारित करना आईडी स्वयं ही समस्याग्रस्त है। अद्वितीय एंड्रॉइड डिवाइस आईडी के बारे में StackOverflow चर्चाओं के लिए बस Google ...
संबंधित मुद्दे