![](/img/trans.png)
[英]appWidget stops updating/working after some time while phone is locked
[英]Phone vibration stops working after screen is off / locked
我有一項服務可以檢查我網站上的更新,我希望它能夠在找到更新時引起振動,即使屏幕關閉或鎖定也是如此。
目前僅當屏幕未關閉/鎖定時振動才有效。 即使屏幕關閉/鎖定,所有其他功能也能正常工作。
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
long[] pattern = new long[]{0, 400, 200, 400};
if (Build.VERSION.SDK_INT >= 26) { // New API
vibrator.vibrate(VibrationEffect.createWaveform(pattern,0));
} else { // Old API
vibrator.vibrate(pattern, 0);
}
即使手機屏幕關閉,如何振動手機? 我嘗試使用WakeLock
但這似乎不是問題?
我設置了所有權限,因為它在屏幕打開時工作。
鑒於這種:
我有一項服務可以檢查我網站上的更新,我希望它能夠在找到更新時引起振動,即使屏幕關閉或鎖定也是如此。
和這個:
即使手機屏幕關閉,如何振動手機? 我嘗試使用 WakeLock 但這似乎不是問題?
我得出的結論是,當您的應用程序在前台時,您的服務可以正常工作,但在后台時不會出現問題。 因此,您的目標 Android API 很可能是26
或更高。
在這種情況下,由於操作系統施加的背景限制,您的更新服務會在一段時間后停止工作。 由於更新服務不再運行,顯然它無法啟動任何振動。
從 Android 8.0 開始,對在后台運行的應用程序有限制。 因此,您的服務將工作一段時間,然后它將被系統殺死,如文檔中所述(請在此處閱讀更多信息):
當一個應用程序進入后台時,它有一個幾分鍾的 window ,它仍然可以創建和使用服務。 在 window 結束時,應用程序被認為是空閑的。 這時,系統會停止應用程序的后台服務,就像應用程序調用了服務的 Service.stopSelf() 方法一樣。
因此,如果您希望您的服務在應用程序處於后台時繼續運行,您仍然可以選擇。 其中一些如下
WorkManager API 可以輕松安排可延遲的異步任務,即使應用程序退出或設備重新啟動,這些任務也會運行。
用WorkManager替換您的服務,它會定期運行以查詢您的服務器。
好吧,如果您使用WorkManager
,您實際上並不需要它。 如果您的設備 API 為23
及更高版本, WorkManager
將在內部使用它。
將您的服務轉換為前台服務,以便在執行期間將應用程序視為前台。 但在這種情況下,它必須在您執行更新檢查的整個過程中都處於活動狀態,所以它可能不是最好的解決方案。 請在此處閱讀更多內容。
請記住,從 API 26
開始,應將后台服務替換為WorkManager
或Foreground Service
。 否則,它們可能無法按預期執行,因為系統會在一定時間后殺死它們。
您可以嘗試添加一個接收器來控制屏幕邏輯的開/關:
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// DO WHATEVER YOU NEED TO DO HERE
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = new long[]{0, 400, 200, 400};
// Only perform this pattern one time (-1 means "do not repeat")
v.vibrate(pattern, -1);
wasScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// AND DO WHATEVER YOU NEED TO DO HERE
wasScreenOn = true;
}
}
}
public class ExampleActivity extends Activity {
@Override
protected void onCreate() {
// INITIALIZE RECEIVER
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
// YOUR CODE
}
@Override
protected void onPause() {
// WHEN THE SCREEN IS ABOUT TO TURN OFF
if (ScreenReceiver.wasScreenOn) {
// THIS IS THE CASE WHEN ONPAUSE() IS CALLED BY THE SYSTEM DUE TO A SCREEN STATE CHANGE
System.out.println("SCREEN TURNED OFF");
} else {
// THIS IS WHEN ONPAUSE() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
}
super.onPause();
}
@Override
protected void onResume() {
// ONLY WHEN SCREEN TURNS ON
if (!ScreenReceiver.wasScreenOn) {
// THIS IS WHEN ONRESUME() IS CALLED DUE TO A SCREEN STATE CHANGE
System.out.println("SCREEN TURNED ON");
} else {
// THIS IS WHEN ONRESUME() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
}
super.onResume();
}
}
參考:
https://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
無論您使用服務還是生命周期方法,您都需要創建一個循環周期,以便您的振動器在完成您定義的模式后重新啟動。
我使用處理程序按如下方式進行了操作。
Handler handlerVibrate;
Vibrator vibrator;
private void vibrate(){
// this handler will keep vibrator running even with screen off (vibrator stops when the phone has the screen off)
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
handlerVibrate = new Handler();
handlerVibrate.post(new Runnable() {
@Override
public void run() {
if(vibrator != null) {
Log.d("mainActivity", "handler");
long[] pattern = {0, 500, 500};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createWaveform(pattern, 0)); // repeat at index 0
} else {
//deprecated in API 26
vibrator.vibrate(pattern, 0); // repeat at index 0
}
}
if(CONDITIONS TO STOP/CONTINUE){
// keep launching so that it keeps vibrating even with the screen off
handlerVibrate.postDelayed(this, 1000);
} else {
if(vibrator != null) {
vibrator.cancel();
}
}
}
});
}
從你的解釋
我有一項服務可以檢查我網站上的更新
您會定期檢查您網站的更新。 確保在嘗試連接到服務器之前獲得喚醒鎖,因為您的應用程序不會,否則您的應用程序將無法連接到互聯網。
您還可以嘗試通過顯示通知或按照此答案以編程方式打開屏幕,以防屏幕關閉時您無法獲得喚醒鎖定。
我相信這個問題可能是因為您可能在檢測到更新后嘗試獲取喚醒鎖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.