Android获取GPS时间

Android获取所在时区正确时间的方式有两种:

一:wifi获取时间

在联网且系统设置了自动获取时间自动获取时区的系统设置前提下,系统会自动更新正确的时间,当然如果你用了TextClockDateClock也会自动更新。

二:通过GPS获取时间。

2.1未联网且GPS可用的情况下,可以通过获取原生定位信息来获取所在地点的时间,实现如下:

注意,下面的代码时在Fragment里面实现的
/**  
* 用于获取GPS时间  
*/  
private LocationManager locationManager;  
/**  
* 取消后台定位的时间  
*/  
private final static int CANCEL_LOCATION_DELAY = 5 * 60 * 1000;  
/**  
* 避免多次取消定位和反注册  
*/  
private boolean isHadCancelLocation = false;

/**  
* 如果网络不可用,使用GPS进行刷新系统时间,系统时间更新后会自动更新TextClock和DateClock;如果有网络,理论上会自动刷新系统时间,所以不处理。  
*/  
private void initSystemTime() {  
    if(!NetworkHelper.isNetworkAvailable(getContext())){  
        getLocationBySystem();
        // 注意,这里请用原始Handler.postDelay代替,我用的自定义延时类。
        ArchTaskExecutor.getInstance().postToMainThreadDelay(cancelLocationRunnable, CANCEL_LOCATION_DELAY);  
    }  
}

// 注意,普通app需要申请定位权限,我的是系统级app,所以忽略。
@SuppressLint("MissingPermission")  
private void getLocationBySystem() {  
    XLog.i("无网络启动获取Gps定位");  
    locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);  
    // 注册位置监听器  
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);  
}  

/**  
* 通过GPS获取定位信息  
*/  
private final LocationListener locationListener = location -> {  
    if(null != location) {  
        // 就这里是关键获取代码,其实高德地图Api能自己触发系统时间的更新,不知道怎么实现的,只要打开他们的地图就可以,不管是第三方的高德地图app还是自己内嵌的高德地图api模块,理论上也是location.getTime()获取到的,不理解的是他们为什么有权限更新系统时间。
        long gpsTime = location.getTime();  
        cancelLocationUpdates();  
        XLog.i("Gps定位获取成功并注销定位监听,GPS时间 = " + gpsTime);  
        // 用过这个进行模拟测试,resetSystemTime(1712800932000L);显示的时间是2024-04-11 10:02:12,正确  
        resetSystemTime(gpsTime);  
    }  
};
  
private final Runnable cancelLocationRunnable = () -> {  
    XLog.i("获取定位超时,注销定位监听");  
    cancelLocationUpdates();  
};  
  
/**  
* 获取定位时间成功取消定位  
*/  
public void cancelLocationUpdates() {  
    XLog.i("注销定位监听" + isHadCancelLocation);  
    if (locationManager != null && !isHadCancelLocation) {  
        locationManager.removeUpdates(locationListener);  
        isHadCancelLocation = true;  
        locationManager = null;  
    }  
}  

/**
* 注意,我的是系统级app,所以忽略动态申请权限,普通应用无法设置系统时间但是可以参考取值。
* 系统级app配置 <uses-permission android:name="android.permission.SET_TIME"/> 权限即可
**/
@SuppressLint("MissingPermission")  
private void resetSystemTime(Long utcTimeMillis) {  
    try {  
        // 将UTC时间转换为Date对象  
        Date locationTime = new Date(utcTimeMillis);  
        long localTimeMillis = locationTime.getTime();  

        // 获取AlarmManager实例  
        AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);  
        // 设置系统时间(本地时间)  
        if (alarmManager != null) {  
            alarmManager.setTime(localTimeMillis);  
            XLog.i("重置系统时间成功" + localTimeMillis);  
        }  
     } catch (Exception e){  
        XLog.e("重置系统时间失败");  
    }  
}

2.2 如果你接入了高德地图SDK,也可以使用如下api去获取当前地点的时间:

/**  
* 这里目前获取到GPS返回的正确的时间  
* @throws Exception  
*/  
@SuppressLint("MissingPermission")  
public void getLocationByAMap() throws Exception {  
    // 高德地图的api  
    mlocationClient = new AMapLocationClient(getContext());  
    //初始化定位参数  
    mLocationOption = new AMapLocationClientOption();  
    //设置定位监听  
    mlocationClient.setLocationListener(new AMapLocationListener() {  
    @Override  
    public void onLocationChanged(AMapLocation aMapLocation) {  
        if (aMapLocation != null) {  
            if (aMapLocation.getErrorCode() == 0) {  
                //定位成功回调信息,设置相关消息  
                aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表  
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                Toast.makeText(getContext(), "时间戳为:" + aMapLocation.getTime(),Toast.LENGTH_SHORT).show();  
                Date date = new Date(aMapLocation.getTime());  
                String time = df.format(date);//定位时间  

                SimpleDateFormat dateFormat = new SimpleDateFormat("MM月dd日");  
                SimpleDateFormat hourMinuteSecondFormat = new SimpleDateFormat("HH:mm aa");  

                mlocationClient.stopLocation();// 获取成功停止定位  
                Toast.makeText(getContext(), "时间为:" + time + ";停止了定位并开始设置系统时间" + dateFormat + ";" + hourMinuteSecondFormat,Toast.LENGTH_SHORT).show();  

                // 需要配置 <uses-permission android:name="android.permission.SET_TIME"/>
                resetSystemTime(aMapLocation.getTime());  
            } else {  
                //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。  
                Log.e("AmapError", "location Error, ErrCode:"  
                + aMapLocation.getErrorCode() + ", errInfo:"  
                + aMapLocation.getErrorInfo());  
            }  
        }  
    }});  
    //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式   mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);  
    //设置定位间隔,单位毫秒,默认为2000ms  
    mLocationOption.setInterval(1000);  
    //设置定位参数  
    mlocationClient.setLocationOption(mLocationOption);  
    // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,  
    // 注意设置合适的定位时间的间隔(最小间隔支持为1000ms),并且在合适时间调用stopLocation()方法来取消定位请求  
    // 在定位结束后,在合适的生命周期调用onDestroy()方法  
    // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除  
    //启动定位  
    mlocationClient.startLocation();  
}

三:注意,预加载 GPS 并不是解决 Android 时间显示不准确的最佳方法。虽然 GPS 可以提供精确的时间和位置信息,但在大多数情况下,并不需要通过 GPS 来确保时间的准确性。通常,Android 设备会自动从网络提供商(例如移动网络或Wi-Fi连接)获取准确的时间和时区信息。这个过程通常称为网络时间同步。因此,如果你的自定义 Launcher 在获取时间时不准确,很可能是由于设备的网络时间同步设置出现了问题,而不是时区设置的问题。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用GPS 定位,首先,需要在清单文件(AndroidManifest.xml)中注册获取定位的权限: **1.获取位置管理器对象LocationManager** ``` import android.location.LocationManager; LocationManager lm; // lm =(LocationManager) this.getSystemService(Context`.LOCATION_SERVICE); // ``` **2.一般使用LocationManager的getLastKnownLocation(LocationManager.GPS_PROVIDER);方法获取Location对象** ``` String provider = LocationManager.GPS_PROVIDER;// 指定LocationManager的定位方法 Location location = locationManager.getLastKnownLocation(provider);// 调用getLastKnownLocation()方法获取当前的位置信息 ``` 不过不建议用这种方法,有几点原因: 一,在很多提供定位服务的应用程序中,不仅需要获取当前的位置信息,还需要监视位置的变化,在位置改变时调用特定的处理方法 ,其中LocationManager提供了一种便捷、高效的位置监视方法requestLocationUpdates(),可以根据位置的距离变化和时间间隔设定,产生位置改变事件的条件,这样可以避免因微小的距离变化而产生大量的位置改变事件 。 二,当你开启GPS,provider的值为GPS。这时的定位方式为GPS,由于GPS定位慢,所以它不可能立即返回你一个Location对象,所以就返回null了。 **3.推荐locationManager.requestLocationUpdates();方法** LocationManager中设定监听位置变化的代码如下: ``` lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10,new MyLocationListener()); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值