我有一个服务运行我的应用程序每小时发送通知.由于我的通知,我每小时都听到声音和振动,但工作正常,但我也希望我的通知也会点亮我的屏幕.但是当出现通知时,我无法点亮我的屏幕.
我目前正在使用Android的示例应用程序,它使用地理围栏进行位置监控,我发现很难遵守Android Vitals后台唤醒限制(https://developer.android.com/topic/performance/vitals/wakeup. HTML).
我正在使用Battery Historian来监控唤醒,虽然我们自己的警报速度低于每小时一次,但com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION和com.google.android.location.ALARM_WAKEUP_LOCATOR触发的速率要高得多.我尝试将地理围栏响应延迟设置为5分钟,并且WAKEUP_LOCATOR警报大大减少.尽管如此,ALARM_WAKEUP_ACTIVITY_DETECTION警报仍然远远超过10 /小时限制.
我们使用半径为100米的地理围栏,并按照此处的建议监控退出过渡.我还使用了一个更大的地理围栏,半径可达2公里,以确定何时需要重新加载地理围栏,以避免一次装载太多地理围栏.
最近的测试是在Galaxy S8上的Android 7.1上进行的,但这种情况在其他设备上是常规的.有没有人有类似的问题?Google推荐使用Geofences,特别是考虑到Oreo对后台位置请求的限制,因此系统监控工具在建议的避免方式时会占用大量唤醒,这很奇怪.
Ps:我在这里读过Yvette Colomb的答案,我没有使用位置更新,只使用Geofence服务.我应该放弃它吗?
[编辑]关于android的地理围栏的文档可以在这里看到:https://developer.android.com/training/location/geofencing.html
[编辑2] Android跟踪器上有一个问题正在讨论这种情况,但在这方面也没有新的更新
[编辑3]:问题已在Google问题跟踪器上分配.在~22/08/2018
感谢您的关注,
在过去的3-4天里,我一直在用这个来敲打我的脑袋,我找不到DECENT解释性文件(来自ARM或非官方的)来帮助我.我有一块ODROID-XU板(big.LITTLE 2 x Cortex-A15 + 2 x Cortex-A7)板,我正在尝试更多地了解ARM架构.在我的"试验"代码中,我现在已经到了我想从其WFI(等待中断)状态唤醒其他核心的阶段.
我仍然试图找到的缺失信息是:
1.获取内存映射GIC的基地址时,我明白我需要读取CBAR; 但没有任何文档解释如何安排CBAR中的位(2个PERIPHBASE值)来获取最终的GIC基址
2.通过GICD_SGIR寄存器发送SGI时,我应该选择0到15之间的中断ID?有关系吗?
3.通过GICD_SGIR寄存器发送SGI时,如何告知其他内核何处开始执行?
4. U-BOOT引导加载程序加载我的代码的事实如何影响这个上下文?
该的Cortex-A系列程序员指南3.0版(这里找到:链接)规定在以下部分22.5.2(在Linux中SMP开机,页271):
当主核心启动时,辅助核心将使用WFI指令保持待机状态.它(主核心)将为辅助核心提供启动地址,并使用处理器间中断(IPI)唤醒它们,这意味着通过GIC发信号通知SGI
Linux如何做到这一点?文档-S没有提供有关" 它将为辅助核心提供启动地址 "的任何其他详细信息.
我的挫折感越来越大,我会非常感谢你的答案.非常感谢你提前!
额外细节
我使用的文档:
我现在做了什么:
以上所有似乎都能正常工作.
我现在要做的是:
.... UPDATE ....
我已经开始查看Linux内核和QEMU源代码以寻找答案.这是我发现的(如果我错了,请纠正我):
有没有办法唤醒iOS应用程序而不使用"重大变化位置服务"?
我需要在没有服务器或用户干预的情况下唤醒我的应用程序有些类似于闹钟,其中你在唤醒时获得警报弹出窗口.
UILocalNotification - 无法工作,因为它需要用户和服务器干预.
无声推送通知 - 由于您无法将本地通知作为无声推送通知发送,因此无法正常工作.这些只能由服务器发送.这意味着它需要服务器干预
后台获取 - 由于没有保证的触发时间而无法工作
我错过了什么吗?
我自己的应用程序使用与2016年Google I/O应用程序所示的完全相同的技术.请参阅源代码
我需要在非常具体的时间点提醒用户 - 使用通知.
为此,我使用它AlarmManager
在正确的时间点唤醒设备:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
am.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else {
am.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
}
Run Code Online (Sandbox Code Playgroud)
这pendingIntent
是这样创建的:
final Intent intent = new Intent(MyAlarmService.ACTION_NOTIFY_RIDE, null, this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Run Code Online (Sandbox Code Playgroud)
现在,我的MyAlarmService
类是一个简单的IntentService
处理唤醒只是为了为用户创建通知.
我在日志中收到的消息如下:
W/ActivityManager: Background start not allowed: service Intent { act=xxx.xxx.xxx.action.NOTIFY_RIDE flg=0x4 cmp=xxx.xxx.xxx./xxx.xxx.xxx.service.MyAlarmService (has extras) }
Run Code Online (Sandbox Code Playgroud)
现在,谷歌自己的实施显然已被打破 - 即使我不想做任何繁重的背景工作,我也不能再使用这种技术了.但是,我应该如何在非常具体的时间点唤醒用户呢?(想想我的应用程序作为闹钟)
屏幕锁定时,我收到了传入的C2DM通知.我想唤醒屏幕并使用活动在锁定屏幕顶部显示通知消息.我正在从我的C2DM BroadcastReceiver启动通知活动,如下所示:
Intent new_intent= new Intent().setClass( context, EIAlertDialog.class );
new_intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );
new_intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
context.startActivity( new_intent );
Run Code Online (Sandbox Code Playgroud)
在通知Activity的onCreate方法中,我按如下方式唤醒屏幕:
PowerManager powerManager= (PowerManager)getSystemService( Context.POWER_SERVICE );
if (!powerManager.isScreenOn()) {
mWakeLock= powerManager.newWakeLock(
PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP,
"My Tag" )
mWakeLock.acquire();
}
Run Code Online (Sandbox Code Playgroud)
屏幕被唤醒,但在我解锁屏幕之前,通知活动不可见.
我意识到我可以使用下面的代码来避开锁定屏幕,但这是不可取的.我希望用户解锁手机,只要他/她有兴趣阅读/回复通知.
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
);
Run Code Online (Sandbox Code Playgroud) 我从BroadcastReceiver启动一个活动,它由alaram(RTC_WAKEUP类型)触发.在onCreate的那个活动我添加这些标志
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
);
Run Code Online (Sandbox Code Playgroud)
问题是有时(大约10%的情况)屏幕无法打开.警报被正确触发(我这里是通知的声音,这也是在接收器的onReceive()中触发的.然后,如果我按下电话的电源按钮,屏幕会亮起,显示我的活动,并立即关闭.那个,电源按钮工作正常.这发生在android 2.3.7上,这里是onReceive()方法
@Override
public void onReceive(Context context, Intent intent) {
m_Context = context;
Bundle extras = intent.getExtras();
final int id = extras.getInt("timer_id");
Intent activityIntent = new Intent(m_Context, MyActivity.class);
activityIntent.putExtra("timer_id", id);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
m_Context.startActivity(activityIntent);
// and now load the alarm sound and play it for the desired time
showFinishedNotification();
}
Run Code Online (Sandbox Code Playgroud)
我想避免使用PowerManager,因为它需要一个权限,并且标志是首选的方式.
什么可能是一个问题?logcat没有显示任何问题......
如何以可编程方式唤醒Android手机从睡眠状态(暂停到mem)?我不想获得任何唤醒锁,这意味着手机在禁用cpu的情况下进入"真正的"睡眠状态.我想我可以使用某种RTC(实时时钟)机制?
有没有人有任何例子?
谢谢.
Google Play开发者控制台说:
每日会话的显着百分比(超过1.3%)经历了过多的唤醒,从而将您的应用放在该指标的最低25%的应用中.但是,实际百分比可能低于1.3%,95%置信区间介于0.55%和11.82%之间.仅显示有效APK.
但是AlarmManager
,在最新的应用程序版本中,不会在项目的任何位置使用.什么可能会在控制台中引起这样的警告,除了AlarmManager
?