简体   繁体   English

Android - 启动时启动服务

[英]Android - Start service on boot

From everything I've seen on Stack Exchange and elsewhere, I have everything set up correctly to start an IntentService when Android OS boots.从我在 Stack Exchange 和其他地方看到的一切来看,我已经正确设置了一切,以便在 Android 操作系统启动时启动 IntentService。 Unfortunately it is not starting on boot, and I'm not getting any errors.不幸的是,它没有在启动时启动,而且我没有收到任何错误。 Maybe the experts can help...也许专家可以帮助...

Manifest:显现:

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

BroadcastReceiver for Startup:用于启动的广播接收器:

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

UPDATE : I tried just about all of the suggestions below, and I added logging such as Log.v("BatteryLogger", "Got to onReceive, about to start service");更新:我几乎尝试了以下所有建议,并添加了日志记录,例如Log.v("BatteryLogger", "Got to onReceive, about to start service"); to the onReceive handler of the StartupIntentReceiver, and nothing is ever logged.到 StartupIntentReceiver 的 onReceive 处理程序,并且没有记录任何内容。 So it isn't even making it to the BroadcastReceiver.所以它甚至没有进入 BroadcastReceiver。

I think I'm deploying the APK and testing correctly, just running Debug in Eclipse and the console says it successfully installs it to my Xoom tablet at \\BatteryLogger\\bin\\BatteryLogger.apk.我想我正在部署 APK 并正确测试,只是在 Eclipse 中运行 Debug 并且控制台说它成功地将它安装到我的 Xoom 平板电脑 \\BatteryLogger\\bin\\BatteryLogger.apk。 Then to test, I reboot the tablet and then look at the logs in DDMS and check the Running Services in the OS settings.然后为了测试,我重新启动平板电脑,然后查看 DDMS 中的日志并检查操作系统设置中的运行服务。 Does this all sound correct, or am I missing something?这一切听起来是否正确,还是我遗漏了什么? Again, any help is much appreciated.再次,非常感谢任何帮助。

Well here is a complete example of an AutoStart Application那么这里是一个自动启动应用程序的完整示例

AndroidManifest file 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服务.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 - This will pop-up everytime you start the device after executing the Applicaton once. 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();
    }
}

Your Service may be getting shut down before it completes due to the device going to sleep after booting.由于设备在启动后进入睡眠状态,您的服务可能会在完成之前关闭。 You need to obtain a wake lock first.您需要先获得唤醒锁。 Luckily, the Support library gives us a class to do this:幸运的是, Support 库为我们提供了一个类来执行此操作:

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 permission:不要忘记添加 WAKE_LOCK 权限:

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

Following should work.以下应该有效。 I have verified.我已经验证过了。 May be your problem is somewhere else.可能是你的问题在其他地方。

Receiver:接收者:

public class MyReceiver extends BroadcastReceiver{

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

Service:服务:

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

Manifest:显现:

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

I have found a way to make your application run well when the device reboots, please follow the steps below to be successful.我找到了一种在设备重新启动时使您的应用程序运行良好的方法,请按照以下步骤成功。

AndroidManifest file 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 UI启动接收器

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

This is asking permission to not need to manage battery saving for this app so you can run in the background stably.这是请求允许不需要管理此应用程序的电池节省,以便您可以在后台稳定运行。

Declare this code in onCreate () of MainActivity class:在 MainActivity 类的 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);

Looks very similar to mine but I use the full package name for the receiver:看起来很像我的,但我用的是全包名的接收器:

<receiver android:name=".StartupIntentReceiver">

I have:我有:

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

I've had success without the full package, do you know where the call chain is getting interrupted?我在没有完整包的情况下取得了成功,您知道调用链在哪里中断吗? If you debug with Log() 's, at what point does it no longer work?如果您使用Log()调试,它在什么时候不再起作用?

I think it may be in your IntentService, this all looks fine.我认为它可能在您的 IntentService 中,这一切看起来都很好。

只是为了使搜索更容易,正如评论中提到的, 这是不可能的,因为 3.1 https://stackoverflow.com/a/19856367/6505257

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM