安卓广播接收器被调用但未启动前台服务。

huangapple go评论81阅读模式
英文:

Android broadcast reciever called but doesn't starts foreground service

问题

我为重新启动前台服务设置了广播接收器。

我有两台设备,它在魅族 M1 Note(Android 5.1)上运行,但在三星 A8(Android 9)上不起作用。在Oreo之后查找限制的原因,似乎没问题,但以防万一可以参考 https://developer.android.com/about/versions/oreo/background.html

在第二个设备上,广播接收器被调用,但服务在重启后没有启动。

该服务跟踪位置并使用带有通知的startForeground()进行正确工作。还尝试添加Worker以便在重启后重新启动服务,但似乎工作丢失了。

请提供任何建议,为什么我的接收器不会运行服务。

感谢。

清单:

<!-- 你的清单内容 -->

接收器:

// 你的接收器内容

服务:

// 你的服务内容

注意:这只是你提供的代码的中文翻译部分。如有更多问题或需要进一步帮助,请随时问我。

英文:

I set up broadcast reciever for restarting my foreground service after reboot.

I have two devices and it works on Meizu M1 note (android 5.1) but doesn't work on Samsung A8 (android 9). Looking for reason in restrictions after Oreo and seems like it ok, but just in case https://developer.android.com/about/versions/oreo/background.html

On the second one broadcast reciever called, but service not started after reboot.

Service tracks location and uses startForeground() with Notification for correct work.
Also tried to add Worker to restart service after reboot, but seems like work missing after that.

Please, geve any suggestions why my reciever doesn't run service.

Thanks.

Manifest:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    package=&quot;com.example.tracker&quot;&gt;

    &lt;uses-permission android:name=&quot;android.permission.FOREGROUND_SERVICE&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.ACCESS_NETWORK_STATE&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.CHANGE_NETWORK_STATE&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.RECEIVE_BOOT_COMPLETED&quot; /&gt;

    &lt;application
        android:name=&quot;.ui.di.App&quot;
        android:allowBackup=&quot;true&quot;
        android:icon=&quot;@mipmap/ic_launcher&quot;
        android:isolatedProcess=&quot;true&quot;
        android:label=&quot;@string/app_name&quot;
        android:roundIcon=&quot;@mipmap/ic_launcher_round&quot;
        android:supportsRtl=&quot;true&quot;
        android:theme=&quot;@style/AppTheme&quot;&gt;

        &lt;receiver android:name=&quot;com.example.tracker.ui.broadcast.ServiceRestart&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;restartService&quot; /&gt;
                &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot; /&gt;
                &lt;action android:name=&quot;android.intent.action.ACTION_BOOT_COMPLETED&quot; /&gt;
                &lt;action android:name=&quot;android.intent.action.QUICKBOOT_POWERON&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/receiver&gt;

        &lt;service
            android:name=&quot;com.example.tracker.ui.service.TrackerService&quot;
            android:enabled=&quot;true&quot; /&gt;

        &lt;service
            android:name=&quot;com.example.tracker.ui.worker.RestartIntentService&quot;
            android:enabled=&quot;true&quot; /&gt;


        &lt;activity android:name=&quot;.ui.screen.main.MainActivity&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;

    &lt;/application&gt;

&lt;/manifest&gt;

Reciever:

public class ServiceRestart extends BroadcastReceiver {

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

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

Service:

public class TrackerService extends Service implements LocationListener {

    public static final String TAG = &quot;TrackerService&quot;;

    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(&quot;TrackerService.HandlerThread&quot;);
        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(() -&gt; {
            connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            runLocationTransfer();
        });

        Log.d(TAG, &quot;===== SERVICE START&quot;);

        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 = &quot;Service running...&quot;;
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

        Notification.Builder notificationBuilder;

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

            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, &quot;===== SERVICE STOP&quot;);

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

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.d(TAG, &quot;TASK REMOVED&quot;);
        Toast.makeText(this, &quot;LOCATION TASK REMOVED&quot;, 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, &quot;====== SERVICE STOPPED by itself&quot;);
        } else if (connectivityManager.getActiveNetworkInfo() != null
            &amp;&amp; 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, &quot;LOCATION ------ LATITUDE: &quot; + location.getLatitude() + &quot; LONGITUDE: &quot; + 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() &gt; count) {
            count = Hawk.count();
        }

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

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

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

答案1

得分: 0

以下步骤帮助我解决了这个问题:

  1. 卸载并重新安装应用

  2. 根据以下更改manifest

     &lt;receiver android:name=&quot;com.foxminded.tracker.ui.broadcast.ServiceRestart&quot;
     android:exported=&quot;true&quot;
     android:enabled=&quot;true&quot;&gt;
     &lt;intent-filter&gt;
         &lt;action android:name=&quot;restartService&quot; /&gt;
         &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot; /&gt;
         &lt;action android:name=&quot;android.intent.action.LOCKED_BOOT_COMPLETED&quot; /&gt;
    
         &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
     &lt;/intent-filter&gt;
    

    </receiver>

在此处添加了 &quot;android.intent.action.LOCKED_BOOT_COMPLETED&quot;android:exported=&quot;true&quot; android:enabled=&quot;true;&quot;

英文:

Following steps helped me solve it:

  1. Remove and reinstall app

  2. Change manifest according to this

     &lt;receiver android:name=&quot;com.foxminded.tracker.ui.broadcast.ServiceRestart&quot;
     android:exported=&quot;true&quot;
     android:enabled=&quot;true&quot;&gt;
     &lt;intent-filter&gt;
         &lt;action android:name=&quot;restartService&quot; /&gt;
         &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot; /&gt;
         &lt;action android:name=&quot;android.intent.action.LOCKED_BOOT_COMPLETED&quot; /&gt;
    
         &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
     &lt;/intent-filter&gt;
    

    </receiver>

Here added &quot;android.intent.action.LOCKED_BOOT_COMPLETED&quot; and android:exported=&quot;true&quot; android:enabled=&quot;true&quot;

huangapple
  • 本文由 发表于 2020年9月10日 03:35:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/63818439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定