Trying to start a service on boot on Android

后端 未结 16 1473
慢半拍i
慢半拍i 2020-11-21 06:41

I\'ve been trying to start a service when a device boots up on android, but I cannot get it to work. I\'ve looked at a number of links online but none of the code works. Am

相关标签:
16条回答
  • 2020-11-21 06:59

    How to start service on device boot(autorun app, etc.)

    For first: since version Android 3.1+ you don't receive BOOT_COMPLETE if user never started your app at least once or user "force closed" application. This was done to prevent malware automatically register service. This security hole was closed in newer versions of Android.

    Solution:

    Create app with activity. When user run it once app can receive BOOT_COMPLETE broadcast message.

    For second: BOOT_COMPLETE is sent before external storage is mounted. If app is installed to external storage it won't receive BOOT_COMPLETE broadcast message.

    In this case there is two solution:

    1. Install your app to internal storage
    2. Install another small app in internal storage. This app receives BOOT_COMPLETE and run second app on external storage.

    If your app already installed in internal storage then code below can help you understand how to start service on device boot.


    In Manifest.xml

    Permission:

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

    Register your BOOT_COMPLETED receiver:

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

    Register your service:

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

    In receiver 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);
    
        }
    
     }
    

    For HTC you maybe need also add in Manifest this code if device don't catch RECEIVE_BOOT_COMPLETED:

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

    Receiver now look like this:

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

    How to test BOOT_COMPLETED without restart emulator or real device? It's easy. Try this:

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

    How to get device id? Get list of connected devices with id's:

    adb devices
    

    adb in ADT by default you can find in:

    adt-installation-dir/sdk/platform-tools
    

    Enjoy! )

    0 讨论(0)
  • 2020-11-21 07:00

    In fact,I get into this trouble not long ago,and it's really really easy to fix,you actually do nothing wrong if you setup the "android.intent.action.BOOT_COMPLETED" permission and intent-filter.

    Be attention that if you On Android 4.X,you have to run the broadcast listener before you start service on boot,that means,you have to add an activity first,once your broadcast receiver running,your app should function as you expected,however,on Android 4.X,I haven't found a way to start the service on boot without any activity,I think google did that for security reasons.

    0 讨论(0)
  • 2020-11-21 07:03

    Refer This Link http://khurramitdeveloper.blogspot.in/2013/06/start-activity-or-service-on-boot.html Step by Step procedure to use boot on Service

    0 讨论(0)
  • 2020-11-21 07:03

    As @Damian commented, all the answers in this thread are doing it wrong. Doing it manually like this runs the risk of your Service being stopped in the middle from the device going to sleep. You need to obtain a wake lock first. Luckily, the Support library gives us a class to do this:

    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);
        }
    }
    

    then, in your Service, make sure to release the wake lock:

        @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);
        }
    

    Don't forget to add the WAKE_LOCK permssion to your mainfest:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    
    0 讨论(0)
  • 2020-11-21 07:05

    I have an additional <category>-tag, don't know if that makes any difference.

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

    Have you tried ommiting the if-clause "android.intent.action.BOOT_COMPLETED".equals(intent.getAction(), as the receiver probably only receives that intent anyway?

    0 讨论(0)
  • 2020-11-21 07:08

    This is what I did

    1. I made the Receiver class

    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.in the manifest

    <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.and after ALL you NEED to "set" the receiver in your MainActivity, it may be inside the onCreate

    ...
     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);
    ...
    

    the final steap I have learned from ApiDemos

    0 讨论(0)
提交回复
热议问题