当前位置: 首页 > 工具软件 > Bing API SDK > 使用案例 >

第一行代码第二版关于作者bingapi无法使用的解决方案

冉丰茂
2023-12-01

在《第一行代码》第二版中最后一章coolweather开发中 14.5.4节 获取必应每日一图

截止到2023.4.5 在访问作者提供的网站

guolin.tech/api/bing_pic

发现返回错误

Request bing pic with error: failed to connect: getaddrinfo: Temporary failure in name resolution

可以自己写一个api来获取bing每日一图,通过bing提供的官方api

https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1

来获取到json数据,获取到的数据如下

{"images":[{"startdate":"20230404","fullstartdate":"202304041600","enddate":"20230405","url":"/th?id=OHR.QingMing2023_ZH-CN6951199028_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp","urlbase":"/th?id=OHR.QingMing2023_ZH-CN6951199028","copyright":"杭州西湖水墨意境般的风景,浙江省,中国 (© zhangshuang/Getty Images)","copyrightlink":"https://www.bing.com/search?q=%E6%B8%85%E6%98%8E%E8%8A%82&form=hpcapt&mkt=zh-cn","title":"水墨西湖","quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20230404_QingMing2023%22&FORM=HPQUIZ","wp":true,"hsh":"fb3b90fb33dde5b3c99c9e2475635809","drk":1,"top":1,"bot":1,"hs":[]}],"tooltips":{"loading":"正在加载...","previous":"上一个图像","next":"下一个图像","walle":"此图片不能下载用作壁纸。","walls":"下载今日美图。仅限用作桌面壁纸。"}}

发现url,通过拼接可得到真正的图片地址

picurl="http://cn.bing.com"+url;

总共分三步,首先通过网络请求获取json数据,然后解析json数据,最后获取到图片地址,用Glide加载到imageview中。

网络请求url代码

private void getImage(){
        final String bingUrl = 
"https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1";
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url(bingUrl)
                            .build();
                    Response response = null;
                    response = client.newCall(request).execute();
//解析json数据
                    parseJSONWithJSONObject(response.body().string());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

json解析代码

private void parseJSONWithJSONObject(String jsonData){

        try {
//获取jsonarray中image的jsonobject
            JSONArray jsonArray = new JSONObject(jsonData).getJSONArray("images");

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
//把url的值放入变量url中
                String url = jsonObject.getString("url");
                String picurl="http://cn.bing.com"+url;
//加载bingpic
                loadBingPic(picurl);

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

通过地址获取图片

private void loadBingPic(final String response)  {
        final String bingPic = response;
        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();
        editor.putString("bing_pic", bingPic);
        editor.apply();
//在ui线程中更新页面
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Glide.with(WeatherActivity.this).load(bingPic).into(bingPicImg);
            }
        });
    }

weatheractivity中的代码如下


    private void getImage(){
        final String bingUrl = "https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1";
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url(bingUrl)
                            .build();
                    Response response = null;
                    response = client.newCall(request).execute();
                    parseJSONWithJSONObject(response.body().string());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    private void parseJSONWithJSONObject(String jsonData){

        try {

            JSONArray jsonArray = new JSONObject(jsonData).getJSONArray("images");

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String url = jsonObject.getString("url");
                String picurl="http://cn.bing.com"+url;
                loadBingPic(picurl);

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    private void loadBingPic(final String response)  {
        final String bingPic = response;
        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();
        editor.putString("bing_pic", bingPic);
        editor.apply();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Glide.with(WeatherActivity.this).load(bingPic).into(bingPicImg);
            }
        });
    }

在使用时将前面loadBingpic()全部替换为getImage()即可;

AutoUpdateService中代码如下:

private void updateBingPic(){
        final String bingUrl = "https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1";
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url(bingUrl)
                            .build();
                    Response response = null;
                    response = client.newCall(request).execute();
                    parseJSONWithJSONObject(response.body().string());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void loadBingPic(final String response)  {
        final String bingPic = response;
        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(AutoUpdateService.this).edit();
        editor.putString("bing_pic", bingPic);
        editor.apply();
    }


    private void parseJSONWithJSONObject(String jsonData){

        try {
            // JSONArray jsonArray = new JSONArray(jsonData);

            JSONArray jsonArray = new JSONObject(jsonData).getJSONArray("images");

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String url = jsonObject.getString("url");
                String picurl="http://cn.bing.com"+url;
                loadBingPic(picurl);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

要在onstartcommand中使用updateBingPic方法

public int onStartCommand(Intent intent, int flags, int startId) {

    updateBingPic();//在这里加入这个函数即可
    updateWeather();...

另:系统状态栏半透明化可能不好用

if(Build.VERSION.SDK_INT>=21){
    View decorView = getWindow().getDecorView();
    decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}

可以在res/values/styles.xml中加入

<item name="android:windowTranslucentStatus">true</item>

参考资料:(66条消息) Android实例之必应每日一图_夜雨闻曦的博客-CSDN博客​​​​​​

 源码地址:GitHub - Daylighttx/coolweather: 跟学项目

 类似资料: