将我的后台服务转换为与Android Oreo 8.0兼容

问题描述 投票:0回答:1

我的应用程序中有一个可以处理许多事情的服务。有时,当设备空闲时,应用程序崩溃。我知道新的Android 8.0准则,但不确定是否应该将服务转换为JobScheduler或采取任何其他正确方法。我可以使用一些建议,这些建议将是转换此服务的最佳方法。这是代码

这里是服务:

public class ConnectionHolderService extends Service {

    private static final String LOG_TAG = ConnectionHolderService.class.getSimpleName();
    private SensorManager mSensorManager;


    private static ConnectionHolderService instance = null;

    public static ConnectionHolderService getInstanceIfRunningOrNull() {
        return instance;
    }


    private class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
           //some code
        }
    }

    private Messenger mMessenger = new Messenger(new IncomingHandler());

    public ConnectionHolderService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        mReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(final Context context, Intent intent) {

            //some code

    }


    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }

    private void startListeningForShake() {
        mShakeEnabled = true;
        startServiceToAvoidStoppingWhenNoClientBound(ACTION_STOP_SHAKE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
            mSensorManager.registerListener(mSensorListener,
                    mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                    SensorManager.SENSOR_DELAY_UI);
        }
    }

    private void startServiceToAvoidStoppingWhenNoClientBound(String action) {
        registerReceiver(mReceiver, new IntentFilter(action));
        startService(new Intent(this, ConnectionHolderService.class));
        final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ":Doze lock");
        if (!lock.isHeld()) {
            lock.acquire();
        }
        // When the Shake is active, we should not stop when UI unbinds from this service
        startNotification();
    }

    private Notification getShakeServiceForegroundNotification() {
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);

        if (mShakeEnabled) {
            notificationBuilder.addAction(0, getString(R.string.shake_turn_off),
                    PendingIntent.getBroadcast(this,
                            REQ_CODE_STAY_ON,
                            new Intent(ACTION_STOP_SHAKE),
                            PendingIntent.FLAG_UPDATE_CURRENT));
        }

        if (mPollingEnabled) {
//            notificationBuilder.addAction(0, getString(R.string.stop_smart_home_integration),
//                    PendingIntent.getBroadcast(this,
//                            REQ_CODE_STAY_ON,
//                            new Intent(ACTION_STOP_POLLING_SQS),
//                            PendingIntent.FLAG_UPDATE_CURRENT));
        }

        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        notificationBuilder
                .setSmallIcon(R.drawable.logo)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setUsesChronometer(true)
                .setContentIntent(PendingIntent.getActivity(this, REQ_CODE_STAY_ON, intent, PendingIntent.FLAG_UPDATE_CURRENT))
                .setContentTitle(getString(R.string.title_notification_running_background))
                .setContentText(getString(R.string.description_running_background));
        return notificationBuilder.build();
    }


    private void stopIfNeeded() {
        if (!mShakeEnabled && !mPollingEnabled) {
            try {
                unregisterReceiver(mReceiver);
            } catch (Exception e) {
                // It can be IllegalStateException
            }
            stopNotification();
            stopSelf();
            if (lock != null && lock.isHeld()) {
                lock.release();
            }
        }
    }


    public void startNotification() {
        if (SqsPollManager.sharedInstance().isConnectInBackground() && !MyApp.sharedInstance().isAppInForeground()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
                startForeground(ID_SHAKE_SERVICE, getShakeServiceForegroundNotification());
            }
        }
    }


    public void stopNotification() {
        mNotificationManager.cancel(ID_SHAKE_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
            stopForeground(true);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mReceiver = null;
        Log.i(LOG_TAG, "onDestroy");
        mMessenger = null;
        mSensorListener = null;
        instance = null;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Log.i(LOG_TAG, "onTaskRemoved! Stopping ConnectionHolderService");
        try {
            unregisterReceiver(mReceiver);
        } catch (Exception e) {
        }
        stopNotification();
        stopSelf();
        if (lock != null && lock.isHeld()) {
            lock.release();
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
            stopForeground(true);
        }
        stopSelf();
    }
}

这里是我的应用程序类别:

public class MyApp  {

@Override
    public void onCreate() {
        super.onCreate();
         sendMessageToConnectionHolderService("SomeMessage");
    }

public void sendMessageToConnectionHolderService(final int what) {
        bindService(new Intent(this, ConnectionHolderService.class), new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.i(LOG_TAG, "ConnectionHolderService connected!");
                Messenger messenger = new Messenger(service);
                Message msg = new Message();
                msg.what = what;
                try {
                    messenger.send(msg);
                    Log.i(LOG_TAG, "Message " + what + " has been sent to the service!");
                } catch (RemoteException e) {
                    Log.e(LOG_TAG, "Error sending message " + msg.what + " to ConnectionHolderService", e);
                }

                final ServiceConnection conn = this;
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        unbindService(conn);
                    }
                }, 1000);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.i(LOG_TAG, "ConnectionHolderService disconnected!");
            }
        }, Context.BIND_AUTO_CREATE);
    }


private Runnable mStartNotificationRunnable = new Runnable() {
        @Override
        public void run() {
            if (SqsPollManager.sharedInstance().isPollingEnabled()
                    && SqsPollManager.sharedInstance().isConnectInBackground()
                    && !isAppInForeground()) {
                if (null != ConnectionHolderService.getInstanceIfRunningOrNull()) {
                    ConnectionHolderService.getInstanceIfRunningOrNull().startNotification();
                }
            }
        }
    };

    private Runnable mStopNotificationRunnable = new Runnable() {
        @Override
        public void run() {
            if (null != ConnectionHolderService.getInstanceIfRunningOrNull()) {
                ConnectionHolderService.getInstanceIfRunningOrNull().stopNotification();
            }
        }
    };

}

AndroidManifest:

<service
          android:name=".ConnectionHolderService"
            android:enabled="true"
            android:exported="false" />
android service android-service android-8.0-oreo background-service
1个回答
0
投票

您应该考虑使用WorkManager。关于如何使用它,including samples, code-labs and blogs有很多资源。

并且如果您特别由于Android 8.0准则对JobScheduler感兴趣,我写了blog post that provides insights

© www.soinside.com 2019 - 2024. All rights reserved.