日期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);
}
}
这样欢迎页就完美的做好了,下面是效果图: