एंड्रॉइड पर बूट पर एक सेवा शुरू करने की कोशिश कर रहा है


332

जब कोई डिवाइस एंड्रॉइड पर बूट करता है, तो मैं एक सेवा शुरू करने की कोशिश कर रहा हूं, लेकिन मैं इसे काम नहीं कर सकता। मैंने ऑनलाइन कई लिंक देखे हैं लेकिन कोई भी कोड काम नहीं करता है। क्या मैं कुछ भूल रहा हूँ?

AndroidManifest.xml

<receiver
    android:name=".StartServiceAtBootReceiver"
    android:enabled="true"
    android:exported="false"
    android:label="StartServiceAtBootReceiver" >
    <intent-filter>
        <action android:name="android.intent.action._BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<service
    android:name="com.test.RunService"
    android:enabled="true" />

प्रसारण प्राप्तकर्ता

public void onReceive(Context context, Intent intent) {
    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
        Intent serviceLauncher = new Intent(context, RunService.class);
        context.startService(serviceLauncher);
        Log.v("TEST", "Service loaded at start");
    }
}

2
मुझे पता नहीं है कि मैंने क्या किया, लेकिन मुझे लगता है कि यह अब काम करता है यह हो सकता है कि एंड्रॉइड: अनुमति = "android.permission.RECEIVE_BOOT_COMPLETED" रिसीवर के लिए
एलेक्स

क्या आपने <कार्रवाई एंड्रॉइड में अतिरिक्त "_" की जाँच की है: name = "android.intent.action._BOOT_COMPLETED" />
OneWorld

निर्यात सही होना चाहिए ताकि सिस्टम रिसीवर को चालान कर सके, नहीं? या यह डिफ़ॉल्ट रूप से सही है?
यूजेन पिसेंक सेप

ओरियो के लिए, यहां देखें: stackoverflow.com/questions/44502229/…
एंडी वेनस्टेन

जवाबों:


601

अन्य उत्तर अच्छे लगते हैं, लेकिन मुझे लगा कि मैं सब कुछ एक पूर्ण उत्तर में लपेट दूंगा।

आपको अपनी AndroidManifest.xmlफ़ाइल में निम्नलिखित की आवश्यकता है :

  1. आपके <manifest>तत्व में:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  2. अपने <application>तत्व में ( अपने लिए पूरी तरह से योग्य [या रिश्तेदार] वर्ग नाम का उपयोग करना सुनिश्चित करें BroadcastReceiver):

    <receiver android:name="com.example.MyBroadcastReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
    

    (आप की जरूरत नहीं है android:enabled, exportedआदि,, गुण: एंड्रॉयड चूक सही हैं)

    इन MyBroadcastReceiver.java:

    package com.example;
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent startServiceIntent = new Intent(context, MyService.class);
            context.startService(startServiceIntent);
        }
    }
    

मूल प्रश्न से:

  • यह स्पष्ट नहीं है अगर <receiver>तत्व में था <application>तत्व
  • यह स्पष्ट नहीं है कि BroadcastReceiverनिर्दिष्ट के लिए सही पूरी तरह से योग्य (या रिश्तेदार) वर्ग का नाम क्या है
  • में एक टाइपो था <intent-filter>

2
यह अच्छा लग रहा है। मैं इसे एक आधार के रूप में उपयोग करने वाला हूं, धन्यवाद :)। । कोई सही का निशान या upvotes या उदासी प्रतिक्रिया :( कोई भी इस की पुष्टि?
Nanne

51
बस एक पूरक: सुनिश्चित करें कि आपका ऐप आंतरिक मेमोरी में स्थापित है <प्रकट xmlns: android = "..." package = "..." android: installLocation = "internalOnly">
Bao Le

2
एंड्रॉइड जेलीबीन में 4.2.2 <रिसीवर> टैग में मुझे सेवा शुरू करने के लिए पूरी तरह से योग्य नाम के बजाय वर्ग के सापेक्ष नाम का उपयोग करना था, जैसा कि stackoverflow.com/questions/16671619/…
PioDzanzan

6
यदि रिसीवर को अलग-अलग सामान के लिए उपयोग किया जाता है: <br> यदि ("android.intent.action.BOOT_COMPLETED" .equals (इरादे .getAction ())) {इरादे सेवाभारत = नया इरादा (संदर्भ, सेवा_आवेदन); // i.putExtra ("KEY1", "सेवा द्वारा उपयोग किए जाने वाले मूल्य"); context.startService (serviceIntent); }
गुन्नार बर्नस्टीन 10

2
आपको इसके बजाय developer.android.com/reference/android/support/v4/content/… का विस्तार करना चाहिए । यह ब्रॉडकास्टसीवर को लागू करने के सामान्य पैटर्न के लिए एक हेल्पर है जो एक डिवाइस वेकअप इवेंट प्राप्त करता है और फिर एक सेवा के लिए काम बंद कर देता है, यह सुनिश्चित करते हुए कि डिवाइस संक्रमण के दौरान सोने के लिए वापस नहीं जाता है। यह वर्ग आपके लिए एक आंशिक वेक लॉक बनाने और प्रबंधित करने का ध्यान रखता है; आपको इसे उपयोग करने के लिए WAKE_LOCK अनुमति का अनुरोध करना चाहिए।
डेमियन

84

अतिरिक्त जानकारी के रूप में: बाहरी संग्रहण माउंट होने से पहले BOOT_COMPLETE को अनुप्रयोगों को भेजा जाता है। इसलिए यदि एप्लिकेशन बाहरी संग्रहण में स्थापित है, तो इसे BOOT_COMPLETE प्रसारण संदेश प्राप्त नहीं होगा।

"ब्राड पूर्ण" के लिए सुनने वाले सेक्शन ब्रॉडकास्ट रिवर्स में अधिक जानकारी यहाँ दी गई है


उपरोक्त समस्या को रोकने के लिए, डेवलपर ऐप के लिए "Android: installLocation =" internalOnly "को मैनिफ़ेस्ट में सेट कर सकता है। क्या यह एक बुरा विचार है? एक स्मार्टफ़ोन ऐप के लिए, यदि सभी उपयोगकर्ताओं के 99.9% (मेरा अनुमान) ऐप को सामान्य रूप से इंस्टॉल करते हैं , बाहरी भंडारण के बजाय आंतरिक भंडारण का उपयोग करके, तो ऐसा लगता है कि "आंतरिक" इसके अलावा प्रकट ठीक होगा। मैं इस पर आपके द्वारा दिए गए किसी भी विचार या विचारों की सराहना करता हूं।
AJW

69

डिवाइस बूट (ऑटोरन ऐप, आदि) पर सेवा कैसे शुरू करें

पहले के लिए: एंड्रॉइड 3.1+ संस्करण के बाद से आपको BOOT_COMPLETE प्राप्त नहीं होता है यदि उपयोगकर्ता ने कभी भी अपना ऐप कम से कम एक बार शुरू नहीं किया है या उपयोगकर्ता "बल बंद" एप्लिकेशन नहीं करता है। यह मालवेयर को स्वचालित रूप से रजिस्टर सेवा को रोकने के लिए किया गया था। यह सुरक्षा छेद Android के नए संस्करणों में बंद कर दिया गया था।

समाधान:

गतिविधि के साथ ऐप बनाएं। जब उपयोगकर्ता इसे चलाएगा तो एक बार एप्लिकेशन BOOT_COMPLETE प्रसारण संदेश प्राप्त कर सकता है।

दूसरे के लिए: बाहरी संग्रहण माउंट होने से पहले BOOT_COMPLETE भेजा जाता है। यदि एप्लिकेशन बाहरी संग्रहण में स्थापित है, तो इसे BOOT_COMPLETE प्रसारण संदेश प्राप्त नहीं होगा।

इस मामले में दो समाधान है:

  1. अपने ऐप को इंटरनल स्टोरेज में इंस्टॉल करें
  2. आंतरिक भंडारण में एक और छोटा ऐप इंस्टॉल करें। यह ऐप BOOT_COMPLETE को प्राप्त करता है और बाहरी स्टोरेज पर दूसरा ऐप चलाता है।

यदि आपका ऐप पहले से ही इंटरनल स्टोरेज में इंस्टॉल है तो नीचे दिया गया कोड आपको यह समझने में मदद कर सकता है कि डिवाइस बूट पर सर्विस कैसे शुरू करें।


मेनिफेस्ट.एक्सएमएल में

अनुमति:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

अपना BOOT_COMPLETED रिसीवर पंजीकृत करें:

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

अपनी सेवा पंजीकृत करें:

<service android:name="org.yourapp.YourCoolService" />

रिसीवर OnBoot.java में:

public class OnBoot extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // Create Intent
        Intent serviceIntent = new Intent(context, YourCoolService.class);
        // Start service
        context.startService(serviceIntent);

    }

 }

अगर आपको डिवाइस RECEIVE_BOOT_COMPLETED नहीं पकड़ना है तो HTC के लिए शायद आपको इस मेनिफेस्ट में भी जोड़ना होगा:

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

रिसीवर अब इस तरह दिखता है:

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

पुनः आरंभ एमुलेटर या वास्तविक डिवाइस के बिना BOOT_COMPLETED का परीक्षण कैसे करें? यह आसान है। इसे इस्तेमाल करे:

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED

डिवाइस आईडी कैसे प्राप्त करें? आईडी के साथ जुड़े उपकरणों की सूची प्राप्त करें:

adb devices

एडीबी में डिफ़ॉल्ट रूप से एडीबी आप पा सकते हैं:

adt-installation-dir/sdk/platform-tools

का आनंद लें! )


आपका पहला पैराग्राफ कैपिटल था। मैं इसे अपने डिबगर में चलाने में असमर्थ था।
एस्टेर्न

34

साथ में

<action android:name="android.intent.action.BOOT_COMPLETED" />  

इसका भी प्रयोग करें,

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

HTC डिवाइस BOOT_COMPLETED को पकड़ने के लिए प्रतीत नहीं होते हैं


HTC उपकरणों के लिए अनुमतियों में कुछ समान जोड़ने की आवश्यकता है?
नंद

2
यह कुछ परिस्थितियों में उपयोगी हो सकता है, लेकिन मैं समझता हूं कि एचटीसी फास्ट बूट हाइबरनेशन का एक रूप है जहां सिस्टम स्टेट को फाइल सिस्टम में सहेजा जाता है, और android.intent.action.QUICKBOOT_POWERONइसे केवल तभी भेजा जाता है जब फास्ट बूट से रिस्टोर किया जाता है। इसका मतलब यह है कि फास्ट बूट से ठीक होने पर अलार्म को रीसेट करने जैसे काम करना जरूरी नहीं है क्योंकि वे संरक्षित हैं। इसलिए यह केवल तभी उपयोग <action android:name="android.intent.action.QUICKBOOT_POWERON" />करना आवश्यक होगा जब आप कुछ करना चाहते हैं जब उपयोगकर्ता को लगता है कि डिवाइस ने बूट किया है।
HexAndBugs

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

@HexAndBugs क्या आप इस बात की पुष्टि करने में सक्षम थे कि फास्ट बूट हाइबरनेशन का एक रूप है जहां सिस्टम स्टेट को फाइल सिस्टम में सहेजा जाता है? मैं एक तेज़ बूट के बाद भविष्य की अधिसूचनाओं के लिए उपयोग किए जाने वाले अलार्म को रीसेट करने में सक्षम होना चाहता हूं यदि सिस्टम स्टेट सहेजा नहीं गया है ... कृपया सलाह दें।
AJW

20

ध्यान दें कि प्रश्न की शुरुआत में, टाइपो गलती है:

<action android:name="android.intent.action._BOOT_COMPLETED"/>

के बजाय :

<action android:name="android.intent.action.BOOT_COMPLETED"/>

एक छोटा "_" और यह सब परेशानी :)


13

मुझे अभी पता चला है कि यह > Fast Bootमें विकल्प के कारण हो सकता हैSettingsPower

जब मेरे पास यह विकल्प बंद हो जाता है, तो मेरा आवेदन इस प्रसारण को प्राप्त करता है, लेकिन अन्यथा नहीं।

वैसे, मेरे पास Android 2.3.3है HTC Incredible S

आशा है ये मदद करेगा।


मुद्दे का निश्चित रूप से संभव कारण। Android 4.0.3 पर चलने वाले HTC Desire C पर भी गौर किया गया है।
जेलिमीर

12

मुझे लगता है कि आपकी उपस्थिति को जोड़ने की आवश्यकता है:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

मुझे भी यही समस्या हो रही है। क्या आपको मेरी मदद करने में कोई आपत्ति है? धन्यवाद! stackoverflow.com/questions/35373525/starting-my-service
रुचिर बैरन

7

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


5

मेरे पास एक अतिरिक्त <category>-टैग है, पता नहीं कि क्या इससे कोई फर्क पड़ता है।

<receiver android:name="BootIntentReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
            <category android:name="android.intent.category.HOME" />  
        </intent-filter>  
</receiver>

क्या आपने इफ-क्लॉज को ommiting करने की कोशिश की है "android.intent.action.BOOT_COMPLETED".equals(intent.getAction(), क्योंकि रिसीवर को शायद वैसे भी केवल यही इरादा मिलता है?


यह कोशिश की और यह काम नहीं किया btw मैं उल्लेख करना भूल गया मैं भी <का उपयोग करता है-अनुमति Android: नाम = "android.permission.RECEIVE_BOOT_COMPLETED" />
एलेक्स

2
बस के मामले में: Android.intent.category में जोड़ें। AndroidManifest में किसी भी टैग के लिए, संगतता मोड को बंद करने के लिए हैक का उपयोग करने के बाद भी, संगतता मोड में ऐप को चलाने के लिए सैमसंग गैलेक्सी टैब का कारण होगा। सुनिश्चित नहीं है कि यह अन्य टैब के लिए समान है। मैं अनुशंसा करता हूं कि गृह श्रेणी को बिल्कुल भी सेट न करें। यह अनावश्यक है।
चाँदनीचेय


3

बाहरी संग्रहण को माउंट करने से पहले BOOT_COMPLETE को निष्‍पादन भेजा जाता है। यदि आपका ऐप बाहरी संग्रहण में स्‍थापित है, तो इसे BOOT_COMPLETE प्रसारण संदेश नहीं मिलेगा। इसे रोकने के लिए आप अपने एप्लिकेशन को आंतरिक संग्रहण में स्थापित कर सकते हैं। आप इसे सिर्फ menifest.xml में इस लाइन को जोड़कर कर सकते हैं

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="internalOnly"
... >

कुछ एचटीसी डिवाइस एक "तेज़ बूट" सुविधा को सक्षम कर सकते हैं जो एक गहरी हाइबरनेशन की तरह है और एक वास्तविक रिबूट नहीं है और इसलिए BOOT_COMPLETE इरादा नहीं देना चाहिए। इसे पुनर्प्राप्त करने के लिए आप अपने रिसीवर के अंदर यह आशय फ़िल्टर जोड़ सकते हैं:

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>

जैसा कि आप सुझाव देते हैं, उपरोक्त समस्या को रोकने के लिए, डेवलपर किसी ऐप के लिए "android: installLocation =" internalOnly "सेट कर सकता है। क्या यह एक बुरा विचार है? स्मार्टफ़ोन ऐप के लिए, यदि सभी उपयोगकर्ताओं के 99.9% (मेरा अनुमान)। बाहरी भंडारण के बजाय आंतरिक भंडारण का उपयोग करके, सामान्य रूप से एप्लिकेशन इंस्टॉल करें, फिर ऐसा लगता है कि "आंतरिक" इसके अलावा प्रकट ठीक होगा। मैं इस पर आपके द्वारा किए गए किसी भी विचार या विचारों की सराहना करता हूं। - AJW
AJW

3

यह जो मैंने किया है

1. मैंने रिसीवर वर्ग बनाया

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //whatever you want to do on boot
       Intent serviceIntent = new Intent(context, YourService.class);
       context.startService(serviceIntent);
    }
}

2. प्रकट में

<manifest...>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application...>
        <receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    ...

3. और सब के बाद आप अपने MainActivity में रिसीवर को "सेट" करना चाहते हैं, यह ऑनक्रिएट के अंदर हो सकता है

...
 final ComponentName onBootReceiver = new ComponentName(getApplication().getPackageName(), BootReceiver.class.getName());
        if(getPackageManager().getComponentEnabledSetting(onBootReceiver) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
        getPackageManager().setComponentEnabledSetting(onBootReceiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
...

अंतिम स्टेप मैंने ApiDemos से सीखा है


2

यदि आप एंड्रॉइड स्टूडियो का उपयोग कर रहे हैं और आप ऑटो-पूर्ण के बहुत शौकीन हैं तो मुझे आपको सूचित करना चाहिए, मैं एंड्रॉइड स्टूडियो वी 1.1.0 का उपयोग कर रहा हूं और मैंने निम्नलिखित अनुमति के लिए ऑटो-पूर्ण का उपयोग किया है

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

और एंड्रॉइड स्टूडियो ऑटो RECEIVE_BOOT_COMPLETEDकम-केस में सभी को पूरा करता है receive_boot_completedऔर मैं अपने बालों को बाहर खींचता रहता हूं क्योंकि मैं बूट के लिए सेवा शुरू करने के लिए चीजों के लिए अपनी चेकलिस्ट को पहले ही बाहर कर चुका हूं। मैंने फिर से पुष्टि की

Android Studio निचले-मामले में इस अनुमति को स्वतः पूर्ण करता है।


2

जैसा कि @Damian ने टिप्पणी की, इस धागे के सभी उत्तर गलत हैं। इसे इस तरह से मैन्युअल रूप से करने से आपकी सेवा का जोखिम बीच में ही रुक जाता है जिससे डिवाइस सोने जा रही है। आपको पहले एक वेक लॉक प्राप्त करना होगा। सौभाग्य से, समर्थन पुस्तकालय हमें ऐसा करने के लिए एक वर्ग देता है :

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Intent service = new Intent(context, SimpleWakefulService.class);

        // Start the service, keeping the device awake while it is launching.
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);
    }
}

फिर, अपनी सेवा में, वेक लॉक जारी करना सुनिश्चित करें:

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point SimpleWakefulReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.

...
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }

अपने मेनफेस्ट में WAKE_LOCK परमिट जोड़ना न भूलें:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

छोटा सा सवाल मुझे संदेह है। अगर मेरी सेवा एक सेवा है और न कि IntentService मैं इस तरह का उपयोग नहीं कर सकता, क्योंकि onHandleIntend विधि सरल सेवा में ओवरराइड नहीं हो सकती है ?
पाओलो 2988

मुझे भी यही समस्या हो रही है। क्या आपको मेरी मदद करने में कोई आपत्ति है? धन्यवाद! stackoverflow.com/questions/35373525/starting-my-service
रुचिर बैरन

शायद उपयोग करें onNewIntent()? या आप IntentService के स्रोत को देख सकते हैं और देख सकते हैं कि आपको अपनी सेवा के लिए इसे मैच करने के लिए क्या करना होगा ...
phreakhead

1

वास्तव में, मैं इस समस्या में बहुत पहले नहीं मिला हूं, और इसे ठीक करना वास्तव में आसान है, आप वास्तव में कुछ भी गलत नहीं करते हैं यदि आप "android.intent.action.BOOT_COMPLETED"अनुमति और इरादे को फ़िल्टर करते हैं।

ध्यान रखें कि यदि आप एंड्रॉइड 4.X पर हैं, तो आपको बूट पर सेवा शुरू करने से पहले आपको प्रसारण श्रोता को चलाना होगा, इसका मतलब है, आपको पहले एक गतिविधि जोड़ना होगा, एक बार आपके प्रसारण रिसीवर के चलने के बाद, आपका ऐप आपकी अपेक्षा के अनुरूप कार्य करना चाहिए, हालाँकि, एंड्रॉइड 4.X पर, मुझे बिना किसी गतिविधि के बूट पर सेवा शुरू करने का तरीका नहीं मिला है, मुझे लगता है कि सुरक्षा कारणों से Google ने ऐसा किया।


0

मुझे इस समस्या का सामना करना पड़ा अगर मैं रिसीवर क्लास में खाली कंस्ट्रक्टर को छोड़ दूं। खाली कॉन्ट्रैक्टर को हटाने के बाद OnRreceive methos ने ठीक काम करना शुरू कर दिया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.