Android никогда не заканчивается Сервис - PullRequest
0 голосов
/ 19 октября 2018

Я знаю, что есть много вопросов и ответов по этой теме, но, несмотря на это, я не могу реализовать бесконечную задачу, которая выполняется на устройстве Android 7.0.Он отлично работает на эмуляторе (с использованием API уровня 24), но не на реальном устройстве (Xiaomi Redmi Note 4, Android 7.0 NRD90M).Например, в эмуляторе, когда я закрываю приложение, методы LocationUpdateService.onDestroy и AutoStartLocationUpdate.onReceive вызываются должным образом, как и ожидалось.Но на реальном устройстве нет.

Или я должен вместо этого использовать какой-то другой подход, например Alarm Manager?

Кто-нибудь, пожалуйста, дайте мне несколько советов?Спасибо

Вот моя реализация:

Служба:

package com.ivan.archangel;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.Timer;
import java.util.TimerTask;

public class LocationUpdateService extends Service {

    private Timer timer;

    @Override
    public void onCreate() {
        super.onCreate();
        timer = new Timer();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i("Ivan", "tick");
            }

        }, 0, 1000);
        Log.i("Ivan", "Timer started");
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        timer.cancel();
        Log.i("Ivan", "Timer stopped");

        Intent broadcastIntent = new Intent("Hahaha");
        getApplicationContext().sendBroadcast(broadcastIntent);
    }

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

}

BroadcastReceiver

package com.ivan.archangel;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class AutoStartLocationUpdate extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("Ivan", "Restarting LocationUpdateService...");
        context.startService(new Intent(context, LocationUpdateService.class));
        Log.i("Ivan", "Restarted LocationUpdateService");
    }

}

Манифест:

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".Home"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id" />

        <activity
            android:name="com.facebook.FacebookActivity"
            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name" />
        <activity
            android:name="com.facebook.CustomTabActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="@string/fb_login_protocol_scheme" />
            </intent-filter>
        </activity>

        <service
            android:name=".LocationUpdateService"
            android:enabled="true"
            android:stopWithTask="false"/>

        <receiver
            android:name=".AutoStartLocationUpdate"
            android:enabled="true"
            android:exported="true"
            android:label="RestartServiceWhenStopped">
            <intent-filter>
                <action android:name="Hahaha" />
                <!--<action android:name="android.intent.action.BOOT_COMPLETED" />-->
            </intent-filter>
        </receiver>
        <receiver
            android:name=".SMSReceiver"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter android:priority="5822">
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps"></activity>
    </application>

</manifest>

1 Ответ

0 голосов
/ 19 октября 2018

Вы также можете внедрить Forground Service , позвонив startForeground() в onStartCommand вашего Service class

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {


    // your code

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
        .setContentTitle("Print Server running..")
        .setContentText("")
        .setTicker("")
        .setContentIntent(pendingIntent);
    Notification notification = builder.build();
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
    }
    startForeground(Integer.parseInt(NOTIFICATION_CHANNEL_ID), notification);.
} 

Ссылки

Ограничение обслуживания DOC

Ссылка для разработчиков Google

Внедрение службы Foreground

...