簡體   English   中英

在后台永遠運行服務 - Android

[英]Running a Service forever in background - Android

我在我的 android 應用程序中創建了一個Service ,它通過BroadcastReceiverBOOT_COMPLETE自動啟動。 這工作得很好。 但是這個服務只執行一次我在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>

根據服務文檔

此時服務將繼續運行,直到 Context.stopService() 或 stopSelf() 被調用。

因此,您的服務將永遠運行,直到系統不會因為缺乏資源而決定終止它。

這很簡單。
步驟:
1.創建一個Service類。
2.創建一個BroadcastReceiver
3.在服務的onDestroy方法中調用BroadReceiver
4.在BroadReceiver類的onReceive方法中再次啟動服務。
參考這個鏈接

所以有兩種方法可以實現這一點

1.用startService(new Intent(this, <your.class>))重啟onTaskRemoved的服務
警告onCreate將被調用一次

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

在 onStartCommand 中編寫處理程序代碼。 但請記住,當設備進入“睡眠模式”時,您的服務將暫停。

根據文檔。

您的服務被終止的原因:

Android 系統在內存不足時停止服務,並且必須為具有用戶焦點的活動恢復系統資源。

因此,只要不滿足上述條件,您的服務就會永遠運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM