2013-08-13 4 views
8

मैं एक ऐप लिख रहा हूं जो हेडफोन जैक से ऑडियो का पता लगाता है और जब कुछ ऑडियो शर्तों को पूरा किया जाता है तो विशेष रूप से जब यह एक सहायक ऑडियो डिवाइस के माध्यम से कार्ड स्वाइप करने का पता लगाता है) ।मैं एक सेवा को अनिश्चित काल तक कैसे जीवित रख सकता हूं

मेरे ऐप में कोई गतिविधियां नहीं हैं, यह केवल एक एप्लिकेशन और एक सेवा है।

सब कुछ अच्छी तरह से काम करता है सिवाय इसके कि सेवा अपेक्षाकृत कम समय अवधि (~ एक मिनट) के बाद एंड्रॉइड द्वारा साफ की जाती है।

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

उत्तर

6

मेरा ऐप यह सिर्फ एक आवेदन और एक सेवा है, कोई क्रियाएँ है।

इसका मतलब है कि आपका ऐप किसी भी एंड्रॉइड 3.1+ डिवाइस पर कभी नहीं चलाएगा, जब तक कि आपके पास कुछ अन्य एप्लिकेशन से कुछ टाई न हो जो आपकी सेवा मैन्युअल रूप से लॉन्च करने जा रही है।

मैं एक ऐप लिख रहा हूं जो हेडफोन जैक से ऑडियो का पता लगाता है और जब कुछ ऑडियो शर्तों को पूरा किया जाता है तो विशेष रूप से जब यह एक सहायक ऑडियो डिवाइस के माध्यम से कार्ड स्वाइप करने का पता लगाता है)।

भौगोलिक आकार के बाद अपनी कंपनी का नाम न दें - यह किया गया है। :-)

मुझे उत्सुकता है कि मुझे एंड्रॉइड को यह बताने के लिए क्या करना है कि यह एक उपयोगी सेवा है और इसे इसे अकेले छोड़ देना चाहिए जब तक कि इसे वास्तव में इसकी याददाश्त की आवश्यकता न हो।

आपको startForeground() का उपयोग करने के लिए आपका अग्रभूमि सेवा घोषित करने के लिए आपका स्वागत है। ट्रेडऑफ यह है कि आपको Notification दिखाने की आवश्यकता होगी, आदर्श रूप से उपयोगकर्ता को सेवा को रोकने की अनुमति मिलती है। ध्यान रखें कि उपयोगकर्ता इस Notification की सराहना नहीं कर सकते हैं, लेकिन you are stuck with it, particularly on Android 4.3+। आपको सेवा से किसी गतिविधि में स्विच करके बेहतर सेवा दी जा सकती है, इसलिए उपयोगकर्ता इसे लॉन्च कर सकता है, कार्ड स्वाइप कर सकता है और लेनदेन की प्रक्रिया को संसाधित कर सकता है।

+0

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

+0

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

+0

हाँ, यह सही समझ में आता है। एक बार फिर धन्यवाद। –

0

आप उपयोगकर्ता को सेटिंग, चलने वाली सेवाओं से मैन्युअल रूप से अपनी सेवा को मारने के लिए प्रतिबंधित नहीं कर पाएंगे। डिवाइस प्रशासक के रूप में भी।

आप बूट रिसीवर, स्क्रीन लॉकर और जो भी घटनाएं जोड़ सकते हैं, जो मारे गए सेवा को फिर से लॉन्च करेंगे, और ऐप अगर यह भी होगा यदि आप ऐप के साथ मार डाले गए ध्वज सेटिंग्स के साथ सेवा को फिर से लॉन्च कर सकते हैं उन्नत कार्य हत्यारा।

3

अपनी सेवा को रखने के लिए START_STICKY का उपयोग करें।

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 
     // We want this service to continue running until it is explicitly 
     // stopped, so return sticky. 
     return START_STICKY; 
} 

उदाहरण उपयोग:

http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

अधिक जानकारी:

http://developer.android.com/reference/android/app/Service.html#START_STICKY

1

मैंने अलार्ममेनगर की कोशिश की। यह काम करता हैं। मैंने AlarmReceiver में Contex.startService() का उपयोग किया। और मैं यह जांच सकता हूं कि मेरी सेवा चल रही है ताकि यह तय किया जा सके कि सेवा फिर से शुरू हो गई है या नहीं। तो भले ही मेरी सेवा उपयोगकर्ताओं द्वारा सेटिंग्स में मैन्युअल रूप से बंद हो या कुछ सफाई ऐप द्वारा मारे गए, फिर भी सेवा फिर से शुरू की जा सकती है। नीचे मुख्य कोड यहां दिया गया है।

package com.example.androidnetwork; 

    import android.app.ActivityManager; 
    import android.app.ActivityManager.RunningServiceInfo; 
    import android.app.AlarmManager; 
    import android.app.PendingIntent; 
    import android.content.BroadcastReceiver; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.os.Bundle; 
    import android.support.v7.app.ActionBarActivity; 
    import android.util.Log; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.widget.Button; 

public class MainActivity extends ActionBarActivity { 

    private static final long INTERVAL = 5 * 1000; // unit: ms 

    private Button mRegisterReceiverBtn; 
    private Button mCheckNetStatusBtn; 
    private Button mStopButton; 
    private AlarmManager mAlarmManager; 
    private PendingIntent mPendingIntent; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     initData(); 

     initView(); 
    } 

    private void initData() { 
     mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
    } 

    private void initView() { 
     mRegisterReceiverBtn = (Button) findViewById(R.id.activity_main_start_btn); 
     mCheckNetStatusBtn = (Button) findViewById(R.id.activity_main_start_check_net_status_bnt); 
     mStopButton = (Button) findViewById(R.id.activity_main_stop); 
     mRegisterReceiverBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       MainActivity.this.createServiceControllerPendIntent(); 
       mAlarmManager.setInexactRepeating(
         AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, INTERVAL, 
         mPendingIntent); 
      } 
     }); 
     mCheckNetStatusBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       MainActivity.this.startActivity(new Intent(MainActivity.this, 
         NetStatusActivity.class)); 
      } 
     }); 
     mStopButton.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       if (mPendingIntent != null) { 
        mAlarmManager.cancel(mPendingIntent); 
       } else { 
        createServiceControllerPendIntent(); 
        mAlarmManager.cancel(mPendingIntent); 
       } 
       // MainActivity.this.stopService(ServiceController 
       // .getServiceIntent()); 
       Intent intent = new Intent(); 
       intent.setClass(getApplicationContext(), 
         NetStatusMonitorService.class); 
       stopService(intent); 
      } 
     }); 

    } 

    private void createServiceControllerPendIntent() { 
     Intent intent = new Intent(MainActivity.this, 
       ServiceController.class); 
     mPendingIntent = PendingIntent.getBroadcast(MainActivity.this, 
       0, intent, 0); 
    } 

    @Override 
    protected void onDestroy() { 
     deInitView(); 
     super.onDestroy(); 
    } 

    private void deInitView() { 

    } 


    public static class ServiceController extends BroadcastReceiver { 

     private static Intent sMonitorServiceIntent = null; 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      Log.d("Service Controller", "onReceiver"); 
      if (isServiceRunning(context, NetStatusMonitorService.class) == false) { 
       String info = "starting service by AlarmManager"; 
       Log.d("Service Controller", info); 
       sMonitorServiceIntent = new Intent(context, 
         NetStatusMonitorService.class); 
       context.startService(sMonitorServiceIntent); 
      } 
     } 

      // this method is very important 
     private boolean isServiceRunning(Context context, Class<?> serviceClass) { 
      ActivityManager am = (ActivityManager) context 
        .getSystemService(Context.ACTIVITY_SERVICE); 
      for (RunningServiceInfo serviceInfo : am 
        .getRunningServices(Integer.MAX_VALUE)) { 
       String className1 = serviceInfo.service.getClassName(); 
       String className2 = serviceClass.getName(); 
       if (className1.equals(className2)) { 
        return true; 
       } 
      } 
      return false; 
     } 

     public static Intent getServiceIntent() { 
      return sMonitorServiceIntent; 
     } 
    } 

} 
+0

अलार्ममेनगर स्थिर नहीं है। यदि आप एक दिन में लॉग की जांच करते हैं, तो समय अंतराल 2 मिनट है, आप देखेंगे कि यह लगभग 30 मिनट बंद हो जाता है। – Brave

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