Захват нажатия клавиш, когда телефон Android находится в глубоком спящем режиме

Описание проблемы

Я пытаюсь написать приложение, которое будет захватывать кнопки увеличения и уменьшения громкости, а также кнопки Bluetooth-гарнитуры, когда приложение находится в

  • Фон
  • Передний план
  • Фон и телефон находятся в спящем режиме (кнопка питания нажата)
  • Передний планшет и телефон находятся в спящем режиме (кнопка питания нажата)

Для первых двух точек я пишу какое-то тестовое приложение, и все работает в моем случае, я отправляю приложение в фоновом режиме и нажимаю вверх/вниз, и мое приложение улавливает эти события. После того, как я нажму кнопку питания, и мой телефон перейдет в спящий режим. Затем я нажимаю кнопки громкости вверх/вниз, телефон не реагирует на эти события, и я не вижу никакого loge в logcat, как будто все перестает работать.

Приложения, которые обнаруживают нажатия клавиш в спящем режиме.

Я думаю, что эта проблема не может быть решена, но потом я помню, что Android Media Media Player улавливает эти события, когда вы нажимаете кнопки увеличения и уменьшения громкости во время воспроизведения музыки. Я думаю, что это приложение может сделать это, поскольку это системное приложение, но затем я загружаю проигрыватель Winpm, и он работает одинаково. Winapm увеличивает громкость при переходе в режим ожидания. И приложения для музыкальных плееров это делают.

Вопрос

Я хочу понять, как это можно сделать? Как я могу написать простое приложение, которое будет нажимать кнопки увеличения/уменьшения громкости. Нужно ли мне играть какую-то музыку в это время, или я могу это сделать? Я имею в виду, может быть, главная причина, по которой Winamp и другие приложения поймают это событие, - это то, что в это время играет музыка. Или, может быть, эта проблема не может быть решена, и если она не может быть решена, я хочу знать, почему? Мне нужны некоторые аргументы, почему это невозможно решить.

Исходный код

Я тестировал какое-то приложение, и вот результаты, я пишу простое приложение, которое увеличивает громкость клавиш вверх и вниз в фоновом режиме и переднем плане, а также когда приложение находится в спящем режиме. Все работает отлично, когда приложение было в фоновом режиме и в фойе, мое тестовое приложение захватывает события, но когда я нажимаю кнопку питания, это перестает это делать, тогда я нажимаю на медиаплеер и начинаю играть какую-то музыку после того, как я снова нажмите кнопку питания, а затем нажмите кнопку увеличения громкости и doun, а мой показатель приложения будет увеличивать громкость вверх и вниз. Это означает, что тогда музыка играет мое приложение может поймать, что события, так что мой следующий вопрос, как я могу имитировать, как мой телефон играет somem музыки? может быть, это решение?

Manifest.xml

<receiver android:name="com.vito.backgroundworker.VolumeBroadcast" android:enabled="true">
    <intent-filter>
    <action android:name="android.media.VOLUME_CHANGED_ACTION" />
    </intent-filter>
</receiver>

<receiver android:name="RemoteControlReceiver">
    <intent-filter>
    <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

MainActivity.java

public class MainActivity extends Activity {
    private PowerManager.WakeLock wl;
    //private BroadcastReceiver vol = new VolumeBroadcast();
    private AudioManager mAudioManager;
    private ComponentName mRemoteControlResponder;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNjfdhotDimScreen");

        mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
        mRemoteControlResponder = new ComponentName(getPackageName(),
                RemoteControlReceiver.class.getName());
    }

    @Override
    protected void onPause() {
        super.onPause();
        mAudioManager.registerMediaButtonEventReceiver(
                mRemoteControlResponder);
        wl.release();
    }//End of onPause

    @Override
    protected void onResume() {
        super.onResume();
        wl.acquire();
    }//End of onResume

    @Override
    public void onDestroy() {
        super.onDestroy();
        mAudioManager.unregisterMediaButtonEventReceiver(
                mRemoteControlResponder);
    }
}

Ответ 1

Посмотрите registerMediaButtonEventReceiver(). Вы должны зарегистрировать свое приложение в качестве получателя этих событий, чтобы иметь возможность получить их.

Вот еще несколько ссылок, на которые вы должны обратить внимание:

Ответ 2

По моему опыту, приложение не может получать трансляции медиа-кнопок, когда устройство спит, даже если это функция переднего плана (кнопка мультимедиа не разбудит ее). Удерживание частичного блокирования следа предотвращает его сон, так что нажатие кнопки обнаружено. Я подозреваю, что ваше приложение для игры с музыкой держит блокировку следа, поэтому она работает. Я хотел бы быть доказанным неправильно и не нуждаюсь в блокировке следа, хотя...

Ответ 3

Я нашел приложение с открытым исходным кодом, которое действительно пробуждает телефон от сна, нажав кнопку регулировки громкости. https://github.com/praslnx8/volume_Screen_Lock

Это приложение использует Службу для воспроизведения мультимедиа.

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