在设备重启时重新启动服务

3

我有一个带服务的程序,如果我重新启动设备,该服务也应该重新启动。但是只有在模拟器上才能正常运行,如果我在真机上尝试,该服务根本无法启动。

有人知道我做错了什么或者为什么它只能在模拟器上工作吗?

BroadcastReviever:

@Override
public void onReceive(Context context, Intent intent) {
    //we double check here for only boot complete event
    if(intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED))
    {
        //here we start the service
        Intent serviceIntent = new Intent(context, UploadService.class);
        context.startService(serviceIntent);
    }
}

Manifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
    tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="Upload FTP"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <receiver
        android:name=".BootCompletedIntentReceiver"
        android:enabled="true"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>


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

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter  >
    </activity>

    <service
        android:name=".UploadService"
        android:isolatedProcess="false"
        android:exported="true"
        android:enabled="true"/>
</application>

模拟器的API版本为23,真实设备的API版本为27。 我正在构建一个最小API级别为23,最大API级别为27的应用程序。

编辑

现在我也尝试了使用模拟器和Android API 27运行程序,当我启动我的程序然后重新启动模拟器时,模拟器不再启动。一旦模拟器启动,它就开始无限重启。(真实设备正常启动,只是不会重新启动服务)


1
你可能想要分享你支持的Android API级别,以及模拟器和真实设备在这方面的区别。你做了什么调试?你的接收器是否被调用了? - user1531971
1
请编辑问题并提供详细信息,就像在问题正文中所述。评论可以删除,因为SO不是一个线程论坛。您还应该告诉我们您正在构建的最小和最大API级别。 - user1531971
尝试使用 FireBase Job Dispatcher 来使用 jobservice。 - prashant17
你至少可以在你的接收器和其他地方加入一些日志记录以了解运行时行为。 - user1531971
看看这个帖子。https://dev59.com/W2sz5IYBdhLWcg3wv6ju#7690600 你会注意到他们在他们的AndroidManifest文件中两次使用了android:permission="android.permission.RECEIVE_BOOT_COMPLETED"。它至少可以引导你走上正确的路径。祝好运! - luckyging3r
显示剩余6条评论
3个回答

2

尝试使用LOCKED_BOOT_COMPLETED接收器,如下所示:

<receiver
android:name=".BootReceiver"
android:directBootAware="true"
android:exported="false">
<intent-filter>
    <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
    <!-- For pre-N devices -->
    <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

不要忘记权限

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

点击这里了解更多关于直接启动在Android Nougat的解释。


我的设备上服务仍然无法启动,对我来说不起作用。 - user12346352
有时候你必须等待几秒钟。 - maheryhaja
我等了大约一分钟,但服务并没有重新启动。 - user12346352
你有没有其他解决方案来解决我的问题?因为即使我等几分钟,服务也无法在真实设备上启动。 - user12346352
你有设置 directBootAware = "true" 吗? - maheryhaja
是的,我也已经将“directBootAware =“true””放入了代码中,但是它并没有起作用。这个问题只出现在API 27及更高版本上,在其他API上它能正常工作。 - user12346352

1

现在我自己解决了,比我想象的要容易。

public class BootCompletedIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

    Intent i=new Intent(context, YourClass.class);

    if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
        context.startForegroundService(i);
    }
    else {
        context.startService(i);
    }

}

0

如果我不使用完整的URI,我就会遇到一些奇怪的问题,

例如.BootCompletedIntentReceiver会变成com.company.BootCompletedIntentRecevier

我知道这听起来很蠢,但是在现代SDK中,如果不明确声明清楚Manifest上的事情,我就会遇到许多奇怪的回归问题。


谢谢你的帮助,但是我已经通过我回答中提供的代码解决了问题。 - user12346352

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接