android获取所在时区正确时间的方式有两种:
一:wifi获取时间
在联网且系统设置了自动获取时间,自动获取时区的系统设置前提下,系统会自动更新正确的时间,当然如果你用了textclock和dateclock也会自动更新。
二:通过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 在获取时间时不准确,很可能是由于设备的网络时间同步设置出现了问题,而不是时区设置的问题。
以上就是android获取所在时区时间的两种方式的详细内容,更多关于android获取时间的资料请关注代码网其它相关文章!
发表评论