服务在Android 6.0.1中运行,而不在Android 10中运行

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

我在清单中声明了以下服务:


    <application
        ...

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.example.android.test.TestService"
            android:process=":Remote"
            android:permission="android.permission.WAKE_LOCK"/>
        <receiver android:name="com.example.android.test.TestService">
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_CHANGED"/>
            </intent-filter>
        </receiver>
    </application>

这是Service类


public class TestService extends Service implements SensorEventListener {


    public class BatteryReceiver_andFileChecker extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //TODO
        }
        // constructor
        public BatteryReceiver_andFileChecker(){
        }
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        //TODO
        return START_STICKY;
    }

    @SuppressLint("WakelockTimeout")
    @Override
    public void onCreate() {
        super.onCreate();

        Toast.makeText(this, "Logging service started new", Toast.LENGTH_SHORT).show();

        //Acquire wake lock
        PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
        this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WLTAG:MyWakelockTag");
        wakeLock.acquire();

        //Display notification
        this.notIntent = new Intent(this, MainActivity.class);
        this.pendingIntent = PendingIntent.getActivity(this, 0, this.notIntent, 0);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, this.channelID).setSmallIcon(R.drawable.ic_launcher_background).setContentTitle("Test").setContentText("Sensor is recording").setPriority(NotificationCompat.PRIORITY_DEFAULT).setContentIntent(this.pendingIntent);
        startForeground(this.NOTIFICATION, builder.build());


        //BatteryCheck
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        mReceiver = new BatteryReceiver_andFileChecker();
        registerReceiver(mReceiver, filter);

    }

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


        //cancel notification
        stopForeground(true);

        //Unregister battery receiver
        unregisterReceiver(mReceiver);

        //release wakeLock
        wakeLock.release();

        //Stop Service
        stopSelf();
    }

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

    @Override
    public void onSensorChanged(SensorEvent event) {        
        //TODO
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }


}

并且此服务在MainActivity的两个不同的“ onclick”函数上创建和终止

public class MainActivity extends AppCompatActivity {
     ...

public void onClickStart(View v) {

        // Start Service
        this.intent = new Intent(getApplicationContext(), TestService.class);
        this.intent.putExtra("foo",foo);
        startService(this.intent);
    }

    public void onClickStopAcquisition(View v) {

        // Stop Service
        stopService(this.intent);
    }
}

此代码在Android 6.0.1中按预期运行,在Android 10上不起作用...当我调试应用程序时,在两个操作系统中按下“开始”和“停止”按钮都不会触发任何错误,但是android 6.0.1会触发服务,而android 10不会...

任何原因吗?

仅在理解我的实现时要牢记,我的意图是提供一个即使用户未在应用程序中处于活动状态也能继续运行并在做事情的服务。由于我实现了SensorEventListener来记录来自传感器的数据,因此我的意图是在用户可能与手机进行交互甚至不执行任何操作时记录数据(在他按下手机的电源按钮之后,该服务将继续运行以获取数据并执行操作)

然后,应该在用户单击停止按钮时或在MainActivity终止时终止服务。

谢谢!

android service android-service android-sensors android-version
1个回答
0
投票

我想您应该阅读有关后台服务的更多信息,并在android API 26或更高版本中进行广播

摘自here的官方文档

[如果应用程序注册接收广播,则每次发送广播时,应用程序的接收器都会消耗资源。如果太多的应用程序注册为无法根据系统事件接收广播,则可能会导致问题。触发广播的系统事件可能导致所有这些应用连续消耗资源,从而损害用户体验。为减轻此问题,如背景优化中所述,Android 7.0 (API level 24)对广播设置了限制。 Android 8.0 (API level 26)使这些限制更加严格。

Android 8.0更高]为目标的应用不能再注册清单中隐式广播的广播接收器。一个隐式广播是不针对该应用的广播特别。例如,ACTION_PACKAGE_REPLACED是一个隐式广播,因为它已发送给所有注册的听众,让他们知道设备上的某些包装已被替换。然而,ACTION_MY_PACKAGE_REPLACED不是隐式广播,因为它是仅发送到已替换其软件包的应用程序,无论有多少其他应用已为该广播注册了侦听器。应用可以继续在清单中注册明确的广播。应用可以在运行时使用Context.registerReceiver()注册接收者对于任何广播,无论是隐式还是显式。

需要签名许可的广播不受此限制,因为这些广播仅发送到使用相同证书签名的应用,而不发送到设备上的所有应用]

您应该使用JobScheduler

重要更新

在评论中回答您的问题:将WorkManager用于可延期的后台任务。

此库向后兼容

使用JobSchedulerFirebaseJobDispatcherAlarmManager

不需要依赖播放服务库。

由Google推荐进行可延期的后台工作。

可以使用链接,约束等功能

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