android 6.0 熄屏后导致GPS 位置 监听无法获取

本文探讨了在小米手机和华为6.0系统上遇到的应用程序在熄屏后GPS位置信息更新停止的问题。文中提供了多种解决方案,包括使用WakeLock、处理Doze模式及AppStandby模式的限制,并介绍了如何设置应用进入电池优化白名单。
摘要由CSDN通过智能技术生成

程序在进行导航时需要获取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,

似乎在其他牌子的手机上 设置会有不同 不过应该都是在电量管理模块下面的。

Android锁屏无法继续定位问题 产生问题的原因: 手机锁屏后,Android系统为了省电以及减少CPU消耗,在一段间后会将手机进入休眠状态。此的服务以及线程等都会停止。 最近就这个问题,阅读了很多代码以及官方文档,下面就说下最近都尝试过的方式,可能其中有些您实现了,我这边没实现,望见谅。本文采用的高德定位。 一、PowerManager.WakeLock (1)直接强制当前页面cpu运行 private PowerManager pm; private PowerManager.WakeLock wakeLock; @Override public void onCreate() { super.onCreate(); //创建PowerManager对象 pm = (PowerManager) getSystemService(Context.POWER_SERVICE); //保持cpu一直运行,不管屏幕是否黑屏 wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CPUKeepRunning"); wakeLock.acquire(); } @Override public void onDestroy() { wakeLock.release(); super.onDestroy(); } 这个写法我表示并没有什么用,并不能强制cpu持续运行。 (2)WakefulBroadcastReceiver public class WLWakefulReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // String extra = intent.getStringExtra("msg"); Intent serviceIntent = new Intent(context, MyIntentService.class); serviceIntent.putExtra("msg", extra); startWakefulService(context, serviceIntent); } } WakefulBroadcastReceiver 内部的原理也是PowerManager,注册广播8.0的请动态注册,静态没有用。广播注册完了之后,写一个服务用来与广播互动。 public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override public void onCreate() { super.onCreate(); } @Override protected void onHandleIntent(@Nullable final Intent intent) { //子线程中执行 Log.i("MyIntentService", "onHandleIntent"); String extra = intent.getStringExtra("msg"); new Thread(new Runnable() { @Override public void run() { LocationUtil.getInstance().startLocation(LocationUtil.NULL, new LocationUtil.OnLocationBack() { @Override public void back(AMapLocation aMapLocation, String backString) { Log.e("定位結果", aMapLocation.getAddress()+""); 定位结果操作,我这边是把定位候保存到数据库里面。 } }); } }).start(); Log.i("MyIntentService", "onHandleIntent:"+extra); //调用completeWakefulIntent来释放唤醒锁。 // WLWakefulReceiver.completeWakefulIntent(intent); } } 注册
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值