簡體   English   中英

Android廣播接收器被調用但不啟動前台服務

[英]Android broadcast reciever called but doesn't starts foreground service

我設置了廣播接收器以在重新啟動后重新啟動我的前台服務。

我有兩台設備,它適用於Meizu M1 note (android 5.1)但不適用於Samsung A8 (android 9) Oreo之后尋找限制的原因,似乎沒問題,但以防萬一https://developer.android.com/about/versions/oreo/background.html

在第二個廣播接收器上調用,但重啟后服務未啟動。

服務跟蹤位置並使用startForeground()Notification進行正確的工作。 還嘗試添加Worker以在重新啟動后重新啟動服務,但此后似乎工作丟失。

請提出任何建議,為什么我的接收器不運行服務。

謝謝。

顯現:

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

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:name=".ui.di.App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:isolatedProcess="true"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <receiver android:name="com.example.tracker.ui.broadcast.ServiceRestart">
            <intent-filter>
                <action android:name="restartService" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <service
            android:name="com.example.tracker.ui.service.TrackerService"
            android:enabled="true" />

        <service
            android:name="com.example.tracker.ui.worker.RestartIntentService"
            android:enabled="true" />


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

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

    </application>

</manifest>

接收器:

public class ServiceRestart extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("Broadcast Listened", "Service tried to stop");
        Toast.makeText(context, "Broadcast: ServiceRestart launched " + intent.getAction(), Toast.LENGTH_LONG).show();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(new Intent(context, TrackerService.class));
        } else {
            context.startService(new Intent(context, TrackerService.class));
        }
    }
}

服務:

public class TrackerService extends Service implements LocationListener {

    public static final String TAG = "TrackerService";

    private static final int PROCESS_ID = 1024;

    private static final int INTERVAL = 120; //seconds

    private ConnectivityManager connectivityManager;

    private PeriodicWorkRequest workRequest;
    private PeriodicWorkRequest restartTrackerRequest;

    private DbFirebaseModel dbFirebaseModel = new DbFirebaseModel();

    private ServiceHandler mServiceHandler;

    private static final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message message) {
        }
    }

    public void onCreate() {
        super.onCreate();

        HandlerThread mHandlerThread = new HandlerThread("TrackerService.HandlerThread");
        mHandlerThread.start();

        mServiceHandler = new ServiceHandler(mHandlerThread.getLooper());
    }

    public TrackerService() {
        super();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        addNotificationAndStartForeground();

        addWorkers();

        mServiceHandler.post(() -> {
            connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            runLocationTransfer();
        });

        Log.d(TAG, "===== SERVICE START");

        return START_STICKY;
    }

    private void addWorkers() {

        workRequest = new PeriodicWorkRequest.Builder(
            FirebaseWorker.class, 15, TimeUnit.MINUTES, 2, TimeUnit.MINUTES)
            .build();
        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
            FirebaseWorker.TAG,
            ExistingPeriodicWorkPolicy.REPLACE,
            workRequest);

        restartTrackerRequest = new PeriodicWorkRequest.Builder(
            TrackerRestartWorker.class, 15, TimeUnit.MINUTES, 2, TimeUnit.MINUTES
        ).build();
        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
            TrackerRestartWorker.TAG,
            ExistingPeriodicWorkPolicy.REPLACE,
            restartTrackerRequest);

    }

    private void addNotificationAndStartForeground() {
        String name = getString(R.string.app_name);
        String description = "Service running...";
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

        Notification.Builder notificationBuilder;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                Integer.toString(PROCESS_ID), "Tracker", NotificationManager.IMPORTANCE_HIGH);
            channel.setDescription("Notify me when location tracking");

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);

            notificationBuilder = new Notification.Builder(this, Integer.toString(PROCESS_ID));
            notificationBuilder.setContentTitle(name)
                .setContentText(description)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentIntent(pendingIntent);

            notificationManager.notify(PROCESS_ID, notificationBuilder.build());
        } else {
            notificationBuilder = new Notification.Builder(this);
            notificationBuilder.setContentTitle(name)
                .setContentText(description)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentIntent(pendingIntent);
        }

        startForeground(PROCESS_ID, notificationBuilder.build());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        Log.d(TAG, "===== SERVICE STOP");

        if (FirebaseAuth.getInstance().getCurrentUser() == null) {
            WorkManager.getInstance(this).cancelWorkById(workRequest.getId());
            WorkManager.getInstance(this).cancelWorkById(restartTrackerRequest.getId());
            Log.d(TAG, "===== WORKERS STOP");
        }
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.d(TAG, "TASK REMOVED");
        Toast.makeText(this, "LOCATION TASK REMOVED", Toast.LENGTH_SHORT).show();

        super.onTaskRemoved(rootIntent);
    }

    private void runLocationTransfer() {

        LocationRequest locationRequest = new LocationRequest();
        locationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);

        locationRequest.setInterval(INTERVAL * 1000);
        locationRequest.setFastestInterval(INTERVAL * 1000);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(locationRequest);
        LocationSettingsRequest locationSettingsRequest = builder.build();

        SettingsClient settingsClient = LocationServices.getSettingsClient(this);
        settingsClient.checkLocationSettings(locationSettingsRequest);

        try {
            getFusedLocationProviderClient(this).requestLocationUpdates(locationRequest, new LocationCallback() {
                    @Override
                    public void onLocationResult(LocationResult locationResult) {
                        onLocationChanged(locationResult.getLastLocation());
                    }
                },
                Looper.myLooper());

        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void onLocationChanged(@NonNull Location location) {

        if (FirebaseAuth.getInstance().getCurrentUser() == null) {
            stopSelf();
            Log.d(TAG, "====== SERVICE STOPPED by itself");
        } else if (connectivityManager.getActiveNetworkInfo() != null
            && connectivityManager.getActiveNetworkInfo().isConnected()) {

            dbFirebaseModel.saveLocation(location);

            // test using sound notifications
            try {
                Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
                r.play();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Toast.makeText(this, "LOCATION ------ LATITUDE: " + location.getLatitude() + " LONGITUDE: " + location.getLongitude(), Toast.LENGTH_SHORT).show();

        } else {
            saveToLocalStorage(location);
        }
    }


    private void saveToLocalStorage(Location location) {
        Hawk.init(this).build();

        String userId = Objects.requireNonNull(
            FirebaseAuth.getInstance().getCurrentUser()
        ).getUid();

        LocationData locationData = new LocationData(userId, location);

        long count = 0;
        if (Hawk.count() > count) {
            count = Hawk.count();
        }

        while (Hawk.contains(String.valueOf(count))) {
            count++;
        }

        Hawk.put(String.valueOf(count), locationData);

        Log.d(TAG, "HAWK /// Saved to local storage. COUNT = " + Hawk.count());
    }
}

以下步驟幫助我解決了它:

  1. 刪除並重新安裝應用程序

  2. 根據此更改manifest

     <receiver android:name="com.foxminded.tracker.ui.broadcast.ServiceRestart" android:exported="true" android:enabled="true"> <intent-filter> <action android:name="restartService" /> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>

這里添加了"android.intent.action.LOCKED_BOOT_COMPLETED"android:exported="true" android:enabled="true"

暫無
暫無

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

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