体温登记作业总结
1、要求:开发一个手机端上报体温的手机APP。上报内容包括姓名、日期(自动生成)、时间(自动生成)、地点(自动生成)、体温。
2、我是先将简单的完成,像姓名、日期、时间、体温。除了地点。最后完成地点。
3、在完成这个作业的同时,遇到了许多问题和难题,自己也学到了许多知识,有很大的进步,接下来进入项目开发的完整过程。
4、创建Mysql数据库:
5、添加一些jar包到libs目录下,并且右键选择Add As Library… :
6、界面图形以及代码实现:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="10"
android:columnCount="4"
> <!--设置网格为10行4列-->
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "1"
android:layout_marginLeft="4px"
android:gravity="left"
android:text="姓名:"
android:textSize="30dip" />
<EditText
android:id="@+id/et_name"
android:layout_width="320dp"
android:layout_height="wrap_content"
android:layout_columnSpan = "3"
android:layout_marginLeft="4px"
android:gravity="left"
android:text=""
android:textSize="30dip" />
<Button
android:id="@+id/bt_riqi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:text="获取日期"
android:textSize="26sp" />
<TextView
android:id="@+id/tv_riqi0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "1"
android:layout_marginLeft="4px"
android:gravity="left"
android:text="日期:"
android:textSize="30dip" />
<TextView
android:id="@+id/tv_riqi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "3"
android:layout_marginLeft="4px"
android:gravity="left"
android:text=""
android:textSize="30dip" />
<Button
android:id="@+id/bt_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:text="获取时间"
android:textSize="26sp" />
<TextView
android:id="@+id/tv_time0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "1"
android:layout_marginLeft="4px"
android:gravity="left"
android:text="时间:"
android:textSize="30dip" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "3"
android:layout_marginLeft="4px"
android:gravity="left"
android:text=""
android:textSize="30dip" />
<Button
android:id="@+id/bt_space"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:text="获取地点"
android:textSize="26sp" />
<TextView
android:id="@+id/tv_space0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "1"
android:layout_marginLeft="4px"
android:gravity="left"
android:text="地点:"
android:textSize="30dip" />
<TextView
android:id="@+id/tv_space"
android:layout_width="270dp"
android:layout_height="wrap_content"
android:layout_columnSpan = "3"
android:layout_marginLeft="4px"
android:gravity="left"
android:text=""
android:textSize="30dip" />
<TextView
android:id="@+id/tv_wen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "1"
android:layout_marginLeft="4px"
android:gravity="left"
android:text="体温:"
android:textSize="30dip" />
<EditText
android:id="@+id/et_wen"
android:layout_width="320dp"
android:layout_height="wrap_content"
android:layout_columnSpan = "3"
android:layout_marginLeft="4px"
android:gravity="left"
android:text=""
android:textSize="30dip" />
<Button
android:id="@+id/bt_insert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:text="提交"
android:textSize="26sp" />
<TextView
android:id="@+id/tv_tishi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_columnSpan = "4"
android:layout_marginLeft="4px"
android:gravity="left"
android:text=""
android:textSize="30dip" />
</GridLayout>
7、增加权限以及一些地图的key(我用的高德的key,可以去官网申请),AndroidManifest.xml的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.tiwen">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序设置内置sd卡的写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序访问WiFi网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
<!-- 地图的key -->
android:icon="@drawable/icon"
android:label="@string/app_name" >
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="高德地图的key(自己申请)"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Tiwen">
<service android:name="com.amap.api.location.APSService"
tools:ignore="WrongManifestParent"></service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
8、接下来就到了主要的java代码了,我分了如下几个包:
User类:
package bean;
public class User {
private String name;
private String riqi;
private String time;
private String space;
private String wen;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setRiqi(String riqi) {
this.riqi = riqi;
}
public String getRiqi() {
return riqi;
}
public void setTime(String time) {
this.time = time;
}
public String getTime() {
return time;
}
public void setSpace(String space) {
this.space = space;
}
public String getSpace() {
return space;
}
public void setWen(String wen) {
this.wen = wen;
}
public String getWen() {
return wen;
}
public User(String name,String riqi,String time,String space,String wen){
this.name=name;
this.riqi=riqi;
this.time=time;
this.space=space;
this.wen=wen;
}
}
MainActivity类:
package com.example.tiwen;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.core.app.ActivityCompat;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import bean.User;
import dao.Dao;
public class MainActivity extends Activity implements View.OnClickListener {
Button bt_riqi,bt_time,bt_space,bt_insert;
EditText et_name,et_wen;
TextView tv_riqi,tv_riqi0,tv_time,tv_space,tv_tishi;
private static final String[] authBaseArr = {//申请类型
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
private static final int authBaseRequestCode = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_riqi=(Button)findViewById(R.id.bt_riqi);
bt_time=(Button)findViewById(R.id.bt_time);
bt_space=(Button)findViewById(R.id.bt_space);
bt_insert=(Button)findViewById(R.id.bt_insert);
et_name=(EditText) findViewById(R.id.et_name);
tv_riqi=(TextView)findViewById(R.id.tv_riqi);
tv_riqi0=(TextView)findViewById(R.id.tv_riqi0);
tv_time=(TextView)findViewById(R.id.tv_time);
tv_space=(TextView)findViewById(R.id.tv_space);
et_wen=(EditText) findViewById(R.id.et_wen);
tv_tishi=(TextView)findViewById(R.id.tv_tishi);
bt_riqi.setOnClickListener(this);
bt_time.setOnClickListener(this);
bt_space.setOnClickListener(this);
bt_insert.setOnClickListener(this);
}
@Override
public void onClick(View v) {
String name=et_name.getText().toString();
String riqi="",time="",space="";
String wen=et_wen.getText().toString();
Date date = new Date();
SimpleDateFormat simpleDateFormat;
switch (v.getId()){
case R.id.bt_riqi:
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
riqi= simpleDateFormat.format(date);
tv_riqi.setText(riqi);
break;
case R.id.bt_time:
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
time = simpleDateFormat.format(date);
tv_time.setText(time);
break;
case R.id.bt_space:
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
initNavi();
//权限检查的代码
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
return;
}
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,//指定GPS定位提供者
1000,//指定数据更新的间隔时间
1,//位置间隔的距离为1m
new LocationListener() {//监听GPS信息是否改变
@Override
public void onLocationChanged(Location location) {//GPS信息发送改变时回调
Log.i("lgq","onLocationChanged===="+location.getProvider());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {//GPS状态发送改变时回调
}
@Override
public void onProviderEnabled(String provider) { //定位提供者启动时回调
}
@Override
public void onProviderDisabled(String provider) { //定位提供者关闭时回调
}
}
);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);//获取最新的定位信息
if (location==null){
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,//指定GPS定位提供者
5000,//指定数据更新的间隔时间
10,//位置间隔的距离为1m
new LocationListener() {//监听GPS信息是否改变
@Override
public void onLocationChanged(Location location) {//GPS信息发送改变时回调
Log.i("lgq","onLocationChanged===="+location.getProvider());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {//GPS状态发送改变时回调
}
@Override
public void onProviderEnabled(String provider) { //定位提供者启动时回调
}
@Override
public void onProviderDisabled(String provider) { //定位提供者关闭时回调
}
}
);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);//获取最新的定位信息
}
locationUpdates(location);
break;
case R.id.bt_insert:
riqi=tv_riqi.getText().toString();
time=tv_time.getText().toString();
space=tv_space.getText().toString();
if(name.equals("")||name==""){
tv_tishi.setText("姓名为空,请输入姓名!");
}
else if(riqi.equals("")||riqi==""){
tv_tishi.setText("日期为空,请获取日期!");
}
else if(time.equals("")||time==""){
tv_tishi.setText("时间为空,请获取时间!");
}
else if(space.equals("")||space==""){
tv_tishi.setText("地点为空,请获取地点!");
}
else if(space.equals("GPS失效啦!")||space.equals("获取失败!")){
tv_tishi.setText("地点获取失败,请重新获取地点!");
}
else if(wen.equals("")||wen==""){
tv_tishi.setText("体温为空,请输入体温!");
}
else {
Dao dao = new Dao();
User user = new User(et_name.getText().toString(), tv_riqi.getText().toString(), tv_time.getText().toString(), tv_space.getText().toString(), et_wen.getText().toString());
new Thread(new Runnable() {
@Override
public void run() {
dao.add(user);
}
}).start();
tv_tishi.setText("提交成功!");
}
break;
}
}
private boolean hasBasePhoneAuth() {
PackageManager pm = getPackageManager();
for (String auth : authBaseArr) {
if (pm.checkPermission(auth, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
private void initNavi() {
// 申请权限
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (!hasBasePhoneAuth()) {
this.requestPermissions(authBaseArr, authBaseRequestCode);
return;
}
}
}
public void locationUpdates(Location location){
if(location != null){
StringBuilder stringBuilder = new StringBuilder(); //构建一个字符串构建器,用于记录定位信息
stringBuilder.append("经度:");
stringBuilder.append(location.getLongitude());
stringBuilder.append("\n纬度:");
stringBuilder.append(location.getLatitude());
String ab = getAddress(location.getLatitude(),location.getLongitude());
tv_space.setText(ab);
}
else{
tv_space.setText("GPS失效啦!");
}
}
public String getAddress(double latitude, double longitude) {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
if (addresses.size() > 0) {
Address address = (Address) ((List) addresses).get(0);
String data = address.toString();//获取地点的全部信息
int startSpace = data.indexOf("\"") + ":".length();
int endSpace = data.indexOf("\"", startSpace);
String space=data.substring(startSpace,endSpace);//截取地点
return space;
}
} catch (IOException e) {
e.printStackTrace();
}
return "获取失败!";
}
}
Dao类:
package dao;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.sql.*;
import bean.User;
import util.DBUtil;
public class Dao {
public void add(User user) {
//获得链接对象
Connection connection = DBUtil.getConn("tiwen");
//准备sql语句
String sql = "insert into text(name,riqi,time,space,wen)values(?,?,?,?,?)";
try {
//创建语句传输对象
if(connection!=null) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
if (preparedStatement != null) {
preparedStatement.setString(1, user.getName());
preparedStatement.setString(2, user.getRiqi());
preparedStatement.setString(3, user.getTime());
preparedStatement.setString(4, user.getSpace());
preparedStatement.setString(5, user.getWen());
preparedStatement.executeUpdate();
preparedStatement.close();
connection.close();
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
DBUtil类:
package util;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* 数据库工具类:连接数据库用、获取数据库数据用
* 相关操作数据库的方法均可写在该类
*/
public class DBUtil{
private static String driver = "com.mysql.jdbc.Driver";// MySql驱动
private static String user = "root";// 用户名
private static String password = "001206";// 密码
public static Connection getConn(String dbname){
Connection connection = null;
try{
Class.forName(driver);// 动态加载类
String ip = "192.168.1.104";// 写成本机地址,不能写成localhost,同时手机需要连接电脑的热点。
// 尝试建立到给定数据库URL的连接
connection = DriverManager.getConnection("jdbc:mysql://" + ip + ":3306/" + dbname, user, password);
}catch (Exception e){
e.printStackTrace();
}
return connection;
}
}
9、到这项目的全部代码就结束了。给大家展示一下结果:
10、接下来我给大家讲讲我遇到的问题:
(1)连接Mysql数据库,需要设置可以远程访问(网上可以搜),并且真机需要连接电脑的热点。
(2)真机可以获取到地点。不知道为啥虚拟机获取不到地点,可以获取经纬度,我猜可能是谷歌是外网,谷歌是内网的原因(只是猜测。)。
11、需要自己进行的事情:
(1)申请高德的key。
(2)修改Mysql可以远程访问(就是将root权限改为%),网上有讲解和流程。
(3)运行Android Studio软件,这个软件开发挺好的。
12、到这你基本上就可以完成开发了,有什么问题可以留言啊,欢迎您评论。