Как мне написать приложение для Android, которое действует на ACTION_SCREEN_ON, без остановки через некоторое время?

Пояснение: я не хочу держать устройство в активном состоянии, я просто хочу выполнять свою команду при каждом включении экрана.

Краткая справка о том, почему я хочу это сделать

У некоторых телефонов Oneplus One есть неприятная ошибка, когда сенсорный экран через некоторое время перестает отвечать. Бег cat /sys/class/input/input0/baseline_test Как root, ситуация улучшается на некоторое время, по крайней мере, для некоторых пользователей. Поскольку проблемы часто возникают, когда телефон находится в спящем режиме, разблокировать телефон может быть очень сложно. Итак, я хочу запускать эту команду каждый раз, когда активируется экран телефона.

Да, я знаю, я могу сделать это с Tasker, но где в этом удовольствие?:)

Итак, к моей проблеме

Я не разработчик Android, но я смог написать приложение, которое делает именно это. Он работает отлично, около часа или около того, после чего он просто перестает работать. Я регистрирую намерение ACTION_SCREEN_ON в коде, так как по какой-то причине это невозможно сделать в манифесте. Итак, мой, надеюсь, простой вопрос, как мне изменить свое приложение, чтобы оно не останавливалось в фоновом режиме. Поможет ли мне сервис?

Мой код:

import ...;

public class ConfigurationActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_configuration);
        registBroadcastReceiver();
    }

    public void onDestroy(Bundle savedInstanceState) {
        unregisterReceiver();
    }

    private BroadcastReceiver mPowerKeyReceiver = null;

    private void registBroadcastReceiver() {
        final IntentFilter theFilter = new IntentFilter();

        theFilter.addAction(Intent.ACTION_SCREEN_ON);

        mPowerKeyReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String strAction = intent.getAction();

                if (strAction.equals(Intent.ACTION_SCREEN_ON)) {
                    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                    String[] commands = {"cat /sys/class/input/input0/baseline_test"};
                    RunAsRoot(commands);
                    v.vibrate(25);
                }
            }
        };
        getApplicationContext().registerReceiver(mPowerKeyReceiver, theFilter);
    }

    private void unregisterReceiver() {
            getApplicationContext().unregisterReceiver(mPowerKeyReceiver);
            mPowerKeyReceiver = null;
    }

    public void RunAsRoot(String[] cmds){
        Process p = null;
        try {
            p = Runtime.getRuntime().exec("su");
        } catch (IOException e) {
            e.printStackTrace();
        }
        DataOutputStream os = new DataOutputStream(p.getOutputStream());
        for (String tmpCmd : cmds) {
            try {
                os.writeBytes(tmpCmd+"\n");
                os.writeBytes("exit\n");
                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2 ответа

Использовать этот

private void unlockScreen() {
        Window window = this.getWindow();
        window.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
        window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        window.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);
    }

Добавить это разрешение

<uses-permission android:name="android.permission.WAKE_LOCK" />

Я уже отправил ответ на подобный вопрос.
Включение экрана от приемника / службы
или проверить это,
Как заблокировать / разблокировать экран программно?

Обновлено:

Лучший способ сделать это - использовать FLAG_KEEP_SCREEN_ON в своей деятельности (и только в деятельности, а не в службе или другом компоненте приложения).

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  }

Еще один способ реализовать это в XML-файле макета вашего приложения, используя android:keepScreenOn атрибут:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true">
    ...
</RelativeLayout>

Для получения дополнительной информации нажмите здесь

Другие вопросы по тегам