Take you step by step to complete your first android applet (Express App)

(1) Introduction

  • This article will take you step by step to implement a simple android express delivery applet to let you know better
  • Creation of android project
  • Use of github
  • Parsing of JSON data
    The following is a screenshot of the program (please don’t criticize me)

Insert image description here
Insert image description here

Insert image description here

(2) Start the project

(1) Create your code base on github

Step 1: Create a project.
Insert image description here
Enter the project name. Select the type and license
Insert image description here
. Create a project with the same name in Android Studio.
Insert image description here
Enter the created project directory in bit bash and enter:
git clone (the address of your newly created project on github).
For examplegit clone https://github.com/LQF-dev/DaydayExpress.git

Insert image description here

Finally push to github

 git add .
 git commit -m "你的commit"
 git push origin master

(2)Write layout file

   Note: The layout code is a bit cumbersome, and I am not good enough at it. If you do not follow this layout file, you can choose to skip directly and view the implementation section of the code.

2.1 MainActivity

   In the main activity we will place two EditText and a button and introduce ToolBar to replace the original ActionBar

  • The following is the code of activity_main
<?xml version="1.0" encoding="utf-8"?>

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
   /> >


    <EditText

        android:id="@+id/edit_expNu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:hint="请输入快递单号"/>

    <EditText

        android:id="@+id/edit_expCode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_below="@+id/edit_expNu"
        android:hint="请输入快递公司名称"/>

    <Button
        android:id="@+id/submit"
        android:layout_below="@+id/edit_expCode"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查询"/>




</RelativeLayout>



    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header">


    </com.google.android.material.navigation.NavigationView>





</androidx.drawerlayout.widget.DrawerLayout>

2.2 TraceAcvitity

  • In this activity, there is
    toolbar to display the title bar
    RelativeLayout to accommodate pictures and shipping information
    LinearLayout to accommodate auxiliary information
    RecycleView to display express tracking information
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar_trace"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        /> >

    <RelativeLayout

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:padding="20dp">

        <ImageView
            android:id="@+id/iv_companyImage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:src="@drawable/ic_express_64" />

        <TextView
            android:id="@+id/text_state"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="44dp"
            android:layout_marginTop="12dp"
            android:layout_toRightOf="@+id/iv_companyImage"
            android:text="正在运送" />

        <TextView
            android:id="@+id/text_showNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/text_state"
            android:layout_marginLeft="44dp"

            android:layout_toRightOf="@+id/iv_companyImage"
            android:text="快递单号" />


    </RelativeLayout>


    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:text="快速详情"
            android:layout_gravity="center"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:padding="10dp"/>
        <TextView
            android:id="@+id/tv_time_total"
            android:layout_gravity="center"
            android:text="耗时:"
            android:padding="10dp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>

    </LinearLayout>


<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycle_view_trace"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

</androidx.recyclerview.widget.RecyclerView>




</LinearLayout>

2.3 Use of ToolBar

   ActionBar is displayed by default in the android project, so you must first modify the project's theme in the style.xml file before you can use Toobar.

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
      
    </style>

</resources>

    The following is a simple use of toobar. I only added a scan item to the toolbar. You can add different functions according to your needs.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/scan"
        android:title="扫一扫"
        app:showAsAction="never"
        />
</menu>

2.4 Introduction of dependencies

Insert image description here

(3) Project code implementation

3.1 Overall understanding of the code

   The idea of ​​the current program is very simple

1. Call the Query Express API    locally and send a query request.
   2. Accept the parsed json data and extract the valid data using GSON or other methods.
   3. Finally , display the data in the main thread (UITHread) .

3.2 Code implementation of MainActivity

  • overall framework
    Insert image description here
3.2.1.onCreate
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化各种控件
        Button submit = (Button)findViewById(R.id.submit);
        submit.setOnClickListener(this);

        expCode = (EditText)findViewById(R.id.edit_expCode);
        expNu =  (EditText)findViewById(R.id.edit_expNu);

       androidx.appcompat.widget.Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
       setSupportActionBar(toolbar);

        mdrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout) ;

        //展示ActionBar
        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
    
    
          actionBar.setDisplayHomeAsUpEnabled(true);
          //Todo change icon later
          actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);

        }


    }
3.2.2.Button onCLick event
  • Store input data through SharedPreferences and pass it to TraceActivity
  @Override
    public void onClick(View v){
    
    
        switch (v.getId()){
    
    
            case R.id.submit:
                 final String code = expCode.getText().toString();
                 final String num = expNu.getText().toString();
                Log.d(TAG, "code = "+ code);
                Log.d(TAG, "num = " + num);
                 if(!(code.equals("STO") || code.equals("YTO")|| code.equals("ZTO")) ){
    
    
                     Toast.makeText(this, "仅支持 申通 圆通 中通", Toast.LENGTH_SHORT).show();
                 }else{
    
    
                     Toast.makeText(this, "查询成功", Toast.LENGTH_SHORT).show();
                 }

                // 打开另一个activity
                 SharedPreferences.Editor editor =  getSharedPreferences("data",MODE_PRIVATE).edit();
                editor.putString("code",code);
                editor.putString("number",num);
                editor.apply();
                Intent intent = new Intent(this,TraceActivity.class);
                startActivity(intent);
                
        }

    }
3.2.3 Loading Toolbar and TooBar’s click event
  • I just added a scan menu
  public boolean onCreateOptionsMenu(Menu menu){
    
    
        getMenuInflater().inflate(R.menu.toolbar,menu);
        return true;
    }
    public boolean onOptionsItemSelected(MenuItem item){
    
    
        switch (item.getItemId()){
    
    
            case R.id.scan:
                Toast.makeText(this, "你点击了扫一扫按钮", Toast.LENGTH_SHORT).show();
                break;

            case android.R.id.home:
                Log.d(TAG, "onOptionsItemSelected: open_drawer");
                mdrawerLayout.openDrawer(GravityCompat.START);
                break;
                default:
                    break;
        }
        return true;

    }

3.3 Code implementation of TraceActivity

  • overall framework
    Insert image description here
    Insert image description here
3.3.1 What are the free express APIs? How to use the API?

   You can use Express 100 Express Bird's API. Here I am using the free version of Express Bird (you can register directly with Express Bird, but Express 100 still needs to be reviewed). . . The free version of Express Bird only supports express delivery inquiries from ZTO, Yuantong and Shentong. For specific information, please log in to Express Bird's website for inquiries.
Insert image description here    When you get your ID apikey, you can use the Express Bird API, but how to use it? Don’t worry, I will explain it clearly to you!

   As shown in the figure below, open the demo provided by Express Bird
   
   and copy the downloaded .java file to your project.
Insert image description here
   This interface KdniaoTrackQueryAPI is relatively complex. You don’t need to know the specific implementation. You only need to know that there is one. getOrderByJson method, this method requires you to pass in two parameters (company number) (courier number) to return JSON data

Insert image description here

3.3.2 Json data parsing and implementation of onCreate method
  • This is the json data obtained
    Insert image description here

   Since I only need the parsed logistics track, I will not use the GSON parsing method here, but directly convert it to JSONObject for direct parsing.

 new Thread(new Runnable() {
    
    


            @Override
           public void run() {
    
    
                try {
    
    
                    //Log.d(TAG, "run: 进入run");

                    //这里的 respond 就是 待解析的Json数据
                    String respond = new KdniaoTrackQueryAPI().getOrderTracesByJson(code,num);
                   // Log.d(TAG, "respond:  " + respond);

                    JSONObject jsonObject = new JSONObject(respond);
                    JSONArray array = jsonObject.getJSONArray("Traces");
                    for (int i = 0; i < array.length(); i++) {
    
    
                        JSONObject object = array.getJSONObject(i);
                        String AcceptStation = object.getString("AcceptStation");
                        stations.add(AcceptStation);
                        String AcceptTime = object.getString("AcceptTime");
                        times.add(AcceptTime);
                       // Log.d(TAG, "AcceptStation:" + stations.get(i));
                       // Log.d(TAG, "AcceptTime : " + times.get(i));
                        //Log.d(TAG, "AcceptTime size: " + times.size());
                    } try {
    
    
                        Reason = jsonObject.getString("Reason");
                        Log.d(TAG, "Reason: " + Reason);
                    } catch (Exception e) {
    
    
                        e.printStackTrace();
                        //Log.d(TAG, "Reason: 正常查询无Reason 现在Reason:" + Reason);

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

    The data has been obtained and already exists in two lists. The next step is to update the data.

3.3.3 Update data in the main thread
 if(   Reason==null  ){
    
    
                runOnUiThread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        //查询正确显示
                        showInfo();
                    }
                });
            }
                else {
    
    
                    runOnUiThread(new Runnable() {
    
    
                        @Override
                        public void run() {
    
    
                            //查询不正确显示默认数据
                            showDefaultInfo();
                        }
                    });
                }

           }
       }).start();//runable

Please see below for the logic of showInfo() and showDefaultInfo()

  /**
     * 初始化 list 给recycleView的Adapter提供数据
     */
    public void initLoadTrace(){
    
    

        for(int i =0;i < times.size();i++){
    
    

            LoadTrace loadTraceItem = new LoadTrace(stations.get(i),times.get(i));
            loadTraces.add(loadTraceItem);

        }

    }

    /**
     * 展示物流轨迹信息
     */
    public void showTraceInfo(){
    
    
        initLoadTrace();
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        LoadTraceAdapter adapter = new LoadTraceAdapter(loadTraces);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this,
                DividerItemDecoration.VERTICAL));
        recyclerView.setAdapter(adapter);

    }

    /**
     *展示界面以及物流轨迹信息
     */
    public void showInfo(){
    
    
        showTraceInfo();
        tv_showNumber.setText(LogisticCode);

    }

    /**
     * 展示默认信息
     */
    public void showDefaultInfo(){
    
    
        tv_showNumber.setText("暂无");
        Toast.makeText(this, "请输入正确信息", Toast.LENGTH_SHORT).show();
    }

-At this point the overall logic is basically over.

3.3.4 Use of RecycleView

I will briefly skip this section. If you don’t understand, please download the use of RecycleView from Baidu.
Insert image description here

public class LoadTrace {
    
    


    private String traceInfo;
    private String time;

    public LoadTrace(String traceInfo,String time){
    
    
        this.traceInfo = traceInfo;
        this.time = time;
    }

    public String getTraceInfo() {
    
    
        return traceInfo;
    }

    public String getTime() {
    
    
        return time;
    }
}
public class LoadTraceAdapter extends RecyclerView.Adapter<LoadTraceAdapter.ViewHolder> {
    
    


    private List<LoadTrace>mLoadTraces;
    static class ViewHolder extends RecyclerView.ViewHolder{
    
    
        TextView traceInfo;
        TextView time;
        public ViewHolder(View view){
    
    
            super(view);
            traceInfo = (TextView)view.findViewById(R.id.tv_traceInfo);
            time = (TextView)view.findViewById(R.id.tv_time_item);

        }
    }


    public LoadTraceAdapter(List<LoadTrace>loadTraceList){
    
    
        mLoadTraces = loadTraceList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent , int viewType){
    
    
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.loadtrace_item,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }


    //滚动到这里加载
    @Override
    public void onBindViewHolder(ViewHolder holder,int position){
    
    
        LoadTrace loadTrace = mLoadTraces.get(position);
        holder.traceInfo.setText(loadTrace.getTraceInfo());
        holder.time.setText(loadTrace.getTime());
    }


    @Override
    public  int  getItemCount(){
    
    

        return mLoadTraces.size();
    }

}

(3) Push the code to github

The project is finally completed! At this time, we can upload our project to github for management.
Insert image description here

Tail:

    Thank you for reading this, friends. This is my first time writing such a long blog. I hope you can gain something, and I hope we can work together to learn technology well!
    If any friends don’t know what the final effect is, you can download my code in github. Here is my source code:
https://github.com/LQF-dev/DaydayExpress

Click here to jump directly

Guess you like

Origin blog.csdn.net/qq_44716086/article/details/105022893