程序在进行导航时需要获取GPS 位置信息,使用小米手机和华为 (6.0)系统,测试发现app在熄屏后差不多一分钟左右,位置信息不再改变。当点亮手机屏幕之后一切又恢复正常。之前在6.0以下也会出现此类状况,经设置wakelock后不再出现。
PowerManager pm;
PowerManager.WakeLock wakeLock;
//防止手机进入休眠状态
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock"); //保持CPU 运转,屏幕和键盘灯有可能是关闭的。
wakeLock.acquire(); //构建activity时获取到 wakelock
记得调用wakeLock.release();方法释放掉。
在安卓6.0又发现了doze机制…
如果用户一段时间没有操作设备,或者屏幕熄屏 没有连接电源 就会进入
doze模式里会有这么一些限制:
•网络连接会被禁止
•Wake Lock会被屏蔽
•AlarmManager定时任务延迟到下一个maintenancewindow进行处理,除非使用AlarmManager提供的方法:setAndAllowWhileIdle()或者setExactAndAllowWhileIdle()
•系统将不扫描热点WIFI
•同步工作将被禁止
•不允许JobScheduler进行任务调度
以下操作会退出doze
•用户唤醒移动装置,打开屏幕
•设备连接电源
除了doze模式 还有一个App standby模式
App Standby:这个概念则是针对于应用的,当App进入AppStandby状态后,也会受到网络等状态的限制
进入条件
当用户不触摸使用应用程序一段时间时,该应用程序处于AppStandby状态,系统将把该App标志为空闲状态
退出条件
用户主动启动该App
该App当前有一个前台进程(或包含一个活动的前台服务,或被另一个activity或前台service使用)
App生成一个用户所能在锁屏或通知托盘看到的Notification
而当用户设备插入电源时,系统将会释放App的待机状态,允许他们自由的连接网络及其执行未完成的工作和同步。如果设备空闲很长一段时间,系统将允许空闲App一天一次访问网络。
Doze模式与App Standby模式的区别
Doze模式需要屏幕关闭(通常晚上睡觉或长时间屏幕关闭才会进入)
App Standby不需要屏幕关闭,App进入后台一段时间也会受到连接网络等限制。
百度到下面的方法可以设置程序白名单
在AndroidManifest中加入以下权限
<android:uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
然后在需要加入白名单的地方加入如下代码:
Intent ignore = new Intent();
ignore.setData(Uri.parse("package:"+this.getPackageName()));
ignore.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
this.startActivity(ignore);
但是好像设置之后 依然没有用 小米手机6.0系统的
然后又发现以下方法使用alarmManager
//注册一个广播
AlarmManager alarmManager;
alarmManager= (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent("alarm");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, 20000, pendingIntent);
BroadcastReceiver alarB = new BroadcastReceiver() {
int i = 0;
@Override
public void onReceive(Context context, Intent intent) {
if ("alarm".equals(intent.getAction())) {
LogUtils.i("gps,收到alar消息 " + i);
i += 1;
if (ActivityCompat.checkSelfPermission(NaviExtendActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(NaviExtendActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
//这里就是请求位置和GPS监听
// lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
// lm.addGpsStatusListener(gpsStatusListener);
//判断GPS状态是否开启
boolean gpsEnabled = Settings.Secure.isLocationProviderEnabled( getContentResolver(), LocationManager.GPS_PROVIDER );
PowerManager powermanager;
powermanager = (PowerManager) getSystemService(Context.POWER_SERVICE);
LogUtils.i("gps,收到alar消息 "+i+" GPS状态 "+gpsEnabled +" "+"屏幕状态"+ powermanager.isScreenOn()+ lm.getProvider(LocationManager.GPS_PROVIDER)+" "+ lm.getGpsStatus(null));
alarm();
}
}
};
//然后注册广播
IntentFilter alarintentFilter=new IntentFilter(“alarm”);
registerReceiver(alarB,alarintentFilter);
到这里还没有彻底解决gps不会接受到回调的问题,小米测试机在熄屏后一分钟左右还是会无法获取到GPS和位置的回调,设置白名单优化也没有起作用,这个小米手机再需要通过手动设置手机电量优化 将APP设置为无限制并后台启动定位,然后测试终于OK,
似乎在其他牌子的手机上 设置会有不同 不过应该都是在电量管理模块下面的。