在后台永远运行服务 - Android

时间:2016-05-07 15:41:30

标签: android

我在我的Android应用程序中创建了一个Service,它在BOOT_COMPLETEBroadcastReceiver上自动启动。这工作得非常好。但是这个服务执行我在onCreate()方法中定义的任务,只执行一次。另一方面,我想在后台永远运行Service。实际上在onCreate()方法内部,我正在从我的数据库中读取数据,如果需要,我正在生成通知。并且可以随时生成通知,因此我希望永远运行我的服务。我是Android的新手,我见过可能的例子&教程,但他们没有帮助。如此友好地回答我怎样才能永远地运行Service

这是服务代码:

package com.example.abc.project1;

import android.app.*;
import android.content.Intent;
import android.os.IBinder;
import android.util.*;
import org.json.*;
import java.io.*;
import java.net.*;
import java.util.*;


public class HelloService extends Service {

    private static final String TAG = "HelloService";
    public static boolean isRunning  = false;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }


    @Override
    public void onCreate() {
        isRunning = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                /*Here I want to do my task forever (reading from database & generate notifications)*/
            }
        }).start();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        isRunning = false;
    }

}

这是BroadcastReceiver的代码

package com.example.abc.project1;

import android.content.*;
import android.util.Log;

public class MyBroadcastreceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent startServiceIntent = new Intent(context, HelloService.class);
        context.startService(startServiceIntent);
    }
}

这是AndroidManifest.xml的一部分

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.abc.project1">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gef.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_COARSE_CATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <service android:name=".HelloService"></service>

        <receiver android:name="com.example.abc.project1.MyBroadcastreceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <data android:scheme="package" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

    </application>

</manifest>

5 个答案:

答案 0 :(得分:3)

非常简单 步骤:
1.创建一个服务类 2.创建 BroadcastReceiver
3.在 onDestroy 服务方法中调用 BroadReceiver 4.再次 BroadReceiver 类启动服务的 onReceive 方法。
refer this link

答案 1 :(得分:2)

根据Service documentation

  

此服务将在此时继续运行,直到调用Context.stopService()或stopSelf()。

因此,您的服务将永远运行,直到系统因为缺乏资源而无法决定杀死它。

答案 2 :(得分:2)

所以有 2 种方法来实现这一目标

1. 重新启动 onTaskRemoved 中的服务并带有 startService(new Intent(this, <your.class>))
警告onCreate 将被调用一次
< br/>2.使用 startForeground(NOTIFICATION_ID, notification) 在 Android N 之上定位,这样服务不会被停止,如果使用任何广播接收器也不会被杀死(首选方式)。

@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground() {
    NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, getClass().getSimpleName(), NotificationManager.IMPORTANCE_NONE);
    chan.setLightColor(Color.WHITE);
    chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);

    notifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notifManager.createNotificationChannel(chan);

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
    Notification notification = notificationBuilder.setOngoing(true)
            .setContentTitle("App is running in background")
            .setPriority(NotificationManager.IMPORTANCE_MIN)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build();
    startForeground(NOTIFICATION_ID, notification);
}


对于底层 API

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
   startMyOwnForeground();
} else {
   startForeground(NOTIFICATION_ID, new Notification());
}

答案 3 :(得分:0)

在onStartCommand中编写处理程序代码。但请记住,当设备进入&#34;睡眠模式&#34;。

时,您的服务将暂停

答案 4 :(得分:0)

根据文档。

由于您的服务被终止:

  

Android系统在内存不足时仅停止服务,并且必须为具有用户焦点的活动恢复系统资源。

只要不满足上述条件,您的服务将永远运行。