Как заставить broadcastreceiver работать на MIUI, когда телефон спит?

#android #android-studio #kotlin

Вопрос:

 class AlarmReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context,"Ready to wake up?", Toast.LENGTH_LONG).show()

        val myIntent = Intent(context,AlarmActivity::class.java)
        myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(myIntent)
    }
}
 

Манифест:

 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.QuickNap">
        <activity android:name=".AlarmActivity"
            android:screenOrientation="portrait"
            android:theme="@style/Theme.NoActioBar"
            android:windowSoftInputMode="adjustResize"></activity>

<!--        <receiver-->
<!--            android:name=".AlarmReceiver"-->
<!--            android:process=":remote" />-->

        <receiver android:name=".AlarmReceiver"
            android:enabled="true"
            android:exported="true"
            android:process=":remote">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="android.intent.action.REBOOT"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:theme="@style/Theme.NoActioBar"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

MainActivity:

   onTimer = true;
        moonImage.setColorFilter(null)
        val mIntent = Intent(this, AlarmReceiver::class.java)
        val mPendingIntent = PendingIntent.getBroadcast(this, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT)
        val calendar = Calendar.getInstance()
        calendar.add(Calendar.SECOND, minuteSet)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,calendar.timeInMillis,mPendingIntent)
        }
        else
        {
            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, mPendingIntent)
        }
 

привет, я пытаюсь создать приложение для Android с будильником, используя kotlin.
итак, я создал приемник, в этом приемнике я включаю действие, и в этом действии я воспроизводю звук.

этот код отлично работает, как и предполагалось, на эмуляторе. но на устройстве (Redmi Note 7 pro, MIUI OS). это работает только тогда, когда экран включен и если приложение открыто. есть какие-нибудь идеи о том, как убедиться, что он включает экран при вызове этого приемника?

также я новичок в разработке Android, поэтому ELI5. ty

Ответ №1:

Существует множество причин, по которым вы не можете вывести приложение на передний план. Давайте разберем ее на части и решим соответствующим образом:

1- Ограничения стандартной ОС : : Android известен растущими ограничениями на фоновые задачи. MIUI даже превзошел это с большим ограничением из-за своего алгоритма «Оптимизации батареи». Прежде всего, убедитесь, что вы проинформировали пользователя о том, что приложение НЕ МОЖЕТ работать в фоновом режиме или выводиться на передний план, если включена оптимизация заряда батареи MIUI. Поэтому дайте пользователю возможность перейти к опции экономии заряда батареи в настройках приложения, указав ему намерение одним щелчком мыши. К сожалению, нет никакого программного решения. Здесь вы можете увидеть список производителей, которые применяют свои правила экономии заряда батареи: Не убивайте мое приложение!
Xiaomi — не единственный производитель, о котором вам нужно беспокоиться.

2- Android 10 (API 29) Ограничения: Начиная с этого конкретного API, приложения БОЛЬШЕ НЕ могут переходить на передний план из фона. Google начал накладывать множество ограничений на множество разрешений и функций. Пожалуйста, прочитайте больше здесь о том, какие условия должны быть выполнены, чтобы иметь возможность запускать приложение, работающее в фоновом режиме: Ограничения на запуск действий — API 29

Что вы можете сделать: вы можете возиться с различными флагами и категориями, а также параметрами для добавления в манифест. Например, если вы еще не добавили это разрешение, убедитесь, что вы сделали это сейчас:

 QUOTED FROM THE LINK ABOVE:
...
The app should be granted the SYSTEM_ALERT_WINDOW permission by the user.
...
 

Вы также можете попробовать добавить разные флаги и категории, это МОЖЕТ НЕ сработать, но вы все равно можете попробовать и поработать, особенно с этими двумя строками:

     intent.addCategory(Intent.CATEGORY_LAUNCHER) //You can always add and remove categories
    intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
 

Ваше лучшее решение на данный момент: вы всегда можете проверить проект с открытым исходным кодом и посмотреть, как они справились с этой конкретной проблемой. Одним из моих любимых должен быть этот: AlarmClock FOSS на GitHub от yuriykulikov

Желаю удачи.

Комментарии:

1. Это сработало. Добавлено intent.addCategory(Intent.CATEGORY_LAUNCHER) в AlarmReceiver и SYSTEM_ALERT_WINDOW в manifest, также мне пришлось указать несколько настроек, как указано в комментарии выше.

2. Рад, что помог =)

3. эй, еще одна проблема, активность не запускается, когда телефон спит: (

4. ложная тревога .. это была моя логическая проблема при onPause ()

Ответ №2:

Перейдите в Настройки / Приложения / управление приложениями и выберите свое приложение, затем выберите battery saver и убедитесь, что оно включено «Без ограничений», чтобы ваше приложение могло работать в фоновом режиме без каких-либо ограничений.

Если это сработало, вы должны научить пользователя делать это. напишите намерение открыть настройки и так далее.

Комментарии:

1. кажется, это не работает, я могу показать всплывающее сообщение, но действие не открывается