我的VOIP Android应用程序具有C / Native Library,它可以执行登录/注销等所有业务逻辑。
问题是当设备屏幕被锁定时,应用程序(c代码)无法从服务器接收任何数据包。我用Wireshark验证了这一点。看起来CPU没有运行。
我能够在我的应用程序INIT上解决下面的问题。
WakeLock mWakeLock = null;
PowerManager pm = (PowerManager) cxt.getSystemService(Context.POWER_SERVICE);
if(mPartialWakeLock == null){
// lock used to keep the processor awake.
mPartialWakeLock = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, TAG);
mPartialWakeLock.acquire;
}
但是上面的操作会耗尽我的电池。
为什么请求没有到达我的申请?当屏幕被锁定并从服务器接收请求时,如何使设备CPU始终启动?
注意: EDITED 使用的设备:三星Rugby Smart i847 操作系统:Android操作系统,v2.3.6(Gingerbread.UCLA4)
该应用程序适用于Galaxy s2。(这是因为它的双核心处理器和CPU在屏幕锁定上运行吗?) SKYPE和VIBER如何将WRT设计为睡眠模式?
答案 0 :(得分:1)
您考虑使用service吗?
Service为应用程序提供了一个工具,告诉系统它想要在后台执行的操作(即使用户没有直接与应用程序交互)。通过启动它,系统将安排服务的工作,直到服务或其他人明确停止它为止。
我想这可以帮助..干杯
修改强> Oki,你之前没有提过服务..我仍然不确定你是否有两个问题(耗尽电池而没有接收数据),或者只是一个你接收带漏的数据...?
考虑到耗尽电量,你可以试验WAKE_LOCK的不同标志。
我注意到的重要一点是,您没有发布锁定mPartialWakeLock.release()
,因为已建议链接WAKE_LOCK页面:
使用此设备可显着影响设备电池寿命 API。除非你真的需要,否则不要获得WakeLocks,使用 可能的最低水平,并确保尽快释放。
此外,根据其他一些posts,电池耗尽速度取决于您在服务中所做事情的工作和效果,所以这是我们无法在没有看到更多代码的情况下提供帮助的地方..:小号
顺便说一句..恕我直言,如果你只是等待来电而你一直保持WAKE_LOCK,这可能是电池耗尽的原因。想想你需要什么,尽量减少资源的使用不需要它们。例如,考虑WIFI_LOCK,并尽快释放WAKE_LOCK。
答案 1 :(得分:1)
我正在开发一个类似的应用程序,它运行一个服务,在启动时建立与服务器的持久TCP连接,以便能够从服务器接收消息。该服务不会获得任何锁定。这段时间的应用程序已经实现了,到目前为止,我没有遇到任何无法从服务器接收消息的问题。在读完你的问题后,我决定测试为什么我没有这个问题。
我认为即使我没有持有任何锁,也许还有其他应用程序,因此可以保持CPU活着。正在运行adb shell dumpsys
,我注意到情况并非如此:mLocks.size=0
。
这必须意味着应用程序仍然能够接收数据包,即使设备处于睡眠状态。我在这方面找不到任何官方内容,但互联网上的几篇帖子似乎都同意:
虽然我没有找到一个很好的例子来说明这一点,但似乎即使你的手机处于睡眠状态,如果连接上收到数据,你的代码也会被唤醒[...]({{ 3}})
>假设设备处于深度睡眠状态,并且网络堆栈接收传入数据包。这会唤醒设备吗?
它应该。 (source)
但是,请注意,两个来源都建议您应该获取唤醒锁来处理数据包,以防止设备在此处理过程中入睡。我不会在我的应用程序中这样做(也许我应该),但我的处理时间很短。
当您说您的请求未到达您的申请时,您确定不是吗?也许他们是,但你的应用程序在发送回复之前就睡着了?当您在套接字上接收数据并在完成处理后释放它时,请尝试获取唤醒锁定。
答案 2 :(得分:0)
不需要使用唤醒锁,因为它们不可靠且有缺陷。
使用系统自己的版本以更易于管理的方式保持屏幕安装会更有效率:
在您活动的onCreate
内,执行以下操作:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.FLAG_SHOW_WHEN_LOCKED);
这是来自开发人员的API here:
public static final int FLAG_SHOW_WHEN_LOCKED
自:API Level 5 Window标志:允许显示窗口的特殊标志 当屏幕被锁定时。这将让应用程序窗口占用 优先于密钥保护或任何其他锁定屏幕。可以搭配使用 FLAG_KEEP_SCREEN_ON打开屏幕并直接显示窗口 在显示钥匙防护窗口之前。可以搭配使用 FLAG_DISMISS_KEYGUARD自动完全取消非安全 keyguards。此标志仅适用于最顶层的全屏窗口。
常数值:524288(0x00080000)
通过将其与旗帜上的高效屏幕相结合,应该绕过屏幕锁定设施。唯一的办法是确保您的活动是屏幕上最顶层的。
引用FLAG_KEEP_SCREEN_ON
{{1}}
public static final int SCREEN_BRIGHT_WAKE_LOCK
此常量已弃用。大多数应用应该使用 FLAG_KEEP_SCREEN_ON而不是这种类型的唤醒锁定 当用户在两者之间移动时由平台正确管理 申请并不需要特别许可。唤醒锁定 确保屏幕全亮;键盘 背光将被允许熄灭。
答案 3 :(得分:0)
没有必要创建不起作用的代码 - 为什么不使用准备好的软件?我们使用Ozeki电话系统XE PBX和Android手机(有30部Android手机通过VoIP连接到系统),他们无故障地工作。
检查出来:Link
RTCP协议处理从未出现过问题。如果需要,请尝试试用版。
希望我能提供帮助。
答案 4 :(得分:0)
App在后台运行时无法接收UDP数据。 因为您的客户端正在以多播方式发送数据。当您的移动设备屏幕锁定且App在后台运行时,在这种情况下移动硬件有mac过滤器和ip过滤器,它只能接受指向属于设备的特定IP的数据。简单来说就是你需要做单播。 例如 : 有客户端在特定套接字和ip上发送数据(在您的情况下,您可能在255.255.255.255上发送数据)并且如果有任何设备准备接收该端口上的数据,则您的数据在特定端口上广播比如服务器,例如你App就像服务器一样,如果你的应用程序在前台运行,它就会收到数据。当你在后台app应用时不会。
所以,你要做的就是你必须得到设备的IP地址,你必须在你的设备IP地址上发送数据,这意味着你要做单播。在此,您的应用将接收运行背景或前景并锁定移动屏幕的数据。