Android - बूट पर सेवा शुरू करें


107

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

मैनिफ़ेस्ट:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.phx.batterylogger"
  android:versionCode="1"
  android:versionName="1.0"
  android:installLocation="internalOnly">

<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <service android:name=".BatteryLogger"/>
    <receiver android:name=".StartupIntentReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
</application>

</manifest>

स्टार्टअप के लिए ब्रॉडकास्टरीवर:

package com.phx.batterylogger;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class StartupIntentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent serviceIntent = new Intent(context, BatteryLogger.class);
        context.startService(serviceIntent);
    }
}

अद्यतन करें : मैंने नीचे दिए गए सभी सुझावों के बारे में कोशिश की, और मैंने लॉगिंग को जोड़ा जैसे Log.v("BatteryLogger", "Got to onReceive, about to start service");कि StartIIntentReceiver के ऑनरिविव हैंडलर, और कुछ भी कभी लॉग नहीं किया गया है। तो यह ब्रॉडकास्टसीवर को भी नहीं बना रहा है।

मुझे लगता है कि मैं एपीके और टेस्ट को सही ढंग से तैनात कर रहा हूं, बस डिबग इन एक्लिप्स चला रहा हूं और कंसोल कहता है कि यह सफलतापूर्वक इसे मेरे एक्सओम टैबलेट में \ BatteryLogger \ bin \ BatteryLogger.apk पर स्थापित करता है। फिर परीक्षण करने के लिए, मैं टैबलेट को रिबूट करता हूं और फिर डीडीएमएस में लॉग को देखता हूं और ओएस सेटिंग्स में रनिंग सर्विसेज की जांच करता हूं। क्या यह सब सही है, या मुझे कुछ याद आ रहा है? फिर, किसी भी मदद की बहुत सराहना की है।


1
आपको क्या समस्या हो रही है, क्या आपको कोई UI नहीं मिल रहा है ..?
ललित पोपटानी

1
सेवा बस कभी शुरू नहीं होती है, यही समस्या है।
गीडिऑक्ट

आपको कैसे पता चलेगा कि आपकी सेवा शुरू नहीं हो रही है, क्या आपने लॉग या ऐसा कुछ भी मुद्रित किया है ..?
बजे ललित पोपटानी

1
आपको इसकी नहीं चलने के लिए लॉग की आवश्यकता नहीं है। Android OS चल रही सेवाओं को उजागर करता है। हालांकि, यह देखने के लिए लॉगिंग का उपयोग करना बुद्धिमान होगा कि क्या कोई त्रुटि हो रही है। मैं एक अनुमान लगाता हूं कि अगर यह एक त्रुटि हो रही है, तो reference.startService () से पहले होता है।
टोनी

1
मैंने Log.v("BatteryLogger", "Got to onReceive, about to start service");onReceive हैंडलर में जोड़ा , और यह लॉग में कभी नहीं दिखा। तो श्रोता असफल हो रहा है (?)
Gady

जवाबों:


302

वैसे यहाँ एक AutoStart Application का पूरा उदाहरण है

AndroidManifest फ़ाइल

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pack.saltriver" android:versionCode="1" android:versionName="1.0">

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

    <application android:icon="@drawable/icon" android:label="@string/app_name">

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

        <activity android:name=".hello"></activity>
        <service android:enabled="true" android:name=".service" />
    </application>
</manifest>

autostart.java

public class autostart extends BroadcastReceiver 
{
    public void onReceive(Context context, Intent arg1) 
    {
        Intent intent = new Intent(context,service.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
        Log.i("Autostart", "started");
    }
}

service.java

public class service extends Service
{
    private static final String TAG = "MyService";
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    public void onDestroy() {
        Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public void onStart(Intent intent, int startid)
    {
        Intent intents = new Intent(getBaseContext(),hello.class);
        intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intents);
        Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
        Log.d(TAG, "onStart");
    }
}

hello.java - यह एक बार जब आप एप्लिकेशन को एक बार एप्लिकेशन को निष्पादित करने के बाद डिवाइस को शुरू करेंगे तो पॉप-अप हो जाएगा।

public class hello extends Activity 
{   
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Toast.makeText(getBaseContext(), "Hello........", Toast.LENGTH_LONG).show();
    }
}

10
पूर्ण उदाहरण के लिए +1। हो सकता है कि मैं अपने इरादे को एक पुरानी पुरानी सेवा के साथ onHandleIntent में बदल दूं
Gady

6
यह अंततः इसे हल कर दिया। यह समस्या मेरी सेवा के संयोजन के रूप में सादा पुरानी सेवा के बजाय एक IntentService होने के कारण थी और सेवा कोड में त्रुटियाँ थीं। इस उत्तर की संपूर्णता और एंड्रॉइड में लॉग इन करने से मुझे अपने मुद्दों को हल करने में मदद मिली।
गेदी

3
विस्तृत उदाहरण के लिए +1। क्या यह भी एक गतिविधि के बिना काम करेगा?
बाला

1
onStart () कॉलबैक पदावनत है। आपको इसके बजाय onStartCommand () का उपयोग करना चाहिए।
एमएमबी

1
@mmBs का जवाब लगभग 5 साल पुराना है, इसलिए इसका स्पष्ट
ललित पोपटानी

3

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

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" />

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

2

काम करना चाहिए। मैंने सत्यापित किया है। हो सकता है आपकी समस्या कहीं और हो।

public class MyReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("TAG", "MyReceiver");
        Intent serviceIntent = new Intent(context, Test1Service.class);
        context.startService(serviceIntent);
    }
}




public class Test1Service extends Service {
    /** Called when the activity is first created. */
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("TAG", "Service created.");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("TAG", "Service started.");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.d("TAG", "Service started.");
    }
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}




<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test"
      android:versionCode="1"
      android:versionName="1.0"
      android:installLocation="internalOnly">
    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BATTERY_STATS" 
    />
<!--        <activity android:name=".MyActivity">
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER"></category> 
            </intent-filter>
       </activity> -->
        <service android:name=".Test1Service" 
                  android:label="@string/app_name"
                  >
        </service>
        <receiver android:name=".MyReceiver">  
            <intent-filter>  
                <action android:name="android.intent.action.BOOT_COMPLETED" /> 
            </intent-filter>  
        </receiver> 
    </application>
</manifest>

इसके लिए धन्यवाद, लेकिन यह अभी भी काम नहीं किया। लॉग यह दिखाने के लिए भी नहीं है कि यह StartupIntentReceiver को बनाता है। कोई अन्य विचार?
गादी

1
क्या आपका कोड एमुलेटर में काम कर रहा है? क्या आप एमुलेटर में आशय प्राप्त कर सकते हैं?
विवेक

मैंने एमुलेटर में परीक्षण किया और मुझे डीडीएमएस में एक त्रुटि मिलती है, लेकिन ऐसा लगता है कि कम से कम सेवा शुरू करने का प्रयास कर रहा है, हालांकि मेरा कोई भी Log()बयान नहीं है और एमुलेटर डिवाइस ओएस सेटिंग्स में चलने के रूप में मेरी सेवा नहीं दिखाता है। यहाँ System.err - at com.phx.batterylogger$1.onReceive(BatteryLogger.java:43)DDMS में त्रुटि है: क्या इसका मतलब यह है कि समस्या मेरी BatteryLogger सेवा की लाइन 43 पर है?
Gady

2

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

AndroidManifest फ़ाइल

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pack.saltriver" android:versionCode="1" android:versionName="1.0">
<uses-permission 
android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <receiver android:name=".UIBootReceiver" android:enabled="true" 
    android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
     <service android:name=".class_Service" />
</application>

UIBootReceiver

public class UIBootReceiver extends BroadcastReceiver {

private static final String TAG = "UIBootReceiver";
@Override

    public void onReceive(Context context, Intent arg1)
    {
        Toast.makeText(context, "started", Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(context,class_Service.class);
        context.startService(intent);
    }
  }

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

इस कोड को मुख्यता वर्ग के onCreate () में घोषित करें:

   Intent myIntent = new Intent();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        myIntent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        myIntent.setData(Uri.parse("package:" + 
   DeviceMovingSpeed.this.getPackageName()));
    }
    startActivity(myIntent);

1

मेरे जैसा ही दिखता है, लेकिन मैं रिसीवर के लिए पूर्ण पैकेज नाम का उपयोग करता हूं:

<receiver android:name=".StartupIntentReceiver">

मेरे पास है:

<receiver android:name="com.your.package.AutoStart"> 

हाँ, यह आपकी समस्या को हल करने के लिए थोड़ा सा था, इसलिए बेहतर ढंग से एक हैलो वर्ल्ड उदाहरण पोस्ट किया।
ललित पोपटानी

1

मुझे पूर्ण पैकेज के बिना सफलता मिली है, क्या आप जानते हैं कि कॉल चेन कहां बाधित हो रही है? यदि आप डीबग करते हैं Log(), तो किस बिंदु पर यह अब काम नहीं करता है?

मुझे लगता है कि यह आपके इरादे में हो सकता है, यह सब ठीक लग रहा है।


मैंने Log.v("BatteryLogger", "Got to onReceive, about to start service");onReceive हैंडलर में जोड़ा , और यह लॉग में कभी नहीं दिखा। तो श्रोता असफल हो रहा है (?)
Gady

फ़ोन के बूट होने पर ब्रॉडकास्ट रिसीवर क्या शुरू करता है? धन्यवाद!
रुचिर बरोनिया

लड़का। मैंने कुछ वर्षों में Android को नहीं छुआ है। क्षमा करें @ रुचिर
फिक्स

0

बस खोज को आसान बनाने के लिए, जैसा कि टिप्पणियों में बताया गया है, यह 3.1 के बाद से संभव नहीं है। https://stackoverflow.com/a/19856367/650h257


यह सच नहीं है, जैसा कि थिंक ट्वाइस कोड द्वारा कहा गया है, एक ही जवाब के टिप्पणी अनुभाग में एक बार
रिकार्डो ए।

मेरे तर्क का समर्थन करने के लिए एक अधिक विस्तृत विवरण: stackoverflow.com/questions/20441308/…
रिकार्डो ए।

यह वास्तव में बहुत समय है क्योंकि मैं एंड्रॉइड के साथ कुछ भी कर रहा हूं, लेकिन आप सही हैं, यह संभव है। कोई अन्य तर्क आवश्यक नहीं है। (मैं जवाब संपादित करूंगा)
MrKew
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.