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、到这你基本上就可以完成开发了,有什么问题可以留言啊,欢迎您评论。