2013-01-18 30 views
5

मेरे पास एंड्रॉइड विगेट्स और विशेष रूप से एंड्रॉइड सेवाओं के बारे में एक सवाल है। यहां मैं यह करना चाहता हूं: फोन पर उपयोगकर्ता को अपना होमस्क्रीन में अपना विजेट जोड़ना चाहिए। विजेट नेटवर्क से अपना डेटा प्राप्त करता है। इस बारे में कुछ ट्यूटोरियल पढ़ने के बाद, मुझे पता चला कि नेटवर्क (टीसीपी सॉकेट) से डेटा प्राप्त करने वाली सेवा बनाने के लिए सबसे अच्छा तरीका होगा और फिर विजेट को लगातार अद्यतन करेगा। यह ScheduledExecutorService के साथ किया जाता है जो एक निश्चित अंतराल में एक रननेबल निष्पादित करता है। रननेबल एक सर्वर से कनेक्ट होगा, डेटा प्राप्त करें और विजेट को अपडेट करना चाहिए)।एंड्रॉइड - नेटवर्क से डेटा के साथ सेवा पर विजेट अद्यतन करें। सर्वश्रेष्ठ दृष्टिकोण?

मेरी समस्या अब है, कि स्क्रीन बंद होने पर विजेट को अद्यतन करने की आवश्यकता नहीं है और इसलिए बैटरी नाली के कारण सेवा नहीं चलनी चाहिए। मेरा सवाल है: इसे सबसे अच्छा तरीका कैसे करें?

मैं 2 दृष्टिकोण जो कम या ज्यादा मैं क्या चाहते हो जाएगा पाया:

  1. विजेट का पहला उदाहरण होमस्क्रीन पर जोड़ा जाता है, यह एक प्रसारण रिसीवर कि ACTION_SCREEN_ON प्राप्त करता है और रजिस्टर करेंगे एंड्रॉइड ओएस से ACTION_SCREEN_OFF इरादा कार्रवाई। यदि ACTION_SCREEN_ON निकाल दिया गया है, तो यह अद्यतनकर्ता सेवा शुरू करेगा, अन्यथा यह इसे रोक देगा। लेकिन अगर मैं प्रसारण रिसीवर जीवनकाल के कारण एक अच्छा दृष्टिकोण है तो मैं वास्तव में अनिश्चित हूं।

  2. अद्यतनकर्ता सेवा के रननेबल में, जिसे शेड्यूल किए गए एक्सेप्टर सेवा द्वारा समय-समय पर निष्पादित किया जाता है और वास्तव में नेटवर्क सामग्री करता है, मैं स्क्रीन चालू होने पर PowerManager.isScreenOn() के माध्यम से जांचता हूं। यदि हां, तो मैं नेटवर्क कोड निष्पादित करता हूं, अन्यथा नहीं। लेकिन डिवाइस कब स्टैंडबाय में है? क्या यह कोड तब निष्पादित किया गया है? यहां बैटरी नाली के बारे में क्या?

क्या मैं शायद जो करना चाहता हूं उसके लिए "सर्वोत्तम अभ्यास" दृष्टिकोण हो सकता है? मैंने अलार्ममेनगर के बारे में बहुत कुछ पढ़ा है और यह एक बहुत शक्तिशाली उपकरण है। क्या आप इस तरीके से कार्यों को शेड्यूल कर सकते हैं, कि डिस्प्ले चालू होने पर उन्हें केवल तभी निष्पादित किया जाता है?

आपकी मदद के लिए धन्यवाद।

बेस्ट सादर NiThDi

+0

क्या आपने [Google क्लाउड मैसेजिंग] (http://developer.android.com/google/gcm/index.html) के बारे में कोई विचार दिया था? इस तरह आपको डेटा के लिए मतदान करने की आवश्यकता नहीं होगी (भले ही डिवाइस केवल जागने के लिए ही हो) और जब आप बदल जाए तो आपको केवल नया डेटा मिलेगा। इसके अलावा जब आप किसी भी प्रारंभिक देरी के बिना उपयोगकर्ता को अपना डिवाइस जगाते हैं तो इसका नवीनतम टुकड़ा प्रदर्शित करने का लाभ प्राप्त होगा। – Audrius

+0

हैलो, तेज़ उत्तर के लिए धन्यवाद। मुझे नहीं लगता कि Google क्लाउड मैसेजिंग जो भी मैं चाहता हूं वह कर सकता हूं। बिंदु (स्पष्ट होने के लिए) है, ऊपर उल्लिखित सर्वर सभी उपयोगकर्ताओं के लिए एक सर्वर नहीं है। यह एक सर्वर अनुप्रयोग है जो अपने कंप्यूटर में चल रहा है। वास्तव में, यह ऐप एक रिमोट कंट्रोल है जो सर्वर से सर्वर पर टीसीपी/आईपी पर लैन में कनेक्ट होता है। – NiThDi

उत्तर

3

आपका पहला समाधान (विजेट से निपटने स्क्रीन चालू और बंद प्रसारण) समस्या पर जाने के लिए रास्ता है। अपने एप्लिकेशन सर्वर पर पृष्ठभूमि संचार के लिए एक नया IntentService प्रारंभ करें। एक बार यह समाप्त हो जाने के बाद, परिणामों के साथ अपना कस्टम "पूर्ण" प्रसारण भेजें और फिर इसे अपने विजेट में संभाल लें।

अतिरिक्त लाभ के रूप में यह आपके विजेट के कई उदाहरणों को एक "स्रोत" से काम करने की अनुमति देगा और यदि उपयोगकर्ता ने कोई विजेट नहीं जोड़ा है तो किसी भी संसाधन का उपभोग नहीं करेगा।

अद्यतन यह एक विजेट के साथ/बंद प्रसारण स्क्रीन का उपयोग करने के लिए असंभव है के रूप में, मैं शायद this (AlarmManager एक ELAPSED_REALTIME (नहीं ELAPSED_REALTIME_WAKEUP) अलार्म के साथ) का उपयोग एक (आशय) सेवा रन शेड्यूल करने के लिए होगा। इस तरह आपकी सेवा स्क्रीन बंद होने पर निर्धारित नहीं की जाएगी, लेकिन जब यह चालू हो तब समय-समय पर चलती है। और यदि स्क्रीन चालू और बंद के बीच की देरी अवधि की अवधि से अधिक है तो यह तुरंत स्क्रीन पर वापस आने पर चलती है।

प्रसारण रिसीवर जीवनकाल के बारे में आपके प्रश्न के लिए, जैसा कि पहले कहा गया था, एक लंबे समय तक चलने वाले कार्य के लिए IntentService का उपयोग करें और फिर अपने परिणामों को वापस प्रसारित करें। जब आप एक सेवा शुरू करते हैं जो कॉल अवरुद्ध नहीं करता है तो प्रसारण रिसीवर समय पर मामला खत्म हो जाएगा।

अद्यतन 2this स्क्रीन ऑफ़ के अनुसार डिवाइस का मतलब यह नहीं है कि डिवाइस सो रहा है। PowerManager.isScreenOn() का उपयोग करके आपके पास पहले से ही इस समस्या का समाधान है।

+0

आपके उत्तर के लिए धन्यवाद। लेकिन प्रसारण रिसीवर जीवन चक्र के बारे में क्या? मुझे पता है कि एक विजेट एक प्रसारण रिसीवर भी है, लेकिन ऐसा लगता है कि AppWidgetProvider को विस्तारित करने वाली कक्षा ACTION_SCREEN_ON/OFF क्रियाएं प्राप्त नहीं कर सकती है। और दुर्भाग्य से यदि मैं एक नया प्रसारण रिसीवर पंजीकृत करता हूं (इसलिए ब्रॉडकास्ट रिसीवर को समाप्त करने वाला एक वर्ग) मैं जीवन भर के बारे में निश्चित नहीं हो सकता। मुझे लगता है कि यह सही है कि एंड्रॉइड किसी भी ब्रॉडकास्ट्रेसीवर को मार सकता है अगर उसे स्मृति की आवश्यकता है ?! – NiThDi

+0

मैं स्क्रीन चालू/बंद चीज़ पर ध्यान नहीं दे रहा था। आप सही हैं, विजेट के साथ इसका उपयोग करना संभव नहीं है। मैं अपना जवाब अपडेट करूंगा। – Audrius

0

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

विजेट onEnabled():

@Override 
public void onEnabled(Context c) { 
    super.onEnabled(c); 

    Intent intent = new Intent(c.getApplicationContext(), SimpleIntentService.class); 

    PendingIntent intentExecuted = PendingIntent.getService(c.getApplicationContext(), 45451894, intent, 
      PendingIntent.FLAG_UPDATE_CURRENT); 

    AlarmManager alarmManager = (AlarmManager) c.getApplicationContext().getSystemService(Context.ALARM_SERVICE); 
    alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, 0, 3000, intentExecuted); 
} 

विजेट onReceive():

SimpleIntentService onHandleIntent():

@Override 
protected void onHandleIntent(Intent intent) { 
    Log.w("TestService", "SimpleIntentService onHandleIntent called."); 
    String msg = new Date().toGMTString(); 

    Intent broadcastIntent = new Intent(); 
    broadcastIntent.setAction(Widget.ACTION_RESP); 
    broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
    broadcastIntent.putExtra("msg", msg); 
    sendBroadcast(broadcastIntent); 
} 

तो, मैंने अपने नेक्सस 4 पर एंड्रॉइड 4.2.1 चलाने और एंड्रॉइड 4.0.4 के साथ एक एमुलेटर पर इसका परीक्षण किया है। दोनों मामलों में SimpleIntentService बनाया जाता है और HandleIntent() को प्रत्येक 3 सेकंड कहा जाता है, भले ही मैं मैन्युअल रूप से डिस्प्ले बंद कर देता हूं। मुझे बिल्कुल पता नहीं है कि अलार्ममेनगर अभी भी अलार्म शेड्यूल क्यों करता है, क्या आपके पास है ?!

धन्यवाद!

+0

[इस] के अनुसार (https://groups.google.com/d/msg/android-developers/Airlo3g5luw/OcLEUW2aq6UJ) स्क्रीन ऑफ का मतलब यह नहीं है कि डिवाइस सो रहा है। 'PowerManager.isScreenOn()' का उपयोग करके आपके पास पहले से ही इस समस्या का समाधान है। – Audrius