Служба работает в Android 6.0.1, а не в Android 10 - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть следующая служба, объявленная в манифесте:


    <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>

, и это класс службы


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) {

    }


}

И эта служба создается и завершается в двух разных «onclick» функции из MainActivity

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 для записи данных с датчиков, я намерен записывать данные, когда пользователь может взаимодействовать с телефоном или вообще ничего не делать (после того, как он нажмет кнопку питания на телефоне, служба продолжает выполнять сбор данных и выполнение действий )

Затем служба должна быть прервана, либо когда пользователь нажмет кнопку «Стоп», либо когда будет завершена основная деятельность.

Спасибо!

1 Ответ

0 голосов
/ 30 апреля 2020

Полагаю, вам следует больше узнать о фоновых сервисах и широковещании в android API 26 или выше

Из официальной документации здесь

Если приложение регистрируется для приема трансляций, приемник приложения потребляет ресурсы при каждой отправке трансляции. Это может вызвать проблемы, если слишком много приложений регистрируется для приема трансляций на основе системных событий; системное событие, запускающее широковещательную рассылку, может привести к тому, что все эти приложения будут использовать ресурсы в быстрой последовательности, что ухудшит работу пользователя. Чтобы решить эту проблему, 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 для отложенных фоновых задач.

Эта библиотека обратно совместима

Она использует JobScheduler, FirebaseJobDispatcher или AlarmManager

Нет необходимости зависеть от библиотеки службы воспроизведения.

Рекомендовано Google для отложенной фоновой работы.

Может использовать такие функции, как сцепление, ограничения и т. д. c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...