android-獲取網(wǎng)絡(luò)時(shí)間、獲取特定時(shí)區(qū)時(shí)間、時(shí)間同步的方法
最近整理出android-獲取網(wǎng)絡(luò)時(shí)間、獲取特定時(shí)區(qū)時(shí)間、時(shí)間同步的方法。具體如下:
方法一:
SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dff.setTimeZone(TimeZone.getTimeZone("GMT+08")); String ee = dff.format(new Date());
這個(gè)方法獲取的結(jié)果是24小時(shí)制的,月份也正確。
這個(gè)方法不隨手機(jī)時(shí)間的變動(dòng)而變動(dòng)。也就是說,即使手機(jī)設(shè)置成別的時(shí)區(qū),不是東八區(qū),這個(gè)方法返回的也照樣是北京時(shí)間?。?!這正是我在做項(xiàng)目的時(shí)候用到的方法??!徹底解決項(xiàng)目需求!
方法二:
Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss"); sdf.setTimeZone(TimeZone.getTimeZone("GMT+8")); String rt = sdf.format(calendar.getTime());
這個(gè)方法獲取的結(jié)果是不是24小時(shí)制的,月份也正確。
方法三:
public static String getLocalDatetimeString(String local) { Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(local)); cal.setTimeInMillis(Calendar.getInstance().getTimeInMillis()); String date = cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH); String time = cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND); return date + " " + time; }
方法調(diào)用:
String tt = getLocalDatetimeString("GMT+8");
代碼里也看出來了,這個(gè)在月份上加了一個(gè)1, 24小時(shí)制
以上三種方法驗(yàn)證如下:
import java.sql.Time; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; public class TimeTest { /** * @param args */ public static void main(String[] args) { method1(); method2(); method3(); } static void method1(){ SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dff.setTimeZone(TimeZone.getTimeZone("GMT+08")); String ee = dff.format(new Date()); System.out.println("ee="+ee); } static void method2(){ Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss"); sdf.setTimeZone(TimeZone.getTimeZone("GMT+8")); String rt = sdf.format(calendar.getTime()); System.out.println("TimeTest.method2() rt="+rt); } static void method3(){ String local = "GMT+8"; Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(local)); cal.setTimeInMillis(Calendar.getInstance().getTimeInMillis()); String date = cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH); String time = cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND); System.out.println("TimeTest.method3() date="+date+",time="+time); } }
結(jié)果如下:
本人采用的是第一種方法,因?yàn)榈谝环N方法的時(shí)間是不隨手機(jī)時(shí)間的設(shè)置而改變。
第二種方法也是可以的,不過時(shí)間小時(shí)是12進(jìn)制。
第四種方法:
網(wǎng)上還有這種方法獲取時(shí)間:
URL url=new URL("http://www.bjtime.cn");//取得資源對象 URLConnection uc=url.openConnection();//生成連接對象 uc.connect(); //發(fā)出連接 long ld=uc.getDate(); //取得網(wǎng)站日期時(shí)間 Date date=new Date(ld); //轉(zhuǎn)換為標(biāo)準(zhǔn)時(shí)間對象 //分別取得時(shí)間中的小時(shí),分鐘和秒,并輸出 System.out.print(date.getHours()+"時(shí)"+date.getMinutes()+"分"+date.getSeconds()+"秒");
這種方式需要開啟一個(gè)線程獲取時(shí)間,同時(shí)也存在著一種風(fēng)險(xiǎn)就是由于網(wǎng)絡(luò)問題,獲取不到響應(yīng)的問題。還有一個(gè)重要的問題件就是這個(gè)時(shí)間的獲取會(huì)隨著手機(jī)時(shí)區(qū)的改變而改變。
方法五:
通過網(wǎng)絡(luò)或者GPS的方式。
代碼:
LocationManager locMan = (LocationManager) this.getSystemService(MainActivity.LOCATION_SERVICE); //獲取最近一次知道的時(shí)間 long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();
或者實(shí)時(shí)的獲取時(shí)間:
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); //獲取當(dāng)前時(shí)間
當(dāng)我們使用requestLocationUpdates時(shí),我們需要實(shí)現(xiàn)LocationListener接口。
在LocationListen的回調(diào)onLocationChanged當(dāng)中獲取時(shí)間
@Override public void onLocationChanged(Location location) { // TODO Auto-generated method stub long time = location.getTime(); Date date = new Date(time); System.out.println(time + " NETWORK_PROVIDER " + date); // System.out.println(STANDARD_TIME + " "); }
這種方式是利用手機(jī)定位系統(tǒng)進(jìn)行時(shí)間的獲取,但是這種方式會(huì)隨著手機(jī)的設(shè)置的時(shí)區(qū)的變動(dòng)而改變。
第四種方式和第五種方式,我都在手機(jī)端進(jìn)行了驗(yàn)證,可以正常獲取時(shí)間。方式是沒有問題的。
既然有這么多方法,大家看著那種方式適合自己的需求,選擇相應(yīng)的方法。
我還是推薦第一種方法!簡單實(shí)用?。。。_^
今天再在本文基礎(chǔ)上補(bǔ)充一些內(nèi)容?,F(xiàn)在我的項(xiàng)目中有這樣一種需求:就是播放視頻的時(shí)候,特別是監(jiān)控視頻,我想要有時(shí)間限制,在一定時(shí)間內(nèi)可以觀看,超出設(shè)置的時(shí)間,不能觀看。
Android端對于這樣的需求,上面的幾種方法都不行了,因?yàn)樯厦娴姆椒ǘ几謾C(jī)系統(tǒng)有關(guān)系了,當(dāng)我改變手機(jī)系統(tǒng)的時(shí)間,時(shí)區(qū)等都會(huì)造成獲取的時(shí)間不對應(yīng),跟服務(wù)器時(shí)間不對。怎么辦呢?有辦法!??!
我是這樣做的,當(dāng)獲取到信息的時(shí)候,比如視頻節(jié)點(diǎn)信息的時(shí)候,服務(wù)器順帶著把服務(wù)器當(dāng)前的時(shí)間返回來,有了服務(wù)器的時(shí)間,剩下的我就利用用戶操作的時(shí)間間隔,加上服務(wù)器的時(shí)間不就是手機(jī)所在地當(dāng)前的時(shí)間嗎?
那么時(shí)間間隔怎么算呢?請看下面的SystemClock類幾個(gè)方法:
1、System.currentTimeMillis()是一個(gè)標(biāo)準(zhǔn)的“墻”時(shí)鐘(時(shí)間和日期),表示從紀(jì)元到現(xiàn)在的毫秒數(shù)。該墻時(shí)鐘能夠被用戶或電話網(wǎng)絡(luò)(見setCurrentTimeMillis(long))設(shè)置,所以該時(shí)間可能會(huì)向前或向后不可預(yù)知地跳越。該時(shí)鐘應(yīng)該僅僅被使用在當(dāng)現(xiàn)實(shí)世界的對應(yīng)的日期和時(shí)間是重要的情況,例如一個(gè)日歷或鬧鐘應(yīng)用程序。而間隔時(shí)間和經(jīng)過時(shí)間應(yīng)該使用不同的時(shí)鐘。如果你使用System.currentTimeMillis(),可以考慮監(jiān)聽ACTION為ACTION_TIME_TICK、 ACTION_TIME_CHANGED、ACTION_TIMEZONE_CHANGED 的廣播去監(jiān)聽時(shí)間變化。
2、uptimeMillis()表示自系統(tǒng)啟動(dòng)時(shí)開始計(jì)數(shù),以毫秒為單位。返回的是從系統(tǒng)啟動(dòng)到現(xiàn)在這個(gè)過程中的處于非休眠期的時(shí)間。當(dāng)系統(tǒng)進(jìn)入深度睡眠時(shí)(CPU關(guān)閉,設(shè)備變黑,等待外部輸入裝置)該時(shí)鐘會(huì)停止。但是該時(shí)鐘不會(huì)被時(shí)鐘調(diào)整,閑置或其他節(jié)能機(jī)所影響。這是大多數(shù)間隔時(shí)間的基本點(diǎn),例如Thread.sleep(millls)、Object.wait(millis)和System.nanoTime()。該時(shí)鐘被保證是單調(diào)的,適用于檢測不包含休眠的間隔時(shí)間的情況。大多數(shù)的方法接受一個(gè)時(shí)間戳的值除了uptimeMillis()時(shí)鐘。
3、elapsedRealtime() and elapsedRealtimeNanos() 返回系統(tǒng)啟動(dòng)到現(xiàn)在的時(shí)間,包含設(shè)備深度休眠的時(shí)間。該時(shí)鐘被保證是單調(diào)的,即使CPU在省電模式下,該時(shí)間也會(huì)繼續(xù)計(jì)時(shí)。該時(shí)鐘可以被使用在當(dāng)測量時(shí)間間隔可能跨越系統(tǒng)睡眠的時(shí)間段。
有幾種機(jī)制控制事件發(fā)生的時(shí)間:
1、標(biāo)準(zhǔn)的方法像Thread.sleep(millis) 和 Object.wait(millis)總是可用的,這些方法使用的是uptimeMillis()時(shí)鐘,如果設(shè)備進(jìn)入深度休眠,剩余的時(shí)間將被推遲直到系統(tǒng)喚醒。這些同步方法可能被Thread.interrupt()中斷,并且你必須處理InterruptedException異常。
2、SystemClock.sleep(millis)是一個(gè)類似于Thread.sleep(millis)的實(shí)用方法,但是它忽略InterruptedException異常。使用該函數(shù)產(chǎn)生的延遲如果你不使用Thread.interrupt(),因?yàn)樗鼤?huì)保存線程的中斷狀態(tài)。
3、Handler可以在一個(gè)相對或者絕對的時(shí)間設(shè)置異步回調(diào),Handler類對象也使用uptimeMillis()時(shí)鐘,而且需要一個(gè)loop(經(jīng)常出現(xiàn)在GUI程序中)。
4、AlarmManager可以觸發(fā)一次或重復(fù)事件,即使設(shè)備深度休眠或者應(yīng)用程序沒有運(yùn)行。事件可以選擇用 currentTimeMillis或者elapsedRealtime()(ELAPSED_REALTIME)來設(shè)置時(shí)間,當(dāng)事件發(fā)生會(huì)觸發(fā)一個(gè)廣播。
方法:
1、public static long currentThreadTimeMillis () 返在當(dāng)前線程運(yùn)行的毫秒數(shù)。
2、public static long elapsedRealtime () 返回系統(tǒng)啟動(dòng)到現(xiàn)在的毫秒數(shù),包含休眠時(shí)間。
3、public static long elapsedRealtimeNanos () 返回系統(tǒng)啟動(dòng)到現(xiàn)在的納秒數(shù),包含休眠時(shí)間。
4、public static boolean setCurrentTimeMillis (long millis) 設(shè)置當(dāng)前的”墻”時(shí)間,要求調(diào)用進(jìn)程有許可權(quán)限。返回是否成功。
5、public static void sleep (long ms) 等待給定的時(shí)間。和Thread.sleep(millis)類似,但是它不會(huì)拋出InterruptedException異常。事件被推遲到下一個(gè)中斷操作。該方法直到指定的時(shí)間過去才返回。
6、public static long uptimeMillis () 返回系統(tǒng)啟動(dòng)到現(xiàn)在的毫秒數(shù),不包含休眠時(shí)間。就是說統(tǒng)計(jì)系統(tǒng)啟動(dòng)到現(xiàn)在的非休眠期時(shí)間。
這些方法大家看看就知道啦。
剩下的就是計(jì)算事件間隔了:
public static long elapsedRealtime () 返回系統(tǒng)啟動(dòng)到現(xiàn)在的毫秒數(shù),包含休眠時(shí)間
這個(gè)方法就可以計(jì)算從服務(wù)器返回時(shí)間到用戶操作,播放視頻這一段時(shí)間的時(shí)間間隔。有個(gè)這個(gè)不就可以做到時(shí)間不受手機(jī)系統(tǒng)的限制了嗎?
/** * * @param ts 形如yyyy-MM-dd hh:mm:ss * @param intervalTime long類型 * @return String HH:mm:ss */ @SuppressLint("SimpleDateFormat") public static String getTime(String ts,long intervalTime){ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); Timestamp t=null; String tt=""; try { t = new Timestamp(format.parse(ts).getTime()); long ss = t.getTime(); long st = ss+intervalTime; tt= getTime(st); } catch (java.text.ParseException e) { e.printStackTrace(); } return tt; } /** * @param mis * @return HH:mm:ss */ @SuppressLint("SimpleDateFormat") public static String getTime(long mis){ SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String ee = dff.format(new Date(mis)); return ee.substring(11); }
上面的方法中, ts參數(shù)就是服務(wù)器返回的當(dāng)前時(shí)間,形如yyyy-MM-dd hh:mm:ss的字符串intervalTime參數(shù),是獲取到服務(wù)器響應(yīng)到用戶進(jìn)行操作的時(shí)間間隔,就是使用上面的elapsedRealtime ()方法獲取兩次時(shí)間計(jì)算得到。
方法的返回值String,形如 HH:mm:ss,這樣返回字符串方便比較時(shí)間字符。由于視頻事件限制,就是時(shí)分秒,不可能涉及到年月日,所以這里就是直接返回時(shí)分秒。
有了這個(gè)方法,完美解決了android APP與服務(wù)器時(shí)間保持基本一致的需求。但是還是存在一定的問題的,因?yàn)榉?wù)器返回時(shí)間不定,可能長可能短,所以時(shí)間并不會(huì)和服務(wù)器的當(dāng)前時(shí)間分秒不差,總會(huì)有延時(shí),但是這個(gè)延時(shí)可以接受,大概最多在10秒左右??梢栽跁r(shí)間間隔上稍微加一點(diǎn)就可以了?;揪蜐M足需求了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android異步方法以同步方式實(shí)現(xiàn)
- Android多線程之同步鎖的使用
- Android seekbar(自定義)控制音量同步更新
- android中ListView數(shù)據(jù)刷新時(shí)的同步方法
- Android實(shí)現(xiàn)歌曲播放時(shí)歌詞同步顯示具體思路
- Android獲取點(diǎn)擊屏幕的位置坐標(biāo)
- Android 5.0+ 屏幕錄制實(shí)現(xiàn)的示例代碼
- Android自適應(yīng)不同屏幕大小的全部方法
- Android6.0開發(fā)中屏幕旋轉(zhuǎn)原理與流程分析
- Android手機(jī)屏幕同步工具asm.jar
相關(guān)文章
Android進(jìn)階NestedScroll嵌套滑動(dòng)機(jī)制實(shí)現(xiàn)吸頂效果詳解
這篇文章主要為大家介紹了Android進(jìn)階NestedScroll嵌套滑動(dòng)機(jī)制實(shí)現(xiàn)吸頂效果詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01使用SharedPreferences在Android存儲對象詳細(xì)代碼
這篇文章主要介紹了使用SharedPreferences在Android存儲對象并附上詳細(xì)代碼,下面文章內(nèi)容較少,大多以代碼的形式體現(xiàn),需要的小伙伴可以參考一下,希望對你有所幫助2021-11-11Android shell命令行中過濾adb logcat輸出的方法
本文主要介紹Android shell命令行中過濾adb logcat輸出,這里詳細(xì)說明了shell 命令過濾logcat 輸出內(nèi)容,有需要的小伙伴可以參考下2016-08-08Flutter 自定義Drawer 滑出位置的大小實(shí)例代碼詳解
這篇文章主要介紹了Flutter 自定義Drawer 滑出位置的大小,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04詳解關(guān)于Android Studio中安裝和gradle的一些坑
本篇文章主要介紹了關(guān)于Android Studio中安裝和gradle的一些坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10Android-實(shí)現(xiàn)切換Fragment頁功能的實(shí)現(xiàn)代碼
本篇文章主要介紹了Android-實(shí)現(xiàn)切換Fragment頁功能的實(shí)現(xiàn)代碼,具有一定的參加價(jià)值,有興趣的可以了解一下。2017-02-02Android開發(fā)疫情查詢app(實(shí)例代碼)
這篇文章主要介紹了用Android開發(fā)一個(gè)疫情查詢的APP,文中代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06