每日一記—獲取Bing每一日一圖實現Android歡迎頁(二)
日期2018.9.12
第二部分:獲取bing每日一圖
通過訪問 http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=5&mkt=zh-CN 可以得到一組json資料,如下:
{"images": [{"startdate":"20180911", "fullstartdate":"201809111600", "enddate":"20180912", "url":"/az/hprichbg/rb/BlackBrowed_ZH-CN11903207028_1920x1080.jpg", "urlbase":"/az/hprichbg/rb/BlackBrowed_ZH-CN11903207028", "copyright":"回到福克蘭群島的黑眉信天翁 (© Cultura RM/Alamy)", "copyrightlink":"http://www.bing.com/search?q=%E9%BB%91%E7%9C%89%E4%BF%A1%E5%A4%A9%E7%BF%81&form=hpcapt&mkt=zh-cn", "title":"", "quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20180911_BlackBrowed%22&FORM=HPQUIZ", "wp":true, "hsh":"12948b177d0c26492dcb1049700602ea", "drk":1,"top":1,"bot":1,"hs":[]}, {"startdate":"20180910", "fullstartdate":"201809101600", "enddate":"20180911", "url":"/az/hprichbg/rb/ShinjukuKiku_ZH-CN8446848393_1920x1080.jpg", "urlbase":"/az/hprichbg/rb/ShinjukuKiku_ZH-CN8446848393", "copyright":"管物菊,日本東京都新宿區 (© I love Photo and Apple./Getty images)", "copyrightlink":"http://www.bing.com/search?q=%E7%AE%A1%E7%89%A9%E8%8F%8A&form=hpcapt&mkt=zh-cn", "title":"","quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20180910_ShinjukuKiku%22&FORM=HPQUIZ", "wp":true, "hsh":"c79ceca8823a08c1c93373f4b26c9996", "drk":1,"top":1,"bot":1,"hs":[]}, {"startdate":"20180909", "fullstartdate":"201809091600", "enddate":"20180910", "url":"/az/hprichbg/rb/Honeycomb_ZH-CN7204448210_1920x1080.jpg", "urlbase":"/az/hprichbg/rb/Honeycomb_ZH-CN7204448210", "copyright":"蜂巢 (© Heidi and Hans-Juergen Koch/Minden Pictures)", "copyrightlink":"http://www.bing.com/search?q=%E8%9C%82%E5%B7%A2&form=hpcapt&mkt=zh-cn", "title":"", "quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20180909_Honeycomb%22&FORM=HPQUIZ", "wp":true, "hsh":"956060a94d566e18964ea6aff9a7a2aa", "drk":1,"top":1,"bot":1,"hs":[]}, {"startdate":"20180908", "fullstartdate":"201809081600", "enddate":"20180909", "url":"/az/hprichbg/rb/RoyalOntarioMuseum_ZH-CN10362892998_1920x1080.jpg", "urlbase":"/az/hprichbg/rb/RoyalOntarioMuseum_ZH-CN10362892998", "copyright":"皇家安大略博物館,加拿大多倫多 (© Ken Straiton/Aurora Photos)", "copyrightlink":"http://www.bing.com/search?q=%E7%9A%87%E5%AE%B6%E5%AE%89%E5%A4%A7%E7%95%A5%E5%8D%9A%E7%89%A9%E9%A6%86&form=hpcapt&mkt=zh-cn", "title":"", "quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20180908_RoyalOntarioMuseum%22&FORM=HPQUIZ", "wp":false, "hsh":"ed4c961d60ff9e9ebc17f94a4fa5e8cb", "drk":1,"top":1,"bot":1,"hs":[]}, {"startdate":"20180907", "fullstartdate":"201809071600", "enddate":"20180908", "url":"/az/hprichbg/rb/TrinityLibrary_ZH-CN10332583093_1920x1080.jpg", "urlbase":"/az/hprichbg/rb/TrinityLibrary_ZH-CN10332583093", "copyright":"都柏林三一學院圖書館,愛爾蘭 (© Nigel Hicks/Robert Harding/Aurora Photos)", "copyrightlink":"http://www.bing.com/search?q=%E4%B8%89%E4%B8%80%E5%AD%A6%E9%99%A2%E5%9B%BE%E4%B9%A6%E9%A6%86&form=hpcapt&mkt=zh-cn", "title":"", "quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20180907_TrinityLibrary%22&FORM=HPQUIZ", "wp":false, "hsh":"e5b5bf66170be8116ecd6a6f73fb1e1e", "drk":1,"top":1,"bot":1,"hs":[]}], "tooltips":{ "loading":"正在載入...", "previous":"上一個影象", "next":"下一個影象", "walle":"此圖片不能下載用作桌布。", "walls":"下載今日美圖。僅限用作桌面桌布。"}}
我們看到得到JSON資料中 每個組內都一個url屬性,即"url":"/az/hprichbg/rb/BlackBrowed_ZH-CN11903207028_1920x1080.jpg",我們通過這個URL就可以得到當前這個組裡的圖片,需要注意的事,這個URL缺少網址的前半部分,訪問的時候需要加上“http://www.bing.com”,即網址為:http://www.bing.com/az/hprichbg/rb/BlackBrowed_ZH-CN11903207028_1920x1080.jpg。那麼需要用到的邏輯程式碼就清楚了,第一步是獲取到這個JSON資料;第二步是解析這個JSON資料;第三步是將得到的圖片URL轉成bitmap;第四步是將轉化的bitmap賦值給背景圖片,並將這個bitmap儲存在本地,這樣可以在再次開啟程式的時候直接訪問本地圖片,不必再重複下載。
第一步:獲取JSON資料
這裡我使用的是HttpURLConnection進行的連結,程式碼如下:
private String getData(String path){ String data=""; try{ URL url = new URL(path); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.setConnectTimeout(5000); urlConn.connect(); if (urlConn.getResponseCode() == 200) { data = readStream(urlConn.getInputStream()); Log.i("TAG", "請求成功"); } else { Log.i("TAG", "資料請求失敗"); } urlConn.disconnect(); }catch (Exception e){ e.printStackTrace(); } return data; } private String readStream(InputStream inputStream) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); outputStream.flush(); } outputStream.close(); inputStream.close(); return outputStream.toString(); }
第二步:解析JSON資料,得到圖片URL
通過觀察之前得到的JSON資料,我們可以看出,這組資料裡包含了多個URL,也就是說存在多個日期的圖片,而我們想得到的是當天日期的圖片,因此,觀察可以看出,第一個URL是最新的圖片,因此在得到第一個URL資料的時候,就將這個URL返回就好了,無需再判斷其他的URL,程式碼如下:
private String resolveData(String data){
String url="";
try{
JSONArray jsonArray=new JSONObject(data).getJSONArray("images");
for (int i=0;i<jsonArray.length();i++){
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
if (jsonObject.has("url")){
url=jsonObject.getString("url");
break;
}
}
}catch (JSONException e){
e.printStackTrace();
}
return url;
}
第三步:將圖片URL轉化為bitmap
注意在URL前面加上“http://www.bing.com”,程式碼如下:(這裡有一個問題,目前沒有解決,哪位高手給指點一下:就是這個BitmapFactory.decodeStream()獲取的圖片是變形的,如何獲取到適應螢幕,並且不變形的方法呢?)
private Bitmap getBitmap(String path) throws IOException {
URL url = new URL("http://www.bing.com"+path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
InputStream inputStream = conn.getInputStream();
DisplayMetrics dm = getResources().getDisplayMetrics();//獲得螢幕的寬度和高度
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream), dm.widthPixels, dm.heightPixels, true);
conn.disconnect();
return bitmap;
}
conn.disconnect();
return null;
}
第四步:賦值給背景圖片,並將bitmap儲存在本地
這步就是要獲取圖片了,因此需要呼叫前三步中所有的函式,所以特別需要注意的是,在Android4.0以後,所有關於網路方面的操作都不能在主執行緒了(我們訪問bing的時候用到了INTERNET許可權),所以這裡使用了一個AsyncTask;並且由於在本地沒有圖片而載入圖片的時候,根據網速的不同,會造成介面的等待,因此加入了一個ProgressDialog,具體程式碼如下:
class DownImgAsyncTask extends AsyncTask<String,Void,Bitmap> {
@Override
protected Bitmap doInBackground(String... strings) {
try{
Bitmap b=getBitmap(resolveData(getData(strings[0])));
return b;
}catch (IOException e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (bitmap!=null){
iv_background.setImageBitmap(bitmap);
//儲存到本地
CutPictureUtils.saveImageToGallery(SplashActivity.this,bitmap);
}
progressDialog.dismiss();
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
儲存到本地的函式程式碼如下:
public static void saveImageToGallery(Context context, Bitmap bmp) {
// 首先儲存圖片
File appDir = new File(Environment.getExternalStorageDirectory(), "crazystudy");
if (!appDir.exists()) {
appDir.mkdir();
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");// HH:mm:ss
//獲取當前時間
Date date = new Date(System.currentTimeMillis());
String fileName = simpleDateFormat.format(date) + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// // 其次把檔案插入到系統圖庫
// try {
// MediaStore.Images.Media.insertImage(context.getContentResolver(),
// file.getAbsolutePath(), fileName, null);
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
// // 最後通知相簿更新
// context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getPath())));
}
現在我們可以呼叫這個DownImgAsyncTask來完成我們歡迎頁的製作了,在《每日一記—獲取Bing每一日一圖實現Android歡迎頁(一)》中的“獲取bing背景圖片”預留位置,加入如下程式碼:
if(AnalysisUtils.isFolderExists("/sdcard/crazystudy/")){
if (AnalysisUtils.fileIsExists(imgUri.getPath())){
// 顯示出來
CutPictureUtils cutPictureUtils=new CutPictureUtils(SplashActivity.this,
"");
iv_background.setImageBitmap(cutPictureUtils.decodeUriAsBitmap(imgUri));
}else {
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage("載入中");
progressDialog.setCancelable(false);
//獲取背景圖片
String path = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=5&mkt=zh-CN";
new DownImgAsyncTask().execute(path);
}
}
這樣歡迎頁就完美的做好了,下面是效果圖: