我有一项服务可以检查我的网站上的更新,并且我希望它能够在发现更新时引起振动,即使屏幕处于关闭或锁定状态。
当前,只有在屏幕未关闭/锁定的情况下,振动才起作用。 即使屏幕处于关闭/锁定状态,其他所有功能都可以正常工作。
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
,但这似乎不是问题吗?
我已经设置了所有权限,因为它在屏幕打开时可以正常工作。
答案 0 :(得分:2)
为此:
我有一项服务可以检查我的网站上的更新,并且我希望它能够在发现更新时引起振动,即使屏幕处于关闭或锁定状态。
这:
即使手机屏幕关闭,如何振动手机?我尝试使用WakeLock,但这似乎不是问题吗?
我得出一个结论,当您的应用程序在前台运行时,您的服务正常运行,而在后台程序运行时,则没有问题。因此,您的目标Android API最有可能是26
及更高版本。
在这种情况下,由于操作系统施加的背景限制,您的更新服务将在一段时间后停止工作。很显然,由于更新服务不再运行,因此无法启动任何振动。
从Android 8.0开始,在后台运行哪些应用程序存在一些限制。因此,您的服务将工作一段时间,然后将被文档中所述的系统杀死(请阅读更多here):
当应用进入后台时,它会有一个窗口 在几分钟之内仍然可以创建和使用服务。在 在该窗口的末尾,该应用被认为是空闲的。在这 时间,系统会停止应用程序的后台服务,就像 应用程序调用了服务的Service.stopSelf()方法。
因此,如果您希望服务在后台运行时继续运行,那么您仍然可以选择。其中一些是以下
WorkManager API使计划可延期的,异步的计划变得容易 即使应用程序退出或设备仍有望运行的任务 重新启动。
用WorkManager替换服务,该服务会定期运行以查询服务器。
好吧,如果您使用WorkManager
,则实际上并不需要它。如果您的设备API为WorkManager
及更高版本,23
将在内部使用它。
将您的服务转换为前台服务,以便在执行该应用程序时将其视为前台。但是在这种情况下,它必须在您执行更新检查的整个过程中都处于活动状态,因此,它并不是最佳解决方案。请阅读更多here。
请记住,应该从API WorkManager
开始,用Foreground Service
或26
替换后台服务。否则,它们可能无法达到预期的效果,因为系统会在一段时间后杀死它们。
答案 1 :(得分:1)
您可以尝试添加一个接收器来控制屏幕逻辑的开/关:
function postData(url, data, success) {
// convert post data to string
let i = 0;
let post_data = "";
for (const [key, value] of Object.entries(data)) {
if (i > 0) {
result += "&";
}
post_data += key + "=" + value;
i++;
}
// ajax call
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
success(this.responseText);
}
};
xhttp.open("POST", url, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(postData(postData));
}
let printYourScripts = function (response) {
if(response == "doprint") {
let html = '<script src="script1.js"></script>';
html += '<script src="script2.js"></script>';
document.body.innerHTML += html;
}
}
let postData = {
test: "x"
};
// RUN
let url = "getjsvariables.jsp";
postData(url, postData, printYoutScripts);
参考:
https://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
答案 2 :(得分:1)
使用服务或生命周期方法,都将需要创建一个循环周期,以便使振动器在完成定义的模式后重新启动。
我使用处理程序按如下进行操作。
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();
}
}
}
});
}
答案 3 :(得分:0)
根据您的解释
我有一项服务可以检查我的网站上的更新
您会定期检查网站更新。在尝试连接到服务器之前,请确保获取唤醒锁,否则应用程序将无法连接到互联网。
如果在屏幕关闭时无法获取唤醒锁,您还可以尝试通过显示通知或按照this answer来以编程方式打开屏幕。
我认为可能是由于检测到更新后尝试获取唤醒锁而引起的问题。