2012-08-12 19 views
6

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

मैं क्या करने की कोशिश की:

  • जब मैं डेटा मैन्युअल रूप से बंद कर देते हैं, फिर ऐप्स पर यह हो रहा है और यह
  • मैं भी Wakelock की कोशिश की, लेकिन यह मदद नहीं की काम करता है।
  • अलार्म के रूप में उम्मीद काम करता है, भले ही आपका फ़ोन घंटे

मोटोरोला Atrix एंड्रॉयड 2.3.3 पर परीक्षण किया गया के लिए सोने के लिए चला जाता है। मैं वाईफ़ाई पर भरोसा नहीं कर सकता। वास्तविक जीवन में यह हर हफ्ते सिंक होगा। हम इसे कैसे संभव बना सकते हैं?

AlarmManager:

alarm_manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); 
Intent intent = new Intent(this, AlarmReceiver.class); 
PendingIntent pending = PendingIntent.getBroadcast(this, 0, intent, 
         PendingIntent.FLAG_UPDATE_CURRENT); 
alarm_manager.setRepeating(AlarmManager.RTC_WAKEUP, 
         System.currentTimeMillis(), 15000, pending); 

AlarmReceiver:

public class AlarmReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d("MYTAG", "RECEIVED getMobileDataEnabled: " + getMobileDataEnabled(context)); 
     if (!isOnline(context)) { 
      Log.d("MYTAG", "NO INET"); 
      if (turnOnInet(context)) { 
       Log.d("MYTAG", "INET IS ON"); 
      } 
     } 

     HttpClient httpclient = new DefaultHttpClient(); 
     HttpPost httppost = new HttpPost("http://xxx.xxx.xxx.xxx/ping/pong/moto/"); 
      try { 
       List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); 
       nameValuePairs.add(new BasicNameValuePair("short_code", "ROFL")); 
       httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
       httpclient.execute(httppost); 
       Log.d("MYTAG", "POST FINISHED"); 
      } 
      catch (Exception e) { 
       Log.e("MYTAG", "MYTAG", e); 
      } 
    } 

    public boolean isOnline(Context context) { 
     ConnectivityManager cm = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo netInfo = cm.getActiveNetworkInfo(); 
     if (netInfo != null){ 
      Log.d("MYTAG", "isAvailable: "+netInfo.isAvailable()); 
     } 
     if (netInfo != null && netInfo.isConnectedOrConnecting()) { 
      return true; 
     } 
     return false; 
    } 

    public boolean turnOnInet(Context context) { 
     ConnectivityManager mgr = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); 
     if (mgr == null) { 
      Log.d("MYTAG", "ConnectivityManager == NULL"); 
      return false; 
     } 
     try { 
      Method setMobileDataEnabledMethod = mgr.getClass().getDeclaredMethod("setMobileDataEnabled", boolean.class); 
      if (null == setMobileDataEnabledMethod) { 
       Log.d("MYTAG", "setMobileDataEnabledMethod == null"); 
       return false; 
      }  
      setMobileDataEnabledMethod.invoke(mgr, true); 
     } 
     catch(Exception e) { 
      Log.e("MYTAG", "MYTAG", e); 
      return false; 
     } 
     return true; 
    } 


    private boolean getMobileDataEnabled(Context context) { 
     ConnectivityManager mgr = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); 
     if (mgr == null) { 
      Log.d("MYTAG", "getMobileDataEnabled ConnectivityManager == null"); 
      return false; 
     } 
     try { 
      Method method = mgr.getClass().getMethod("getMobileDataEnabled"); 
      return (Boolean) method.invoke(mgr); 
     } catch (Exception e) { 
      Log.e("MYTAG", "MYTAG", e); 
      return false; 
     } 
    } 
} 

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 
+4

कृपया अपने उपयोगकर्ताओं की बैटरी को न मारें। – SLaks

+0

"वास्तविक जीवन" में यह हर सप्ताह सिंक होगा – programmersbook

+0

क्या आपने RTC_WAKEUP के बजाय आरटीसी ध्वज का उपयोग करने का प्रयास किया है? चूंकि वेकअप को मजबूर नहीं किया जाता है, इसलिए ढांचा नेटवर्क पर स्विच हो जाएगा। चूंकि आप एक सप्ताह में सिंक का उपयोग कर रहे हैं, इसलिए आपको WAKEUP ध्वज – nandeesh

उत्तर

5

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

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

इसके अलावा समय-समय पर सिंक करने का मतलब उपयोगकर्ता डेटा को बर्बाद करने का मतलब है यदि उपयोगकर्ता ऐप का उपयोग नहीं करता है। आखिरकार, यह आपके ऐप को एक बार में हर बार सिस्टम द्वारा बंद करने के लिए सही उम्मीदवार में बदल देता है।

उम्मीद है कि यह मदद करता है। हमें अपनी प्रगति के साथ अद्यतन रखें।

संबंधित पढ़ें: Optimizing downloads for efficient network access

+0

अच्छा बिंदु। साथ ही, नेटवर्क का उपयोग करने वाले अनुकूलित अनुप्रयोगों को लिखने के बारे में लेखों पर नज़र डालें। नेटवर्क हस्तांतरण समूह और कई कनेक्शन हैंडलिंग के बारे में टुकड़े हैं। https://developer.att.com/developer/forward.jsp?passedItemId=7200042 –

15

सबसे पहले, आप प्राप्त करने की आवश्यकता है कि BroadcastReceiver के बाहर और किसी IntentService में HttpPost कोड। कभी भी मुख्य अनुप्रयोग धागे पर नेटवर्क I/O करें, और onReceive() को मुख्य एप्लिकेशन थ्रेड पर कॉल किया जाता है। उदाहरण के लिए, यदि आप बहुत अधिक समय लेते हैं, तो एंड्रॉइड आपके इंटरनेट ऑपरेशन के माध्यम से आपके कोड पार्टवे को समाप्त कर देगा।

दूसरा, IntentService दिया गया, आपको WakeLock का उपयोग करने की आवश्यकता है। यह आपको my WakefulIntentService का उपयोग करने के लिए प्रेरित कर सकता है, जो दोनों समस्याओं को संभालता है। या, WakefulBroadcastReceiver का उपयोग करें, जिसका एक ही उद्देश्य है।

तीसरा, turnOnInet() और getMobileDataEnabled() हटाएं। आपको उनकी आवश्यकता नहीं है, वे अविश्वसनीय हैं, और विशेष रूप से turnOnInet() उपयोगकर्ता-विरोधी है - यदि उपयोगकर्ता मोबाइल डेटा चाहते थे, तो वे इसे चालू कर देते थे।

अब, यह सब अपने IntentService() के अपने onHandleIntent() (या अपने WakefulIntentService के अपने doWakefulWork()) में अगर आपके पास इंटरनेट कनेक्शन अभी नहीं है, यह देखते हुए, एक अस्थायी समाधान, एक पल के लिए SystemClock.sleep() के रूप में और फिर कोशिश करें, एक लूप में कुछ बार दोहराना। यदि आपको लगता है कि आपको थोड़ा सा इंटरनेट एक्सेस मिल रहा है, तो आप अधिक परिष्कृत होने पर विचार कर सकते हैं (उदाहरण के लिए, मतदान के बजाय कनेक्टिविटी परिवर्तन प्रसारण के लिए सुनना, हालांकि यह आपको WakefulIntentService से दूर ले जाएगा और नियमित रूप से Service में आपके स्वयं के पृष्ठभूमि थ्रेड के साथ ड्राइव करेगा और WakeLock प्रबंधन के लिए एक राज्य मशीन)। या, बस sleep() के साथ चिपके रहें - यदि आप कुछ सेकंड के लिए इस पृष्ठभूमि धागे को बांधते हैं तो यह दुनिया का अंत होने की संभावना नहीं है। यदि आपको थोड़ी सी अवधि के बाद कनेक्टिविटी नहीं मिलती है, तो कृपया अनिश्चित काल तक प्रयास न करें, क्योंकि एंड्रॉइड 4.0+ पर उपयोगकर्ता द्वारा संचालित बैंडविड्थ प्रबंधन सहित कई कारण हैं कि आपको कनेक्शन क्यों नहीं मिल सकता है।

+0

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

+1

@ कॉर्डरहेन: डोज़ मोड, शायद। या, यदि डिवाइस में मोबाइल डेटा नहीं है, तो वाईफ़ाई कनेक्शन स्थापित करने में समय लगता है। – CommonsWare

+0

आपके समय के लिए धन्यवाद, मैं अब डोज़ मोड का शोध करूंगा। मैं 10 सेकंड टाइमआउट और 3 सेकंड अंतराल के साथ सफलतापूर्वक Google को पिंग करने के लिए डिवाइस को 3 मिनट दे रहा हूं। मुझे नहीं लगता कि समाधान सिर्फ "लंबा इंतजार" है? –

1

कोई सटीक उत्तर नहीं - लेकिन यह दृष्टिकोण बैटरी जीवन को पूरी तरह से बर्बाद कर देगा। नींद का पूरा बिंदु बैटरी की शक्ति को बचाने के लिए है और यह ऐप ग्राहकों के लिए परेशान होने से ज्यादा कुछ नहीं करेगा इससे कोई फर्क नहीं पड़ता कि विशेषताएं कितनी उपयोगी हैं।

मैं क्या सुझाव दूंगा कि यदि ऐप उपयोग में नहीं है, तो इंटरनेट से कनेक्ट करना बिल्कुल जरूरी है - फोन उठने के लिए एक ट्रिगर सेट करें। यदि यह पूरी तरह से जरूरी नहीं है तो ऐप खोले जाने पर हर बार इंटरनेट से कनेक्ट होने के लिए शायद सबसे अच्छा होगा।

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