UDP / RTCP数据包未到达设备/应用程序设备屏幕已锁定

时间:2012-07-02 17:00:24

标签: android android-ndk cpu

我的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设计为睡眠模式?

5 个答案:

答案 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}}

的{{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地址上发送数据,这意味着你要做单播。在此,您的应用将接收运行背景或前景并锁定移动屏幕的数据。