有人可以解释一下BroadcastReceiver和之间的确切区别WakefulBroadcastReceiver吗?
在什么情况下我们必须使用每个Receiver类?
我的应用程序中有一个服务,它设计为每10分钟运行一次.它基本上检查我们的服务器,看看是否一切正常运行,并通知用户任何问题.我创建了这个应用程序供我们公司内部使用.
我的同事在漫长的周末使用了该应用程序,并注意到该设备进入睡眠状态时未执行任何检查.我的印象是服务应该在后台继续运行,直到我明确地调用stopService()我的代码.
所以最终,我的目标是让服务运行,直到用户点击应用程序中的关闭按钮或终止进程.
我听说过一些叫做WakeLock屏幕不能关闭的东西,这不是我想要的.然后我听说了另一种称为部分WakeLock的东西,即使设备处于睡眠状态,也可以使CPU保持运行.后者听起来更接近我的需要.
我如何获得此WakeLock以及何时应该发布它并且有其他方法可以解决这个问题吗?
我对wakelock有疑问.在下面显示的情况下,Android操作系统是否释放唤醒锁(PARTIAL_WAKE_LOCK如果您需要指定)以防止获取唤醒锁并且在关闭电源(不睡眠)之前浪费电池.
案例1-a:
App已经在其中一个线程中获得了wakelock(没有超时选项)(在这种情况下请认为这是合理的)并且它被设计为在关键任务完成时释放唤醒锁.应用程序可以被taskmanager或臭名昭着的taskkiller杀死,应用程序没有机会让它的线程释放唤醒锁.那个唤醒锁会发生什么?
案例1-b :(
如果对案例1-a的回答是"是的,请不要担心",那么请忽略这种情况.)与案例1-a相同但应用程序给予唤醒锁的超时选项,比如3秒.此超时选项是否保持有效?
案例2-a:
请想象一下,有一项服务由AlarmManager启动(通过广播接收器),并且该服务已获得唤醒锁(没有超时选项).此服务旨在使唤醒锁获取时间最小化.但不幸的是,由于内存紧缩,Android操作系统选择了这项服务.(我不知道当获得唤醒锁时操作系统是否不会终止服务,但我猜操作系统并不关心.但我希望操作系统稍后会发布唤醒锁.)那个唤醒锁会发生什么?
案例2-b :(
如果对案例2-a的回答是"是的,请不要担心",那么请忽略这种情况.)与案例2-a相同但是服务给了唤醒锁的超时选项,比如3秒.此超时选项是否保持有效?
android kill-process android-source android-wake-lock wakelock
我有一项活动需要在启动时打开屏幕(如果是关闭).所以在onCreate中,我有:
this.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
Run Code Online (Sandbox Code Playgroud)
在广播接收器的wakelock的帮助下使用它,我能够在广播接收器启动时显示我的活动.
但问题很奇怪,活动生命周期以这种方式调用,onPause()和onResume在启动活动后立即调用
所以问题出在启动和恢复调用两次,在停止也调用,我想在onStop()中实现一些逻辑,但是,这样的行为应用程序将无法正常工作.
编辑
我发现问题只是由于标志FLAG_SHOW_WHEN_LOCKED.当设备被锁定时 它只会在活动开始前锁定设备时发生.
PS我正在使用带有广播接收器的报警管理器,然后从广播接收器开始活动.
我一直在使用持久套接字对Android设备的自定义推送通知解决方案进行一些测试.我想分享我的发现并验证结果.
简单描述
应用程序运行前台服务并与服务器建立连接,并通过积极的ping(@ 10秒间隔)维护该连接.如果连接被检测为死机,则应用程序会不断尝试重新连接.服务器通过双工通道发送通知.
测试1:
Pinging is done using a timer at 10 second intervals.
Server sends notification every minute.
Applications acquires wifi and wake locks.
Duration : 8 hours
Battery loss : ~14%
Run Code Online (Sandbox Code Playgroud)
测试2:
Pinging is done using AlarmManager at 10 second intervals.
Server sends notification every minute.
Application acquires only a wifilock
Duration : 8 hours
Battery loss : ~7%
Run Code Online (Sandbox Code Playgroud)
假设:传入的网络数据包会自动唤醒CPU,因此无需唤醒锁定.使用AlarmManager ping(而不是计时器)意味着我们不需要唤醒锁.
取下那个唤醒锁似乎真的有助于电池.令人惊讶的是,对任何一种解决方案的激烈攻击并没有像我预期的那样影响电池寿命.(我们进行了许多其他测试,包括一个应用程序只是持有一个wifilock并且没有做任何导致同期电池损失约4%到5%的测试)
由于应用程序能够成功发送所有ping请求并接收所有传入消息,我相信我的假设是正确的.但我很乐意得到任何专家的确认.
还有一个问题: 如果应用程序要监听传入的连接.在这种情况下我需要拿一个唤醒锁,对吗?传入连接不会唤醒CPU?我们不是沿着这条路走下去,而是想确认一下.
此外,请不要推荐GCM,它已被公司政策排除.
谢谢.
我一直试图找到一种关闭显示器的方法,并从用户触摸触摸屏唤醒.
该设备处于嵌入式环境中,其中设备是平板电脑,并且用户除了触摸屏之外不能访问任何东西(根本没有按钮).
它连接到电源,因此电池不会出现问题,但是当我检测到没有活动时我想要关闭屏幕,这样它就不会整天盯着它们并且不会缩短LCD背光的寿命.
我永久保持一个唤醒锁,并决定何时自己睡觉.
问题是,当我使用以下方式关闭屏幕时:
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 0;
getWindow().setAttributes(params);
Run Code Online (Sandbox Code Playgroud)
活动暂停并停止.并且该单元不会响应触摸来唤醒它.您需要按电源按钮.此时,"滑动解锁"显示出来.
我想关闭显示器,然后继续运行,这样我就可以检测到触摸屏事件并重新打开显示屏.
我也尝试将显示器的亮度设置为0.1,这适用于某些设备,但是我需要它来处理设备,只是"调暗"显示器.
我也试过这个:
// First Remove my FULL wakelock
//then aquire a partial wake lock (which should turn off the display)
PowerManager.WakeLock wl = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Your Tag");
wl.acquire();
Run Code Online (Sandbox Code Playgroud)
但是此方法不会关闭显示屏.
出于某种原因,我的Android手机不会进入睡眠状态.我认为唤醒锁是保持清醒,但没有办法分辨哪些唤醒锁是活跃的.正在运行的服务没有列出任何可疑的东西,当然也没有什么不同.所以我的问题是:
当进程结束时,Android肯定会发布唤醒锁吗?有可能是一个应用程序写得不好而且在退出之前没有发布唤醒锁吗?
有没有办法看到活跃的唤醒锁?
这是dumpsys power显示:
$ dumpsys power
Power Manager State:
mIsPowered=true mPowerState=0 mScreenOffTime=226093 ms
mPartialCount=0
mWakeLockState=
mUserState=
mPowerState=
mLocks.gather=
mNextTimeout=91922738 now=92136117 -213s from now
mDimScreen=true mStayOnConditions=0
mScreenOffReason=3 mUserState=0
mBroadcastQueue={-1,-1,-1}
mBroadcastWhy={0,0,0}
mPokey=1 mPokeAwakeonSet=false
mKeyboardVisible=false mUserActivityAllowed=false
mKeylightDelay=6000 mDimDelay=47000 mScreenOffDelay=7000
mPreventScreenOn=false mScreenBrightnessOverride=-1 mButtonBrightnessOverride=-1
mScreenOffTimeoutSetting=60000 mMaximumScreenOffTimeout=2147483647
mLastScreenOnTime=0
mBroadcastWakeLock=UnsynchronizedWakeLock(mFlags=0x1 mCount=0 mHeld=false)
mStayOnWhilePluggedInScreenDimLock=UnsynchronizedWakeLock(mFlags=0x6 mCount=0 mHeld=false)
mStayOnWhilePluggedInPartialLock=UnsynchronizedWakeLock(mFlags=0x1 mCount=0 mHeld=false)
mPreventScreenOnPartialLock=UnsynchronizedWakeLock(mFlags=0x1 mCount=0 mHeld=false)
mProximityPartialLock=UnsynchronizedWakeLock(mFlags=0x1 mCount=0 mHeld=false)
mProximityWakeLockCount=0
mProximitySensorEnabled=false
mProximitySensorActive=false
mProximityPendingValue=-1
mLastProximityEventTime=0
mLightSensorEnabled=false
mLightSensorValue=-1.0 mLightSensorPendingValue=-1.0
mLightSensorScreenBrightness=35 mLightSensorButtonBrightness=255 mLightSensorKeyboardBrightness=0
mUseSoftwareAutoBrightness=true
mAutoBrightessEnabled=false
mScreenBrightness: animating=false targetValue=-1 curValue=0.0 delta=-1.3333334
mLocks.size=0: …Run Code Online (Sandbox Code Playgroud) 我有一个服务运行我的应用程序每小时发送通知.由于我的通知,我每小时都听到声音和振动,但工作正常,但我也希望我的通知也会点亮我的屏幕.但是当出现通知时,我无法点亮我的屏幕.
在pm和keepScreenOn变量是全局定义.
我在OnCreate方法中获取了PowerManager.WakeLock:
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
keepScreenOn = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_LOCK,"tpd");
Run Code Online (Sandbox Code Playgroud)
在我的onStart,onResume和onRestart中我抓住了锁
if (keepScreenOn == null) {
keepScreenOn = pm.newakeLock(PowerManager,SCREEN_BRIGHT_LOCK,"tpd");
}
keepScreenOn.acquire();
Run Code Online (Sandbox Code Playgroud)
在我的onDestroy,onPause和onStop中,我发布了锁定:
if (keepScreenOn != null) {
keepScreenOn.release();
keepScreenOn = null
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序退出后,我得到一个失败的屏幕,adb抱怨
java.lang.Exception:WakeLock在仍然持有时完成:tpd
跟踪显示我在退出前释放了锁.我错过了什么?
有没有办法退出应用,而不穿过的至少一个
onPause,onStop或onDestroy.我可以看到应用程序
release()经常被称为acquire(),因此即使唤醒锁被引用计数,它仍然应该没有引用.
我有一个应该在后台运行的服务.它在我的应用程序打开时启动,并在用户关闭我的应用程序时结束.
每当我的应用程序在后台或屏幕关闭时,我仍然需要运行该服务.
我用WakeLock实现了这一点,但由于某种原因我在标题中得到了错误.
这是令人担忧的,因为我可能是内存泄漏了WakeLock(如果我理解正确的话).
我可以通过重新启动我的应用程序来触发错误.
这是相关代码:
public class SomeService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
PowerManager manager = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
if (!mWakeLock.isHeld()) mWakeLock.acquire();
//Handle other processing
return START_STICKY;
}
@Override
public void onDestroy() {
if (mWakeLock.isHeld()) mWakeLock.release();
super.onDestroy();
}
}
Run Code Online (Sandbox Code Playgroud)
我很困惑,因为onDestroy()我发布了WakeLock.我不确定是什么触发了这个错误.