6

मुझे एक सेवा के बीच संवाद करने के बारे में सवाल और एक गतिविधि का जवाब कई बार दिया गया है, लेकिन मैं इसकी समीक्षा करने का अपना तरीका भी चाहता हूं और यह जानना चाहता हूं कि यह करने के लिए स्वीकार्य और सही तरीका है या नहीं और मैंने इसे कैसे संभाला है इसकी कमी क्या है। सबसे पहले मैं समस्या विवरण बताऊंगा जितना मैं कर सकता हूं।फ़ायरबेस संदेश सेवा और गतिविधि के बीच संवाद कैसे करें? एंड्रॉइड

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

ग्राहक के पक्ष में, ग्राहक अनुरोध के बाद, उन्हें अगली गतिविधि में ले जाया जाता है जहां उन्हें एक प्रकार की लोडिंग स्क्रीन दिखाई दे रही है जो उन्हें ड्राइवरों में से एक के अनुरोध को स्वीकार करने के लिए प्रतीक्षा करने के लिए कह रही है। जब ड्राइवरों में से एक इस उपयोगकर्ता के अनुरोध को स्वीकार करता है, तो इस उपयोगकर्ता को अब पुश अधिसूचना के पेलोड में निर्दिष्ट ड्राइवर की जानकारी के साथ एक फायरबेस पुश अधिसूचना प्राप्त होगी। फिर उद्देश्य किसी भी अधिसूचना उत्पन्न नहीं करना है बल्कि उपकरणों के बीच डेटा स्थानांतरित करना है।

अब जब आप उपयोग के मामले को समझते हैं तो मैं समस्या पर आगे बढ़ जाऊंगा।

समस्या तब उत्पन्न होती है जब उपयोगकर्ता अनुरोध सबमिट करता है और अगली प्रतीक्षा स्क्रीन पर जाता है जहां उसे एक लोडिंग स्क्रीन दिखाई देती है जो उन्हें प्रतीक्षा करने के लिए कहती है जबकि अनुरोध ड्राइवरों द्वारा स्वीकार किए जाने का इंतजार कर रहा है। जब कोई ड्राइवर अनुरोध स्वीकार करता है, जैसा कि मैंने कहा था कि पुश अधिसूचना के पेलोड में ड्राइवर की जानकारी के साथ उपयोगकर्ता को फायरबेस पुश अधिसूचना प्राप्त होगी। लोडिंग स्क्रीन को दिखाने से रोकने के लिए गतिविधि को बताने और पुश अधिसूचना के पेलोड में प्राप्त डेटा के साथ टेक्स्ट व्यू को भरने के लिए मैं सेवा और गतिविधि के बीच संवाद कैसे करूं।

यहां बताया गया है कि मैंने इसे कैसे संभाला है। मान लीजिए कि मेरे पास AwaitingDriver नाम वाली गतिविधि है, जिसमें टेक्स्टव्यू को ड्राइवर के डेटा से भरा जाना है। लेकिन वर्तमान में गतिविधि लोडिंग स्क्रीन दिखा रही है क्योंकि अनुरोध अभी तक स्वीकार नहीं किया गया है। अब उपयोगकर्ता पृष्ठभूमि में चल रही सेवा में ड्राइवर की जानकारी के साथ पुश अधिसूचना प्राप्त करता है, किसी भी तरह से गतिविधि से जुड़ा नहीं है। यहाँ मेरी onMessageReceived विधि

@Override 
    public void onMessageReceived(RemoteMessage remoteMessage){ 
     SharedPreferences rideInfoPref = getSharedPreferences(getString(R.string.rideInfoPref), MODE_PRIVATE); 
     SharedPreferences.Editor rideInfoPrefEditor = rideInfoPref.edit(); 
     String msgType = remoteMessage.getData().get("MessageType"); 
     if (msgType.equals("RequestAccepted")){     
      rideInfoPrefEditor.putBoolean(getString(R.string.is_request_accepted), true); 
      rideInfoPrefEditor.putString(getString(R.string.driver_phone), remoteMessage.getData().get("DriverPhone")); 
      rideInfoPrefEditor.putString(getString(R.string.driver_lat), remoteMessage.getData().get("DriverLatitude")); 
      rideInfoPrefEditor.putString(getString(R.string.driver_lng), remoteMessage.getData().get("DriverLongitude")); 

      rideInfoPrefEditor.commit(); 
      AwaitingDriver.requestAccepted(); // A static method in AwaitingDriver Activity 
     }    
    } 

यहाँ है, AwaitingDriver.requestAccepted()AwaitingDriver गतिविधि का एक स्थिर तरीका है। AwaitingDriver गतिविधि के अंदर, जो ग्राहक को प्रतीक्षा करने के लिए एक प्रगति संवाद दिखा रहा है, यहां विधि AwaitingDriver.requestAccepted() विधि है।

public static void requestAccepted(){ 
    try{ 
     awaitingDriverRequesting.dismiss(); //ProgressDialog for telling user to wait 
    }catch (Exception e){ 
     e.printStackTrace(); 
    }   
    if (staticActivity != null){ 
     staticActivity.new TaskFindSetValues().execute(); 
    } 
} 

यहाँ staticActivityAwaitingDriver गतिविधि वर्ग इस वर्ग के अंदर घोषित की एक स्थिर वस्तु है। मैं अपना मूल्य onResume और विधियों में सेट कर रहा हूं। मतलब है कि गतिविधि सामने है, स्क्रीन पर दिख रही है, केवल तभी staticActivity का मान null नहीं होगा। यहां onResume और विधियां हैं।

@Override 
public void onResume(){ 
    super.onResume(); 
    staticActivity = this; 
    Boolean accepted = rideInfoPref.getBoolean(getString(R.string.is_request_accepted), false); 
    if (accepted){   
     new TaskFindSetValues().execute();    
    } 
} 
@Override 
protected void onPause(){ 
    super.onPause(); 
    staticActivity = null; 
} 

यहाँ, TaskFindSetValues एक AsyncTask AwaitingDriver गतिविधि वर्ग के भीतर परिभाषित किया गया है। यहाँ के लिए TaskFindSetValues

public class TaskFindSetValues extends AsyncTask<String, Void, String>{ 
    String phone; 
    String lat; 
    String lng; 
    @Override 
    protected void onPreExecute(){ 
     SharedPreferences pref = getSharedPreferences(getString(R.string.rideInfoPref), MODE_PRIVATE);    
     phone = pref.getString(getString(R.string.driver_phone), ""); 
     lat = pref.getString(getString(R.string.driver_lat), ""); 
     lng = pref.getString(getString(R.string.driver_lng), ""); 
    } 
    @Override 
    protected String doInBackground(String... arg0){ 
     return null; 
    } 

    @Override 
    protected void onPostExecute(String returnValue){    
     awaitingDriverPhone.setText(phone); //setting values to the TextViews 
     awaitingDriverLat.setText(lat); 
     awaitingDriverLng.setText(lng); 
    } 
} 

कोड इस कोड की समीक्षा करने और मुझे अन्य समाधान के बजाय ऐसा करने का कमियां के बारे में बता और अगर आप भी एक ही उदाहरण के द्वारा सुझाए गए रास्ते समझा सकता है मैं वास्तव में आभारी हैं, तो कृपया है ।

उत्तर

18

आप AsyncTask का उपयोग क्यों कर रहे हैं? समझ में नहीं आता है। वैसे भी, यदि आप गतिविधि के साथ संवाद करना चाहते हैं तो आप इसे BroadcastReceiver के साथ कर सकते हैं।

public class MyFirebaseMessagingService extends FirebaseMessagingService{ 
    private LocalBroadcastManager broadcaster; 

    @Override 
    public void onCreate() { 
     broadcaster = LocalBroadcastManager.getInstance(this); 
    } 

    @Override 
    public void onMessageReceived(RemoteMessage remoteMessage) { 
     Intent intent = new Intent("MyData"); 
     intent.putExtra("phone", remoteMessage.getData().get("DriverPhone")); 
     intent.putExtra("lat", remoteMessage.getData().get("DriverLatitude")); 
     intent.putExtra("lng", remoteMessage.getData().get("DriverLongitude")); 
     broadcaster.sendBroadcast(intent); 
    } 
} 

और आपके गतिविधि में

@Override 
    protected void onStart() { 
     super.onStart(); 
     LocalBroadcastManager.getInstance(this).registerReceiver((mMessageReceiver), 
       new IntentFilter("MyData") 
     ); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); 
    } 

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      awaitingDriverRequesting.dismiss(); 
      awaitingDriverPhone.setText(intent.getExtras().getString("phone")); //setting values to the TextViews 
      awaitingDriverLat.setText(intent.getExtras().getDouble("lat")); 
      awaitingDriverLng.setText(intent.getExtras().getDouble("lng")); 
     } 
    }; 
+0

पंजीकरण के लिए क्या आवश्यकता है? उर्फ, अगर आप पंजीकरण नहीं करते हैं तो क्या होता है? –

+0

FirebaseMessagingService में मेरी ऑनक्रेट विधि कभी नहीं कहा जाता है। कोई विचार क्यों? – eskalera

+0

क्या आपने 'ऑनक्रेट' विधि को ओवरराइड किया था? और जांचें कि क्या आपके पास टाइपो है, विधि का नाम 'ऑनक्रेट() 'पर नहीं है' ऑनक्रेट()' –

2

ऑन मैसेज रीसेसिव विधि में आप ड्राइवर विवरण को स्थानांतरित करने, एप्लिकेशन प्रसारण में भेज सकते हैं। अनुरोध स्वीकृत विधि को प्रसारण रिसीवर द्वारा रिसीव विधि द्वारा प्रतिस्थापित किया जाएगा। इस तरह साझा प्राथमिकताओं को लिखने की आवश्यकता नहीं है या एक सिंकटस्क का उपयोग करने की आवश्यकता नहीं है जो मूल रूप से कुछ भी नहीं कर रहा है क्योंकि डिनबैकग्राउंड विधि सिर्फ शून्य हो जाती है। आप केवल onPreExecute और onPostExecute विधियों का उपयोग कर रहे हैं, जो दोनों मुख्य धागे पर निष्पादित हैं।

+0

मैं AsyncTask इस्तेमाल किया क्योंकि मैं '' requestAccepted() एक स्थिर विधि के माध्यम से गतिविधि के सदस्य चर और TextViews उपयोग नहीं कर सका, लेकिन मैं से मार डाला AsyncTask के माध्यम से कर सकता है स्थैतिक विधि –

0

आप केवल मैसेज रिसीव विधि के भीतर कोई इरादा क्यों नहीं बनाते हैं, गतिविधि को पुनरारंभ करते हैं, और अतिरिक्त में ड्राइवर के डेटा को पास करते हैं?

+0

क्योंकि मैं नहीं चाहता कि ग्राहक गतिविधि को पुनरारंभ कर रहा हो। उपयोग के मामले में ग्राहक वास्तव में लोडिंग स्क्रीन प्रतीक्षा देख रहा है। –

+0

ठीक है, यह समझ में आता है। – Cuculus

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