Android獲取所在時(shí)區(qū)時(shí)間的兩種方式
Android獲取所在時(shí)區(qū)正確時(shí)間的方式有兩種:
一:wifi獲取時(shí)間
在聯(lián)網(wǎng)且系統(tǒng)設(shè)置了自動(dòng)獲取時(shí)間,自動(dòng)獲取時(shí)區(qū)的系統(tǒng)設(shè)置前提下,系統(tǒng)會(huì)自動(dòng)更新正確的時(shí)間,當(dāng)然如果你用了TextClock
和DateClock
也會(huì)自動(dòng)更新。
二:通過(guò)GPS獲取時(shí)間。
2.1 在未聯(lián)網(wǎng)且GPS可用的情況下,可以通過(guò)獲取原生定位信息來(lái)獲取所在地點(diǎn)的時(shí)間,實(shí)現(xiàn)如下:
注意,下面的代碼時(shí)在Fragment里面實(shí)現(xiàn)的
/** * 用于獲取GPS時(shí)間 */ private LocationManager locationManager; /** * 取消后臺(tái)定位的時(shí)間 */ private final static int CANCEL_LOCATION_DELAY = 5 * 60 * 1000; /** * 避免多次取消定位和反注冊(cè) */ private boolean isHadCancelLocation = false; /** * 如果網(wǎng)絡(luò)不可用,使用GPS進(jìn)行刷新系統(tǒng)時(shí)間,系統(tǒng)時(shí)間更新后會(huì)自動(dòng)更新TextClock和DateClock;如果有網(wǎng)絡(luò),理論上會(huì)自動(dòng)刷新系統(tǒng)時(shí)間,所以不處理。 */ private void initSystemTime() { if(!NetworkHelper.isNetworkAvailable(getContext())){ getLocationBySystem(); // 注意,這里請(qǐng)用原始Handler.postDelay代替,我用的自定義延時(shí)類(lèi)。 ArchTaskExecutor.getInstance().postToMainThreadDelay(cancelLocationRunnable, CANCEL_LOCATION_DELAY); } } // 注意,普通app需要申請(qǐng)定位權(quán)限,我的是系統(tǒng)級(jí)app,所以忽略。 @SuppressLint("MissingPermission") private void getLocationBySystem() { XLog.i("無(wú)網(wǎng)絡(luò)啟動(dòng)獲取Gps定位"); locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE); // 注冊(cè)位置監(jiān)聽(tīng)器 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); } /** * 通過(guò)GPS獲取定位信息 */ private final LocationListener locationListener = location -> { if(null != location) { // 就這里是關(guān)鍵獲取代碼,其實(shí)高德地圖Api能自己觸發(fā)系統(tǒng)時(shí)間的更新,不知道怎么實(shí)現(xiàn)的,只要打開(kāi)他們的地圖就可以,不管是第三方的高德地圖app還是自己內(nèi)嵌的高德地圖api模塊,理論上也是location.getTime()獲取到的,不理解的是他們?yōu)槭裁从袡?quán)限更新系統(tǒng)時(shí)間。 long gpsTime = location.getTime(); cancelLocationUpdates(); XLog.i("Gps定位獲取成功并注銷(xiāo)定位監(jiān)聽(tīng),GPS時(shí)間 = " + gpsTime); // 用過(guò)這個(gè)進(jìn)行模擬測(cè)試,resetSystemTime(1712800932000L);顯示的時(shí)間是2024-04-11 10:02:12,正確 resetSystemTime(gpsTime); } }; private final Runnable cancelLocationRunnable = () -> { XLog.i("獲取定位超時(shí),注銷(xiāo)定位監(jiān)聽(tīng)"); cancelLocationUpdates(); }; /** * 獲取定位時(shí)間成功取消定位 */ public void cancelLocationUpdates() { XLog.i("注銷(xiāo)定位監(jiān)聽(tīng)" + isHadCancelLocation); if (locationManager != null && !isHadCancelLocation) { locationManager.removeUpdates(locationListener); isHadCancelLocation = true; locationManager = null; } } /** * 注意,我的是系統(tǒng)級(jí)app,所以忽略動(dòng)態(tài)申請(qǐng)權(quán)限,普通應(yīng)用無(wú)法設(shè)置系統(tǒng)時(shí)間但是可以參考取值。 * 系統(tǒng)級(jí)app配置 <uses-permission android:name="android.permission.SET_TIME"/> 權(quán)限即可 **/ @SuppressLint("MissingPermission") private void resetSystemTime(Long utcTimeMillis) { try { // 將UTC時(shí)間轉(zhuǎn)換為Date對(duì)象 Date locationTime = new Date(utcTimeMillis); long localTimeMillis = locationTime.getTime(); // 獲取AlarmManager實(shí)例 AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE); // 設(shè)置系統(tǒng)時(shí)間(本地時(shí)間) if (alarmManager != null) { alarmManager.setTime(localTimeMillis); XLog.i("重置系統(tǒng)時(shí)間成功" + localTimeMillis); } } catch (Exception e){ XLog.e("重置系統(tǒng)時(shí)間失敗"); } }
2.2 如果你接入了高德地圖SDK,也可以使用如下api去獲取當(dāng)前地點(diǎn)的時(shí)間:
/** * 這里目前獲取到GPS返回的正確的時(shí)間 * @throws Exception */ @SuppressLint("MissingPermission") public void getLocationByAMap() throws Exception { // 高德地圖的api mlocationClient = new AMapLocationClient(getContext()); //初始化定位參數(shù) mLocationOption = new AMapLocationClientOption(); //設(shè)置定位監(jiān)聽(tīng) mlocationClient.setLocationListener(new AMapLocationListener() { @Override public void onLocationChanged(AMapLocation aMapLocation) { if (aMapLocation != null) { if (aMapLocation.getErrorCode() == 0) { //定位成功回調(diào)信息,設(shè)置相關(guān)消息 aMapLocation.getLocationType();//獲取當(dāng)前定位結(jié)果來(lái)源,如網(wǎng)絡(luò)定位結(jié)果,詳見(jiàn)定位類(lèi)型表 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Toast.makeText(getContext(), "時(shí)間戳為:" + aMapLocation.getTime(),Toast.LENGTH_SHORT).show(); Date date = new Date(aMapLocation.getTime()); String time = df.format(date);//定位時(shí)間 SimpleDateFormat dateFormat = new SimpleDateFormat("MM月dd日"); SimpleDateFormat hourMinuteSecondFormat = new SimpleDateFormat("HH:mm aa"); mlocationClient.stopLocation();// 獲取成功停止定位 Toast.makeText(getContext(), "時(shí)間為:" + time + ";停止了定位并開(kāi)始設(shè)置系統(tǒng)時(shí)間" + dateFormat + ";" + hourMinuteSecondFormat,Toast.LENGTH_SHORT).show(); // 需要配置 <uses-permission android:name="android.permission.SET_TIME"/> resetSystemTime(aMapLocation.getTime()); } else { //顯示錯(cuò)誤信息ErrCode是錯(cuò)誤碼,errInfo是錯(cuò)誤信息,詳見(jiàn)錯(cuò)誤碼表。 Log.e("AmapError", "location Error, ErrCode:" + aMapLocation.getErrorCode() + ", errInfo:" + aMapLocation.getErrorInfo()); } } }}); //設(shè)置定位模式為高精度模式,Battery_Saving為低功耗模式,Device_Sensors是僅設(shè)備模式 mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); //設(shè)置定位間隔,單位毫秒,默認(rèn)為2000ms mLocationOption.setInterval(1000); //設(shè)置定位參數(shù) mlocationClient.setLocationOption(mLocationOption); // 此方法為每隔固定時(shí)間會(huì)發(fā)起一次定位請(qǐng)求,為了減少電量消耗或網(wǎng)絡(luò)流量消耗, // 注意設(shè)置合適的定位時(shí)間的間隔(最小間隔支持為1000ms),并且在合適時(shí)間調(diào)用stopLocation()方法來(lái)取消定位請(qǐng)求 // 在定位結(jié)束后,在合適的生命周期調(diào)用onDestroy()方法 // 在單次定位情況下,定位無(wú)論成功與否,都無(wú)需調(diào)用stopLocation()方法移除請(qǐng)求,定位sdk內(nèi)部會(huì)移除 //啟動(dòng)定位 mlocationClient.startLocation(); }
三:注意,預(yù)加載 GPS 并不是解決 Android 時(shí)間顯示不準(zhǔn)確的最佳方法。雖然 GPS 可以提供精確的時(shí)間和位置信息,但在大多數(shù)情況下,并不需要通過(guò) GPS 來(lái)確保時(shí)間的準(zhǔn)確性。通常,Android 設(shè)備會(huì)自動(dòng)從網(wǎng)絡(luò)提供商(例如移動(dòng)網(wǎng)絡(luò)或Wi-Fi連接)獲取準(zhǔn)確的時(shí)間和時(shí)區(qū)信息。這個(gè)過(guò)程通常稱(chēng)為網(wǎng)絡(luò)時(shí)間同步。因此,如果你的自定義 Launcher 在獲取時(shí)間時(shí)不準(zhǔn)確,很可能是由于設(shè)備的網(wǎng)絡(luò)時(shí)間同步設(shè)置出現(xiàn)了問(wèn)題,而不是時(shí)區(qū)設(shè)置的問(wèn)題。
以上就是Android獲取所在時(shí)區(qū)時(shí)間的兩種方式的詳細(xì)內(nèi)容,更多關(guān)于Android獲取時(shí)間的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android自定義View實(shí)現(xiàn)進(jìn)度條動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)進(jìn)度條動(dòng)畫(huà),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08淺析Android中常見(jiàn)三種彈框在項(xiàng)目中的應(yīng)用
這篇文章主要介紹了淺析Android中常見(jiàn)三種彈框在項(xiàng)目中的應(yīng)用,需要的朋友可以參考下2017-03-03Android自定義豎排TextView實(shí)現(xiàn)實(shí)例
這篇文章主要介紹了Android自定義豎排TextView實(shí)現(xiàn)實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05android SectorMenuView底部導(dǎo)航扇形菜單的實(shí)現(xiàn)代碼
這篇文章主要介紹了android SectorMenuView底部導(dǎo)航扇形菜單的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02Android 無(wú)障礙全局懸浮窗實(shí)現(xiàn)示例
本文主要介紹了Android 無(wú)障礙全局懸浮窗實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06android PopupWindow 和 Activity彈出窗口實(shí)現(xiàn)方式
本人小菜一個(gè)。目前只見(jiàn)過(guò)兩種彈出框的實(shí)現(xiàn)方式,第一種是最常見(jiàn)的PopupWindow,第二種也就是Activity的方式是前幾天才見(jiàn)識(shí)過(guò),需要的朋友可以參考下2012-11-11Android framework ATMS啟動(dòng)流程
這篇文章主要為大家介紹了Android framework ATMS啟動(dòng)流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03