Android - 启动时启动服务

时间:2010-12-30 12:52:43

标签: android autostart bootcompleted

我需要在启动时启动服务。我搜索了很多。他们在谈论Broadcastreceiver。由于我是Android开发的新手,我没有清楚地了解Android上的服务。请提供一些源代码。

9 个答案:

答案 0 :(得分:191)

你的接收者:

public class MyReceiver extends BroadcastReceiver {   

    @Override
    public void onReceive(Context context, Intent intent) {

     Intent myIntent = new Intent(context, YourService.class);
     context.startService(myIntent);

    }
}

您的AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.broadcast.receiver.example"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">

        <activity android:name=".BR_Example"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    <!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
        <receiver android:name=".MyReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>

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

</manifest>

答案 1 :(得分:94)

答案 2 :(得分:32)

  

可以注册您自己的应用程序服务以便启动   设备启动后自动启动。你需要这个,因为   例如,当您想要从http服务器接收推送事件时   想要在新事件发生后立即通知用户。用户没有   必须在服务开始之前手动启动活动...

     

这很简单。首先给你的应用程序许可   项值。接下来,您需要注册BroadcastReveiver。   我们称之为BootCompletedIntentReceiver。

     

你的Manifest.xml现在应该是这样的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.jjoe64">
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
 <application>
  <receiver android:name=".BootCompletedIntentReceiver">
   <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
   </intent-filter>
  </receiver>
  <service android:name=".BackgroundService"/>
 </application>
</manifest>
     

作为最后一步,您必须实施Receiver。这个接收器   刚开始你的后台服务。

package com.jjoe64;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import com.jjoe64.BackgroundService;

public class BootCompletedIntentReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
  if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
   Intent pushIntent = new Intent(context, BackgroundService.class);
   context.startService(pushIntent);
  }
 }
}

来自http://www.jjoe64.com/2011/06/autostart-service-on-device-boot.html

答案 3 :(得分:15)

此处发布的大多数解决方案都缺少一个重要的部分:没有唤醒锁定的情况下运行会导致服务在完成处理之前被杀死的风险。在另一个线程中看到这个解决方案,也在这里回答。

由于在api 26中不推荐使用 WakefulBroadcastReceiver ,因此建议将用于低于26的API级别

您需要获得唤醒锁定。幸运的是,Support library gives us a class要做到这一点:

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

然后,在您的服务中,确保释放唤醒锁:

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

...

<service android:name=".SimpleWakefulReceiver">
    <intent-filter>
        <action android:name="com.example.SimpleWakefulReceiver"/>
    </intent-filter>
</service>

不要忘记添加WAKE_LOCK权限并在清单中注册您的接收者:

import java.util.ArrayList;
import java.util.List;

public class ListADT {
public static void main (String[] args){
    List <String> myList = new ArrayList<String>(); {
    myList.add("A");
    myList.add("B");
    myList.add("C");
    myList.add("D");
    myList.add("E");
System.out.println(myList);}}}

答案 4 :(得分:4)

你应该注册BOOT_COMPLETE以及REBOOT

  <dx:GridViewDataComboBoxColumn FieldName="CartType" PropertiesComboBox-TextField="" VisibleIndex="4" Settings-FilterMode="DisplayText"
                            Width="8%" Settings-AutoFilterCondition="Contains" Caption="Cart Type" PropertiesComboBox-Width="150px"
                            HeaderStyle-Font-Bold="true" CellStyle-HorizontalAlign="Left"
                            PropertiesComboBox-IncrementalFilteringMode="StartsWith" Settings-AllowAutoFilter="True">
                            <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Font-Bold="True" Wrap="True"></HeaderStyle>
                            <CellStyle HorizontalAlign="Left" VerticalAlign="Middle" Wrap="True"></CellStyle>
                            <PropertiesComboBox Width="250px" ValueField="Id" TextField="Type" ValueType="System.Int32" ClientSideEvents-KeyPress="disableenterkey">
                                <ValidationSettings ErrorTextPosition="Bottom" ErrorDisplayMode="Text">
                                    <RequiredField ErrorText="Select Cart Type" IsRequired="true" />
                                </ValidationSettings>
                            </PropertiesComboBox>
                            <EditFormSettings VisibleIndex="2" Caption="Cart Type" />
                        </dx:GridViewDataComboBoxColumn>

答案 5 :(得分:1)

同时在Manifest中注册您创建的服务,并将use-permission注册为

<application ...>
   <service android:name=".MyBroadcastReceiver">
        <intent-filter>
            <action android:name="com.example.MyBroadcastReciver"/>
        </intent-filter>
   </service>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

然后在braod cast Reciever中致电您的服务

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

答案 6 :(得分:0)

首先在manifest.xml文件中注册接收者:

    <receiver android:name="com.mileagelog.service.Broadcast_PowerUp" >
        <intent-filter>
            <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
            <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
        </intent-filter>
    </receiver>

然后为这个接收器写一个广播,如:

public class Broadcast_PowerUp extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();

    if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
        Toast.makeText(context, "Service_PowerUp Started",
                Toast.LENGTH_LONG).show();


    } else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {



        Toast.makeText(context, "Service_PowerUp Stoped", Toast.LENGTH_LONG)
        .show();
    }
  }
}

答案 7 :(得分:0)

要在Android O或更高版本(即OS> 28)中重新启动服务,请使用以下代码 KOTLIN版本 1)在清单中添加权限

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

2)创建一个Class并将其扩展为BroadcastReceiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.core.content.ContextCompat



class BootCompletedReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, arg1: Intent?) {
        Log.d("BootCompletedReceiver", "starting service...")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            ContextCompat.startForegroundService(context, Intent(context, YourServiceClass::class.java))
        } else {
            context.startService(Intent(context, YourServiceClass::class.java))
        }
    }
}

3)在应用标签下声明这样的清单文件

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

答案 8 :(得分:-1)

请检查JobScheduler中26以上的api

WakeLock 是最佳选择,但 api级别26已弃用 如果您认为api级别高于26,请检查this link
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html#startWakefulService(android.content.Context,%20android.content.Intent)

  

从Android O开始,后台检查限制使此类不再普遍有用。 (从广播接收开始启动服务通常是不安全的,因为您不能保证此时您的应用位于前台,因此不能这样做。)相反,开发人员应使用 android.app.job.JobScheduler 来安排作业,这不需要应用程序在执行此操作时保持唤醒锁(系统将为该作业保留唤醒锁)。

正如它所说的cosider JobScheduler
https://developer.android.com/reference/android/app/job/JobScheduler

如果要做的事情比开始并保持下去,您可以接收广播ACTION_BOOT_COMPLETED

如果与前台服务无关,请检查无障碍服务是否可以

另一种选择是从广播接收器启动活动,并在onCreate()中启动服务后完成该活动,因为较新的android版本不允许从接收器启动服务