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
: Необходимо указать допустимый уровень блокировки пробуждения.
К сожалению, все доступные уровни либо устарели, либо явно не могут быть объединены с этим флагом:
-
PARTIAL_WAKE_LOCK
: Не может использоваться сACQUIRE_CAUSES_WAKEUP
флаг -
SCREEN_DIM_WAKE_LOCK
: Не рекомендуется, начиная с API 17 -
SCREEN_BRIGHT_WAKE_LOCK
: Не рекомендуется, начиная с API 15 -
FULL_WAKE_LOCK
: Не рекомендуется, начиная с API 17 -
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).
Посмотрите этот другой мой ответ, где я объясню более подробно, что такое установка.