Android: как использовать PowerManager.wakeUp?

Я хочу использовать метод wakeUp из PowerManager. Eclipse (ADT) не пересматривает этот метод. Но для противоположного "goToSleep" проблем нет:

PowerManager pm = (PowerManager) MyApplication.getAppContext().getSystemService(Context.POWER_SERVICE);
pm.wakeUp(SystemClock.uptimeMillis()); //Detected as error by eclipse
pm.goToSleep(SystemClock.uptimeMillis()); //Not detected as error and work well

Ошибка затмения:

The method wakeUp(long) is undefined for the type PowerManager

Eclipse предлагает мне быстрое исправление, но у меня та же ошибка:

((Object) pm).wakeUp(SystemClock.uptimeMillis()); //the same error 

Это ошибка или только у меня? Спасибо!

2 ответа

Решение

Во-первых, как указал Luksprog, этот метод является новым для API уровня 17.

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

Вам следует взглянуть на PowerManager WakeLock API, в частности на флаг ACQUIRE_CAUSES_WAKEUP:

ACQUIRE_CAUSES_WAKEUP (добавлено на уровне API 1)

public static final int ACQUIRE_CAUSES_WAKEUP

Флаг блокировки пробуждения: включение экрана при получении блокировки пробуждения.

Обычно блокировка пробуждения на самом деле не выводит устройство из спящего режима, а просто заставляет экран оставаться включенным, когда он уже включен. Думайте о приложении видеопроигрывателя как о нормальном поведении. Уведомления, которые всплывают и требуют, чтобы устройство было включено, являются исключением; используйте этот флаг, чтобы быть похожими на них.

Не может использоваться с PARTIAL_WAKE_LOCK.

Постоянное значение: 268435456 (0x10000000)

Примечание для использования этого приложения AndroidMainfest.xml должен использовать WAKE_LOCK разрешение:

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

Документация по API уровня API 29 вызывает недоумение, поскольку ACQUIRE_CAUSES_WAKEUP флаг должен быть совмещен с допустимым уровнем, иначе PowerManager бросит вам IllegalArgumentException: Необходимо указать допустимый уровень блокировки пробуждения.

К сожалению, все доступные уровни либо устарели, либо явно не могут быть объединены с этим флагом:

  1. PARTIAL_WAKE_LOCK: Не может использоваться с ACQUIRE_CAUSES_WAKEUP флаг
  2. SCREEN_DIM_WAKE_LOCK: Не рекомендуется, начиная с API 17
  3. SCREEN_BRIGHT_WAKE_LOCK: Не рекомендуется, начиная с API 15
  4. FULL_WAKE_LOCK: Не рекомендуется, начиная с API 17
  5. PROXIMITY_SCREEN_OFF_WAKE_LOCK: Не может использоваться с ACQUIRE_CAUSES_WAKEUP флаг

Поэтому в своем приложении я решил объединить ACQUIRE_CAUSES_WAKEUP флаг с SCREEN_BRIGHT_WAKE_LOCK как менее злой чем FULL_WAKE_LOCK и полезнее, чем SCREEN_DIM_WAKE_LOCK.

Итак, моя реализация wakeUp выглядит примерно так (обратите внимание, что у меня есть предпочтения для пользователей, чтобы включить / отключить функцию пробуждения, а также определить метод для снятия блокировки пробуждения, когда приложение убито /onDestroy):

import android.content.Context;
import android.content.SharedPreferences;

import android.os.Bundle;
import android.os.PowerManager;

import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import androidx.preference.PreferenceManager;


public class MainActivity extends AppCompatActivity {


    /** Interval of 1 second in milliseconds */
    static final long INTERVAL_SECOND = 1000;

    /** Interval of 1 minute in milliseconds */
    static final long INTERVAL_MINUTE = 60 * INTERVAL_SECOND;

    SharedPreferences sharedPrefs = null;
    PowerManager.WakeLock mWakeLock = null;

    Context applicationContext = null;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final String TAG = "onCreate";
        applicationContext = getApplicationContext();

        setContentView(R.layout.activity_main);
        final Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        PreferenceManager
                .setDefaultValues(this, R.xml.root_preferences, false);
        sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
    }

    void wakeUp() {
        final String TAG = "wakeUp";
        if (sharedPrefs == null) {
            Log.w(TAG, "Shared Preferences was null");
            return;
        }
        final boolean isWakeUpPref = SettingsActivity.isWakelockPref(sharedPrefs);
        if (!isWakeUpPref) {
            Log.i(TAG, "WakeUp is disabled via preference");
            return;
        }
        Log.i(TAG, "WakeUp is enabled via preference");
        if (mWakeLock == null) {
            Log.i(TAG, "Creating WakeLock...");
            final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            if (pm == null) {
                Log.w(TAG, "could not get Power Service");
                return;
            }
            mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyApp:wakeup");
            Log.i(TAG, "WakeLock created!");
        } else if (mWakeLock.isHeld()) {
            Log.i(TAG, "Releasing old WakeLock, to reacquire with fresh timeout");
            mWakeLock.release();
        }
        Log.i(TAG, "Acquiring WakeLock to WakeUp...");
        mWakeLock.acquire(INTERVAL_MINUTE);
        Log.i(TAG, "WakeLock WakeUp acquired!");
    }

    void releaseWakeLock() {
        final String TAG = "releaseWakeLock";
        if (mWakeLock == null) {
            return;
        }
        if (!mWakeLock.isHeld()) {
            Log.w(TAG, "WakeLock not held!");
            return;
        }
        mWakeLock.release();
        Log.i(TAG, "WakeLock released!");
    }

}

Я вижу, у вас есть пользовательский ром. Вы можете использовать sleep () и wakeUp () из uiautomator, начиная с уровня API 16, чтобы в основном достичь той же функциональности, что и в PowerManager wakeUp() и goToSleep(), но без ограничения разрешениями, которые не будут предоставлены os (android.permission.DEVICE_POWER).

Посмотрите этот другой мой ответ, где я объясню более подробно, что такое установка.

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