全球疫情爬取-移動端:
一、項目要求:
二、 項目思路:
1.准備數據:使用pythone將數據存放到mysql中
2.將android連接數據庫mysql,通過導包和更改自己的ip地址
3.進行信息讀取,查詢,移動端app顯示
三、導包:
1.在main目錄下新建文件夾libs,將自己的jar包復制進入,然后右鍵選擇 Add As Library 進行導入;
四、 項目結構:
五、相關源碼:
DBOpenHelper.java:

package com.example.myapplication; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class DBOpenHelper { private static String driver = "com.mysql.jdbc.Driver"; private static String url = "jdbc:mysql://192.168.1.107:3306/database?characterEncoding=utf-8"; private static String user = "root";//用戶名 private static String password = "20000604";//密碼 public static Connection getConn(){ Connection conn = null; try { Class.forName(driver); conn = (Connection) DriverManager.getConnection(url,user,password);//獲取連接 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } public static List<WorldData> searchDataByCountry(String condition,String country_name){ List<WorldData> list = new ArrayList<>(); Connection connection = getConn(); String sql = ""; //System.out.println(condition); if(condition.equals("時間")){ sql = "select * from worlddata where lastupdateTime like ?"; } if(condition.equals("國家")){ sql = "select * from worlddata where countryname like ?"; } System.out.println(country_name); if(connection !=null){ try { PreparedStatement ps = connection.prepareStatement(sql); if(ps!=null){ ps.setString(1,"%"+country_name+"%"); ResultSet rs = ps.executeQuery(); if(rs!=null){ while(rs.next()){ WorldData worldData = new WorldData(); worldData.setId(rs.getInt("id")); worldData.setCountryname(rs.getString("countryname")); worldData.setConfirmed(rs.getString("confirmed")); worldData.setSuspected(rs.getString("suspected")); worldData.setDead(rs.getString("dead")); worldData.setHealed(rs.getString("healed")); worldData.setLastupdateTime(rs.getString("lastupdateTime")); list.add(worldData); } connection.close(); ps.close(); return list; }else{ return null; } }else{ return null; } } catch (SQLException e) { e.printStackTrace(); return null; } }else{ return null; } } }
MainActivity.java:

package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.app.Activity; import android.icu.lang.UCharacter; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private Button bt_send; private EditText et_content; private static final int TEST_USER_SELECT = 1; private String content; private Spinner conditionSpinner; private String condition; private ListView lv; String[] strs = new String[]{}; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg){ switch(msg.what){ case TEST_USER_SELECT: String s = (String)msg.obj; //System.out.println("***********"); // System.out.println("***********"); //System.out.println("data:"+s); strs = s.split(" "); lv.setAdapter(new ArrayAdapter<String>(MainActivity.this,R.layout.support_simple_spinner_dropdown_item,strs)); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt_send = findViewById(R.id.bt_send); et_content = findViewById(R.id.et_content); et_content.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { content = s.toString(); } }); conditionSpinner = findViewById(R.id.condition); final String [] data = {"時間","國家"}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,data); conditionSpinner.setAdapter(adapter); conditionSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //取得選中的值 condition = data[position]; //設置顯示當前選擇的項 parent.setVisibility(View.VISIBLE); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); System.out.println(condition); lv = findViewById(R.id.lv); } @Override protected void onStart(){ super.onStart(); bt_send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //執行查詢操作 //連接數據庫進行操作需要在主線程操作 new Thread(new Runnable() { @Override public void run() { //調用數據庫幫助類中的方法取數據 List<WorldData> list = DBOpenHelper.searchDataByCountry(condition,content); Message message = mHandler.obtainMessage(); String s = ""; for(int i=0;i<list.size();i++){ s+=" "; s += "時間:"+list.get(i).getLastupdateTime()+" "; s += list.get(i).getCountryname()+"確診人數為:"+list.get(i).getConfirmed()+" "; // s += list.get(i).getConfirmed()+" "; s += "治愈人數:"+list.get(i).getHealed()+" "; s += "死亡人數:"+list.get(i).getDead()+" "; } message.what = TEST_USER_SELECT; message.obj = s; mHandler.sendMessage(message); } }).start(); } }); } }
WorldData.java:

package com.example.myapplication; public class WorldData { private int id; private String countryname; private String confirmed; private String suspected; private String dead; private String healed; private String lastupdateTime; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCountryname() { return countryname; } public void setCountryname(String countryname) { this.countryname = countryname; } public String getConfirmed() { return confirmed; } public void setConfirmed(String confirmed) { this.confirmed = confirmed; } public String getSuspected() { return suspected; } public void setSuspected(String suspected) { this.suspected = suspected; } public String getDead() { return dead; } public void setDead(String dead) { this.dead = dead; } public String getHealed() { return healed; } public void setHealed(String healed) { this.healed = healed; } public String getLastupdateTime() { return lastupdateTime; } public void setLastupdateTime(String lastupdateTime) { this.lastupdateTime = lastupdateTime; } }
activity_xml:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context=".MainActivity"> <Spinner android:id="@+id/condition" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_content" android:layout_width="180dp" android:layout_height="40dp" android:layout_toRightOf="@+id/condition" /> <Button android:id="@+id/bt_send" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查詢" android:layout_marginTop="30dp"/> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="50dp" /> </RelativeLayout>
六、運行截圖:
七、遇到的問題:
1.點擊查詢按鈕時,界面進行閃退,顯示mysql連接問題
解決方法:(舍友幫助)
參考博客:https://www.cnblogs.com/xjmm/p/12518798.html
時長:5h
八、PSP時間表:
階段 | 時間 | 問題 | 備注 |
pyhone爬取世界疫情信息,存入mysql | 30min | 在之前讀取全國疫情的知識儲備下,這一步相對來說比較容易 | |
android連接mysql | 6h | 初次使用android連接mysql,並通過ip地址訪問,問題是真的多呀 | 各種網絡問題,權限問題,多種閃退問題,還不詳細提示錯誤信息,是真的難以解決呀,不過最后在舍友的幫助下,在mysql終端下更新權限才得以解決https://www.cnblogs.com/xjmm/p/12518798.html |
android讀取,查詢,顯示疫情信息 | 2h | 在這次的項目上,自我感覺真的是從頭學,現學現賣 | 一個項目的邏輯是真的重要呀,慢慢的解決,積累錯誤原因,吸取經驗 |