Android garbage classification APP network processing

preface

  in the previous article, we completed the display and processing of the news data on the home page, and also made a simple optimization of the UI. Now it looks higher than before, but we still have to continue to optimize.

text

   text is to optimize the network. We have to consider that there is no network when entering this App.

The most important data in the main page is the garbage classified news data, which is not updated in real time, because first of all, it is not necessary to request every time I open the App, which is a waste of resources. After all, my free times are only 100 times a day. Secondly, when I enter the main page without networking, I can't say anything and see nothing. This is inappropriate. So let's solve it one by one.

The first is to deal with when there is no network. Before processing, you should first think about whether each page should be processed in this way. If so, you can write a tool class to facilitate calling. Based on this, I put this tool class into the utils package under the network package under the mvplibrary module.

This NetworkUtils tool class is also one I found online. The code is as follows:

package com.llw.mvplibrary.network;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.provider.Settings;

/**
 * Network detection tools
 */
public class NetworkUtils {

    /** Network unavailable */
    public static final int NO_NET_WORK = 0;
    /** wifi connection */
    public static final int WIFI = 1;
    /** Not wifi connection */
    public static final int NO_WIFI = 2;


    private NetworkUtils(){
        /* cannot be instantiated */
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    /**
     * Determine whether to turn on the network
     * @param context
     * @return
     */
    public static boolean isNetWorkAvailable(Context context){
        boolean isAvailable = false ;
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if(networkInfo!=null && networkInfo.isAvailable()){
            isAvailable = true;
        }
        return isAvailable;
    }

    /**
     * Get network type
     * @param context
     * @return
     */
    public static int getNetWorkType(Context context) {
        if (!isNetWorkAvailable(context)) {
            return NetworkUtils.NO_NET_WORK;
        }
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        // cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        if (cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting()) {
            return NetworkUtils.WIFI;
        } else {
            return NetworkUtils.NO_WIFI;
        }
    }

    /**
     * Judge whether the current network is wifi
     * @param context
     * @return  If it is wifi, return true; Otherwise, false is returned
     */
    @SuppressWarnings("static-access")
    public static boolean isWiFiConnected(Context context){
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        return networkInfo.getType() == manager.TYPE_WIFI ? true : false;
    }

    /**
     * Judge whether MOBILE network is available
     * @param context
     * @return
     * @throws Exception
     */
    public static boolean isMobileDataEnable(Context context){
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isMobileDataEnable = false;
        isMobileDataEnable = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnectedOrConnecting();
        return isMobileDataEnable;
    }

    /**
     * Determine whether wifi is available
     * @param context
     * @return
     * @throws Exception
     */
    public static boolean isWifiDataEnable(Context context){
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isWifiDataEnable = false;
        isWifiDataEnable = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting();
        return isWifiDataEnable;
    }

    /**
     * Jump to network settings page
     * @param activity
     */
    public static void GoSetting(Activity activity){
        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        activity.startActivity(intent);
    }

    /**
     * Open the network setting interface
     */
    public static void openSetting(Activity activity) {
        Intent intent = new Intent("/");
        ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.WirelessSettings");
        intent.setComponent(cn);
        intent.setAction("android.intent.action.VIEW");
        activity.startActivityForResult(intent, 0);
    }

}

The location is as follows:

Here you also need an Android manifest in the mvplibrary module Add a permission to XML

	<!--Access network status-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Add location as follows

Next, open BaseActivity and write a method in it:

	/**
     * Check whether the network is currently turned on
     */
    protected boolean hasNetwork() {
        return (NetworkUtils.isNetWorkAvailable(context));
    }

The advantage of this is that as long as the Activity inherits BaseActivity, you can directly use this hasNetwork() method to judge whether there is a network at present.

Now you can use it in MainActivity. Remember where you initiated the request for news data before?

In the initView method, through

mPresenter.getTrashNews(10);

Initiate a network request, so just judge here.

		if (hasNetwork()) {//Have network
            //Request garbage classification news data
            mPresenter.getTrashNews(10);
        } else {//No network
            //Load default data
           
        }

So how to load the default data? First, we need to get the default data.

I've got this. Add a Constant in the Constant class. The code is as follows:

	/**
     * The default news data is loaded when there is no network
     */
    public static final String LOCAL_NEWS_DATA ="{\n" +
            "  \"code\": 200,\n" +
            "  \"msg\": \"success\",\n" +
            "  \"newslist\": [\n" +
            "    {\n" +
            "      \"id\": \"a448c7cc172e1156b35fb266f96c49cf\",\n" +
            "      \"ctime\": \"2021-04-17 08:44\",\n" +
            "      \"title\": \"21 This administrative law enforcement power will be delegated to the grass-roots level, and behaviors such as non classification of garbage will be directly punished by streets and towns\",\n" +
            "      \"description\": \"Source: Beijing Daily  Original title: 21 administrative law enforcement powers will be delegated to grass-roots units, and behaviors such as non classification of garbage will be directly punished by streets and towns  In the future, catering units take the initiative to provide disposable products to consumers, and units and individuals are not classified according to the regulations\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd20210417s/233/w676h357/20210417/e0e5-knvsnuf8545017.jpg\",\n" +
            "      \"url\": \"http://news.sina.com.cn/c/2021-04-17/doc-ikmyaawc0158409.shtml\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"854fd9faf85e0ebeb588aca038cf5893\",\n" +
            "      \"ctime\": \"2021-04-17 06:42\",\n" +
            "      \"title\": \"Practicing the concept of classification, Shangyu established a "hundred people propaganda group" for domestic waste classification\",\n" +
            "      \"description\": \"4 On the afternoon of June 16, a lecturer group of domestic waste classification in Shangyu District, composed of 100 publicity lecturers from township streets, department units, communities (administrative villages) and universities, was officially established. The lecturer group will publicize the concept of environmental protection and popularize\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd20123/40/w480h360/20210416/e35f-knvsnuf8043448.jpg\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_7505202169_1bf584bf902000uczm.html\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"dde5b1a220c6957e8c60ca9f55ec8403\",\n" +
            "      \"ctime\": \"2021-04-17 07:17\",\n" +
            "      \"title\": \"If the garbage is not classified, it will be directly punished by the streets and towns! 21 administrative law enforcement powers in Beijing will be delegated to grass-roots units\",\n" +
            "      \"description\": \"  Original title: garbage is not classified and directly punished by streets and towns! 21 administrative law enforcement powers in Beijing will be delegated to grass-roots units  In the future, catering units take the initiative to provide disposable products to consumers, and units and individuals fail to classify and put domestic waste in accordance with the regulations\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd2021417s/602/w1280h922/20210417/0d27-knvsnuf8495071.jpg\",\n" +
            "      \"url\": \"http://news.sina.com.cn/c/2021-04-17/doc-ikmxzfmk7288291.shtml\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"3034adf78105d4a3ca53f1d5f14c53ef\",\n" +
            "      \"ctime\": \"2021-04-17 07:36\",\n" +
            "      \"title\": \"How to promote garbage classification in old residential areas? "Bus type" mobile collection in Xuanwu District of Nanjing provides new ideas\",\n" +
            "      \"description\": \"China Jiangsu network news (reporter Nie Longfei) on the wall next to Lanyuan building 19, Meiyuan Xincun street, Xuanwu District, Nanjing, there is a schedule of garbage sorting mobile transport vehicles: collect and transport three times in the morning, noon and evening every day, stop at each point for 5 minutes, and the flow transport route\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd20210417s/233/w676h357/20210417/e0e5-knvsnuf8545017.jpg\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_5675440730_152485a5a0200134ph.html\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"80f5a70563073544de441634f763af70\",\n" +
            "      \"ctime\": \"2021-04-16 23:12\",\n" +
            "      \"title\": \"Haikou Meilan: "small hand in big hand" to carry out garbage classification publicity\",\n" +
            "      \"description\": \"In order to guide young students in the area to practice waste classification and enhance their awareness of environmental protection. On April 15, Meilan District of Haikou launched a campaign on the theme of civilized practice of waste classification in the new era in Sanjiang Town, allowing waste classification to enter thousands of homes in the form of "small hand in big hand"\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd20123/40/w480h360/20210416/e35f-knvsnuf8043448.jpg\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_7517400647_1c0126e47059010dn9.html\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"c50d760bc5fe5e09144d02914a87f009\",\n" +
            "      \"ctime\": \"2021-04-16 20:41\",\n" +
            "      \"title\": \"Selecting the top ten communities and recruiting image ambassadors, Jinan will hold a series of garbage classification publicity and promotion activities\",\n" +
            "      \"description\": \"Popular network·Poster journalist Zhang Wen and correspondent Jiang Xia Jinan reported that the regulations on the reduction and classification management of domestic waste in Jinan will be officially implemented on May 1. The reporter learned from Jinan Urban Management Bureau that in order to implement the regulations of the Standing Committee of Jinan Municipal People's Congress\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd2021416s/320/w640h480/20210416/bd3f-knvsnuf7747977.png\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_2620088113_9c2b5f310200137ds.html\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"a5fb207c5c46a0ac10e5630201264b53\",\n" +
            "      \"ctime\": \"2021-04-16 20:41\",\n" +
            "      \"title\": \"New progress in garbage classification in Jinan: set up one centralized classification and delivery point every 300 households\",\n" +
            "      \"description\": \"Popular network·Poster journalist Zhang Wen reported that on the morning of April 16, Jinan held a comprehensive evaluation and evaluation of urban management in the first quarter of 2021 and a 100 day action promotion meeting to improve urban quality. The meeting deployed waste sorting workers\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd2021416s/450/w750h500/20210416/d2c4-knvsnuf7747865.jpg\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_2620088113_9c2b5f310200137dr.html\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"a8291cec82765336a1ca075f23c96fc7\",\n" +
            "      \"ctime\": \"2021-04-16 20:47\",\n" +
            "      \"title\": \"The space of the old community is small, and the garbage sorting booth is difficult to land. Nanjing Xuanwu community piloted "public transportation collection and transportation"\",\n" +
            "      \"description\": \"Yangzi Evening News Network, April 16 (correspondent Zhu Hailu intern Lou yuanze, reporter Zhang Ke) Lanyuan area of Meiyuan street, Xuanwu District, Nanjing belongs to a typical old community, with 18 residential buildings and 500 residents. Because of the space\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd20210416s/300/w720h380/20210416/7b74-knvsnuf7769851.jpg\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_1653603955_628ffe73020012poo.html\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"d8b40fa53a7f4dedeff9abbbd0e71754\",\n" +
            "      \"ctime\": \"2021-04-16 21:00\",\n" +
            "      \"title\": \"Waste classification and recycling (Figure)\",\n" +
            "      \"description\": \"  Dajiang network/Liu Meiju, correspondent of Dajiang news client, reported that in order to further promote the classification of domestic waste, advocate a green, ecological, healthy and environmental friendly lifestyle, enhance community residents' understanding of waste classification knowledge and actively participate in waste classification\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd2021416s/74/w500h374/20210416/35bb-knvsnuf7798675.png\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_1767961804_6960f4cc02000swdh.html\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"id\": \"b239d2bfc3265df7985dfd583b19fa3e\",\n" +
            "      \"ctime\": \"2021-04-16 21:01\",\n" +
            "      \"title\": \"Nanjing Xuanwu District carried out the pilot of garbage collection and transportation, and the problem of garbage classification in old residential areas became difficult and easy\",\n" +
            "      \"description\": \"The old courtyard and narrow streets and alleys are the appearance of Lanyuan community, Meiyuan New Village street, Xuanwu District. As a community with more than 500 households, Lanyuan community produces 30 or 40 barrels of domestic waste every day. In the past two years, garbage classification has been regarded as a key technology in Nanjing\",\n" +
            "      \"source\": \"Garbage classification news\",\n" +
            "      \"picUrl\": \"http://n.sinaimg.cn/sinakd2021416s/170/w554h416/20210416/7134-knvsnuf7837985.png\",\n" +
            "      \"url\": \"http://k.sina.com.cn/article_5675440730_152485a5a0200134gq.html\"\n" +
            "    }\n" +
            "  ]\n" +
            "}\n";

This data is a Json string, so we can convert the Json string into an entity through Gson. Then write it like this.

		if (hasNetwork()) {//Have network
            //Request garbage classification news data
            mPresenter.getTrashNews(10);
        } else {//No network
            //Load default data
            TrashNewsResponse response = new Gson().fromJson(Constant.LOCAL_NEWS_DATA, TrashNewsResponse.class);
            mList.clear();
            mList.addAll(response.getNewslist());
            mAdapter.notifyDataSetChanged();
        }

It's that simple. Of course, this is not the end here. You also need to set the display of the rotation chart. I didn't set the background of the rotation chart before, so it is the default theme background color, because it is placed under CollapsingToolbarLayout. Now, when I don't have the network natural rotation picture and can't load the network picture, the background picture you set will be displayed. Here I found one on the Internet, which is not bad.

Well, then in activity_main.xml in the banner control.

That's good. Now you can run it.

Well, the effect is quite obvious.

The next step is to judge the processing once a day.

Logic is to judge whether it is the first request of the day when there is a network. If yes, request data, and then save the data to the database. If not, get the data from the database.

Open build. Under mvplibrary Gradle, add the following dependencies:

	//Android SQLite operation framework
    api 'org.litepal.guolindev:core:3.1.1'

Then Sync Now.

Next, create a litepal in the assets under the app module XML file, the code inside is as follows:

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <!--Database name-->
    <dbname value="GoodTrash" />
    <!--Database version-->
    <version value="1" />

    <!--Mapping model-->
    <list>
        <!--News table-->
        <mapping class="com.llw.goodtrash.model.News" />
    </list>
</litepal>

Here corresponds to a News table News. Create a News class under the model package. The code inside is as follows:

package com.llw.goodtrash.model;

import org.litepal.crud.LitePalSupport;

/**
 * News table
 * @author llw
 */
public class News extends LitePalSupport {
    private String ctime;
    private String title;
    private String description;
    private String source;
    private String picUrl;
    private String url;

    public String getCtime() {
        return ctime;
    }

    public void setCtime(String ctime) {
        this.ctime = ctime;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getPicUrl() {
        return picUrl;
    }

    public void setPicUrl(String picUrl) {
        this.picUrl = picUrl;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

You will see that this class inherits LitePalSupport, which is the technical support in the framework. After inheritance, you can directly edit the data of this class
You can't use this database yet. You also need to create and initialize the database when the program is running. This code is written in the onCreate method of TrashApplication. As shown in the figure below:

Now you can operate the data table. For convenience, write a NewsHelper tool class under the utils package. The code inside is as follows:

package com.llw.goodtrash.utils;

import android.util.Log;

import com.google.gson.Gson;
import com.llw.goodtrash.model.News;
import com.llw.goodtrash.model.TrashNewsResponse;

import org.litepal.LitePal;

import java.util.ArrayList;
import java.util.List;

/**
 * News table help class
 *
 * @author llw
 */
public class NewsHelper {

    private static final String TAG = "NewsHelper";

    /**
     * Save news data
     *
     * @param newsList
     * @return
     */
    public static boolean saveNews(List<TrashNewsResponse.NewslistBean> newsList) {
        LitePal.deleteAll(News.class);
        boolean result = false;
        for (TrashNewsResponse.NewslistBean bean : newsList) {
            News news = new News();
            news.setTitle(bean.getTitle());
            news.setDescription(bean.getDescription());
            news.setCtime(bean.getCtime());
            news.setPicUrl(bean.getPicUrl());
            news.setSource(bean.getSource());
            news.setUrl(bean.getUrl());
            news.save();
            if (news.save()) {
                result = true;
                Log.d(TAG, "News data saved successfully");
            } else {
                result = false;
                Log.d(TAG, "Failed to save news data");
            }
        }
        Log.d(TAG, "Saved data;" + new Gson().toJson(LitePal.findAll(News.class)));

        return result;
    }

    /**
     * Query all news data in the news table
     *
     * @return List<TrashNewsResponse.NewslistBean>
     */
    public static List<TrashNewsResponse.NewslistBean> queryAllNews() {
        List<TrashNewsResponse.NewslistBean> newsList = new ArrayList<>();
        List<News> news = LitePal.findAll(News.class);
        Log.d(TAG, String.valueOf(news.size()));
        if (news != null && news.size() > 0) {
            for (int i = 0; i < news.size(); i++) {
                TrashNewsResponse.NewslistBean newslistBean = new TrashNewsResponse.NewslistBean();
                newslistBean.setCtime(news.get(i).getCtime());
                newslistBean.setDescription(news.get(i).getDescription());
                newslistBean.setPicUrl(news.get(i).getPicUrl());
                newslistBean.setSource(news.get(i).getSource());
                newslistBean.setTitle(news.get(i).getTitle());
                newslistBean.setUrl(news.get(i).getUrl());
                newsList.add(newslistBean);
            }
        }
        return newsList;
    }


}

It's just the code to query and save. It's very simple. Let's use them in MainActivity. First, save the returned data when there is a network when you enter the App for the first time that day.

In the getTrashNewsResponse method. As shown in the figure below:

Next, let's look at the subsequent data operations entering the App.

First, judge whether it is started for the first time. There is also a tool class here. Before writing this class, first define it in Constant.

	/**
     * App First start
     */
    public static final String APP_FIRST_START = "appFirstStart";
    /**
     * Time to start APP today
     */
    public static final String START_UP_APP_TIME = "startAppTime";

Then create a new AppStartUpUtils class under the utils package. The code inside is as follows:

package com.llw.goodtrash.utils;

import android.content.Context;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * APP Start judgment tool class
 *
 * @author llw
 */
    public class AppStartUpUtils {
    /**
     * Determine whether it is the first start
     *
     * @param context
     * @return
     */
    public static boolean isFirstStartApp(Context context) {
        Boolean isFirst = SPUtils.getBoolean(Constant.APP_FIRST_START, true, context);
        // for the first time
        if (isFirst) {
            SPUtils.putBoolean(Constant.APP_FIRST_START, false, context);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Judge whether it is the first time to launch the APP today
     *
     * @param context
     * @return
     */
    public static boolean isTodayFirstStartApp(Context context) {

        String saveDate = SPUtils.getString(Constant.START_UP_APP_TIME, "2020-08-27", context);
        String todayDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        //First open
        if (!saveDate.equals(todayDate)) {
            SPUtils.putString(Constant.START_UP_APP_TIME, todayDate, context);
            return true;
        } else {
            return false;
        }

    }
}

Then go back to MainActivity and modify the code as shown in the following figure:

Of course, the operation effect is the same, but the channels for obtaining data are different, which is also a common way in practical development.

Then the network processing of the main page is completed, and there are three more pages. These three pages are relatively simple. Let's take a look at the TextInputActivity page first.

It's simple. Here is ImageInputActivity.

Then NewsDetailsActivity.

Did I miss a page? You will say whether there is still a voice input page that has not been judged and processed by the network. This page does not need to be done. IFLYTEK SDK has a check on the network. Without the network, voice input cannot be carried out. Naturally, it is impossible to have this network request.

Added by mckinney3 on Wed, 02 Mar 2022 01:00:52 +0200