源码上传至https://github.com/durtime/myproject下的temperature
实际效果:
开发过程
1.首先进行布局文件的编写,布局前台页面
2.布置两个按钮,一个是填写页面的跳转,一个是查询页面的跳转。进行按钮事件的添加,onclick,重载父类方法,进行页面的跳转。利用intent开启活动activity。
填写页面:输入框(姓名,体温),时间利用android自带的系统函数获取设备的时间
地点获取:采用高德地图SDK
第 1 步,配置AndroidManifest.xml
首先,声明Service组件
在application标签中声明service组件,每个app拥有自己单独的定位service。
<service android:name="com.amap.api.location.APSService"></service>
然后,声明权限
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!--用于写入缓存数据到扩展存储卡-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
最后,设置高德Key
在application标签中加入:
<meta-data android:name="com.amap.api.v2.apikey" android:value="key">//开发者申请的key
</meta-data>
第 2 步,初始化定位
在主线程中声明AMapLocationClient类对象,需要传Context类型的参数。推荐用getApplicationContext()方法获取全进程有效的context。
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener();
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);
第 3 步,配置参数并启动定位
创建AMapLocationClientOption对象
AMapLocationClientOption对象用来设置发起定位的模式和相关参数。
//声明AMapLocationClientOption对象
public AMapLocationClientOption mLocationOption = null;
//初始化AMapLocationClientOption对象
mLocationOption = new AMapLocationClientOption();
启动定位
//给定位客户端对象设置定位参数 mLocationClient.setLocationOption(mLocationOption); //启动定位 mLocationClient.startLocation();
根据回调函数mylisener设置textview部件,设置参数得到地址。
数据提交保存
将所有的数据保存到android的数据库中
public class MySQLOpenHelper extends SQLiteOpenHelper {
public MySQLOpenHelper(Context context) {
/**第一个参数 上下文
第二个参数 创建的数据库文件名字
第三个参数 游标工厂 通过游标工厂可以获得执行查询语句的返回值 Curor
可以传 null 采用默认的游标工厂
第四个参数 数据库的版本号 从1开始
**/
super(context, "info.db", null, 1);
}
public class MainActivity extends Activity {
private SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MySQLOpenHelper openHelper = new MySQLOpenHelper(this);
//获取SQLiteDatabase对象 如果数据库不存在则创建 如果存在则打开 如果磁盘空间满则出错
db = openHelper.getWritableDatabase();
//与getWritableDatabase功能类似 但如果磁盘空间满则会返回一个只读的数据库
db = openHelper.getReadableDatabase();
}
onCreate方法(必须实现的方法)
@Override
public void onCreate(SQLiteDatabase db) {
//适合做创建表 初始化数据的操作
db.execSQL("create table info (_id integer primary key autoincrement, name varchar(20),phone varchar(20))");
}
onUpgrade方法(必须实现的方法)
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//通过oldVersion 和newVersion 可以判断当前版本号和最新的版本号
//真实开发环境可能会针对不同的数据库版本做不同的操作
db.execSQL("alter table info add age integer");
}
public void insert(View v) {
SQLiteDatabase db = openHelper.getReadableDatabase();
db.execSQL("insert into info(name,phone) values('赵四','13888888888')");
db.execSQL("insert into info(name,phone) values('王五','13888888888')");
db.close();
}
public void update(View v) {
SQLiteDatabase db = openHelper.getReadableDatabase();
db.execSQL("update info set phone = '12345678' where name='赵四' ");
db.close();
}
public void delete(View v) {
SQLiteDatabase db = openHelper.getReadableDatabase();
db.execSQL("delete from info where name = '赵四'");
db.close();
}
public void query(View v) {
SQLiteDatabase db = openHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from info where name = ? ; ", new String[]{"王五"});
while(cursor.moveToNext()){
for (int i = 0; i < cursor.getColumnCount(); i++) {
String result = cursor.getString(i);
Log.d("MainActivity", result+"");
}
}
db.close();
}
进行数据库的操作存入数据
查询数据
将查到的数据利用listview展示,用listview的子方法onclicklistview点击查看详细信息。
遇到的问题
在获取地址时,调用外部的api,导入SDK遇到较多问题。
最开始用的是百度地图SDK,根据开发文档,编写好相关的方法,在测试时出现了版本不适的问题。Android百度地图定位API onReceiveLocation没有调用,无法进行定位。于是换了
最新的版本,又出现了问题,百度地图的jar包中有文件编译版本高于我的jdk版本,无法解析相关的class问价,编译不能通过。问题一直未解决。于是换高德地图,成功根据相关文档获取的位置信息。
源码
AndroidManifest
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.study.temperature" android:versionCode="1" android:versionName="1.0" > <!-- 用于进行网络定位 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" > </uses-permission> <!-- 用于访问GPS定位 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" > </uses-permission> <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > </uses-permission> <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > </uses-permission> <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 --> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > </uses-permission> <!-- 用于访问网络,网络定位需要上网 --> <uses-permission android:name="android.permission.INTERNET" > </uses-permission> <!-- 用于读取手机当前的状态 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" > </uses-permission> <!-- 写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > </uses-permission> <!-- 用于申请调用A-GPS模块 --> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" > </uses-permission> <!-- 用于申请获取蓝牙信息进行室内定位 --> <uses-permission android:name="android.permission.BLUETOOTH" > </uses-permission> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" > </uses-permission> <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="29" /> <application android:allowBackup="true" android:icon="@drawable/preferences_desktop_icons_72px_572043_easyicon" android:label="@string/app_name" android:requestLegacyExternalStorage="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".InActivity" android:label="@string/title_activity_in" > </activity> <activity android:name=".OutActivity" android:label="@string/title_activity_out" > </activity> <service android:name="com.amap.api.location.APSService" > </service> <meta-data android:name="com.amap.api.v2.apikey" android:value="cda85f6569f758ce27c1e616ecbb390c" /> <activity android:name=".SmallitemActivity" android:label="@string/title_activity_smallitem" > </activity> </application> </manifest>
mainactivity
package com.study.temperature; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button bt_in = (Button)findViewById(R.id.bt_in); //数据填写跳转 //绑定监听事件 bt_in.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //点击跳转 Intent intent =new Intent(MainActivity.this,InActivity.class); //启动填写页面 startActivity(intent); } }); //数据查询------------------------------------------------------------------------------------------ Button bt_out = (Button)findViewById(R.id.bt_out); bt_out.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //点击跳转 Intent intent =new Intent(MainActivity.this,OutActivity.class); //启动填写页面 startActivity(intent); } }); } }
main_xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.study.temperature.MainActivity" > <TextView android:id="@+id/tx_outline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/bt_in" android:layout_centerHorizontal="true" android:layout_marginBottom="62dp" android:text="体温填报查看SYSTEM" android:textColor="#771133" android:textSize="25sp" /> <Button android:id="@+id/bt_in" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/bt_out" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:text="填写信息" /> <Button android:id="@+id/bt_out" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/bt_in" android:layout_centerVertical="true" android:text="查询信息" /> </RelativeLayout>
inactivity
package com.study.temperature; import android.app.Activity; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.util.Calendar; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationClient; import com.amap.api.location.AMapLocationClientOption; import com.amap.api.location.AMapLocationClientOption.AMapLocationMode; import com.amap.api.location.AMapLocationListener; public class InActivity extends Activity { //地址 private Button bt_start; private TextView tv_locat; private MyopenHelper helper; private EditText et_name; private EditText et_temon; private EditText et_temunder; private TextView tv_time; private AMapLocationClient mLocationClient = null; private AMapLocationListener mLocationListener = null; /** * 接受百度地图定位的回调类,该类是派生于百度地图的一个地图定位的监听类,用于定位后信息的返回。 */ /** * 自定义的定位回调接口监听器,该接口是自定义的一个接口,用于在使用该对象时,把定位信息进行回调; */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_in); bt_start = (Button)findViewById(R.id.bt_start); tv_locat = (TextView)findViewById(R.id.tv_locat); bt_start.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(bt_start.getText().equals("开始定位")) { bt_start.setText("stop"); //声明AMapLocationClient类对象 //初始化定位 mLocationClient = new AMapLocationClient(getApplicationContext()); mLocationListener = new AMapLocationListener(){ @Override public void onLocationChanged(AMapLocation location) { if (location != null) { if (location.getErrorCode() == 0) { //解析定位结果 String province = location.getProvince(); //获取省份 String city = location.getCity(); //获取城市 String district = location.getDistrict(); //获取区县 String street = location.getStreet(); //获取街道信息 StringBuilder myPosition=new StringBuilder(); myPosition.append("纬度:").append(location.getLatitude()).append(" "); myPosition.append("经度:").append(location.getLongitude()).append(" "); myPosition.append("省份:").append(province).append(" "); myPosition.append("城市:").append(city).append(" "); myPosition.append("区:").append(district).append(" "); myPosition.append("街道:").append(street).append(" "); myPosition.append("门牌号:").append(location.getStreetNum());//街道门牌号信息 tv_locat.setText(myPosition); } } } }; //设置定位回调监听 mLocationClient.setLocationListener(mLocationListener); //异步获取定位结果 initLocation(); //启动定位 mLocationClient.startLocation(); }else if(bt_start.getText().equals("stop")) { bt_start.setText("开始定位"); close(); } } }); //------------------------ et_name = (EditText)findViewById(R.id.et_name); et_temon = (EditText)findViewById(R.id.et_temon); et_temunder = (EditText)findViewById(R.id.et_temunder); Calendar calendar = Calendar.getInstance(); //年 int year = calendar.get(Calendar.YEAR); //月 int month = calendar.get(Calendar.MONTH)+1; //日 int day = calendar.get(Calendar.DAY_OF_MONTH); //获取系统时间 //小时 int hour = calendar.get(Calendar.HOUR_OF_DAY); //分钟 int minute = calendar.get(Calendar.MINUTE); //秒 int second = calendar.get(Calendar.SECOND); tv_time = findViewById(R.id.tv_time); tv_time.setText(year+"年"+month+"月"+day+"日"+hour+":"+minute+":"+second); helper = new MyopenHelper(this,1); Button bt_tijiao = (Button)findViewById(R.id.bt_tijiao); bt_tijiao.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //打开数据库 SQLiteDatabase readableDatabase = helper.getReadableDatabase(); //获取edittext数据 String text = et_name.getText().toString().trim(); String text2 = et_temon.getText().toString().trim(); String text3 = et_temunder.getText().toString().trim(); String text4 = tv_time.getText().toString().trim(); String text5 = tv_locat.getText().toString().trim(); if (TextUtils.isEmpty(text)||TextUtils.isEmpty(text2)||TextUtils.isEmpty(text3)) { Toast.makeText(InActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show(); }else { String sql = "insert into info (name,temon,temunder,time,locat) values('"+text+"','"+text2+"','"+text3+"','"+text4+"','"+text5+"')"; readableDatabase.execSQL(sql); readableDatabase.close(); Toast.makeText(InActivity.this, "提交成功!", Toast.LENGTH_SHORT).show(); Intent intent =new Intent(InActivity.this,MainActivity.class); finish();//结束当前活动 startActivity(intent); } } }); } private void initLocation() { AMapLocationClientOption option = new AMapLocationClientOption(); option.setGpsFirst(true); // 打开gps; //可选,是否需要地址信息,默认为不需要,即参数为false //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。 option.setLocationMode(AMapLocationMode.Hight_Accuracy); //可选,设置是否需要最新版本的地址信息。默认需要,即参数为true mLocationClient.setLocationOption(option); //mLocationClient为第二步初始化过的LocationClient对象 //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用 //更多LocationClientOption的配置,请参照类参考中LocationClientOption类的详细说明 } private void close() { mLocationClient.stopLocation(); mLocationClient.unRegisterLocationListener(mLocationListener); mLocationClient.onDestroy(); } }
in_xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.study.temperature.InActivity" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名:" /> <EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="请输入" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="上午体温:" /> <EditText android:id="@+id/et_temon" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="请输入" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下午体温:" /> <EditText android:id="@+id/et_temunder" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="请输入" /> </LinearLayout> <TextView android:id="@+id/tv_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="时间" /> <Button android:id="@+id/bt_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始定位" /> <TextView android:id="@+id/tv_locat" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="地址"/> <Button android:id="@+id/bt_tijiao" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="210dp" android:onClick="insert" android:text="提交" /> </LinearLayout>
outactivity
package com.study.temperature; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class OutActivity extends Activity { private ListView lv_list; private ArrayList<Person> persons = new ArrayList<Person>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_out); lv_list = (ListView)findViewById(R.id.lv_list); MyopenHelper helper = new MyopenHelper(this,1); SQLiteDatabase readableDatabase = helper.getReadableDatabase(); String sql = "select * from info"; Cursor curor = readableDatabase.rawQuery(sql , null); //遍历查询到的结果 int count=0; while(curor.moveToNext()){ //创建person对象 Person person = new Person(); //根据列名 name 获取数据库中对应的值 String name = curor.getString(curor.getColumnIndex("name")); //根据列名 phone 获取数据库中对应的值 String temon = curor.getString(curor.getColumnIndex("temon")); String temunder = curor.getString(curor.getColumnIndex("temunder")); String time = curor.getString(4); String locat = curor.getString(5); //设置相应数据 person.setName(name); person.setTemon(temon); person.setTemunder(temunder); person.setTime(time); person.setLocat(locat); //把数据添加到集合 persons.add(person); count++; } //list显示 //把数据适配器和listview绑定 lv_list.setAdapter(new MyAdapter()); //关闭游标 curor.close(); helper.close(); if(count!=0) { Toast.makeText(this, "查询成功", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(this, "查询失败", Toast.LENGTH_SHORT).show(); } lv_list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //点击跳转 Intent intent =new Intent(OutActivity.this,SmallitemActivity.class); //启动填写页面 Person tem =persons.get(position); intent.putExtra("name",tem.getName()); intent.putExtra("info", tem.getTime()+" "+tem.getLocat()); startActivity(intent); } }); } private class MyAdapter extends BaseAdapter{ //返回要展示的数据集合的条目数 @Override public int getCount() { return persons.size(); } //通过adapter传进来的posion(listview中条目的position) //把它对应的数据集合中的对象返回来 @Override public Object getItem(int position) { return persons.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { //①把布局文件转换为View对象 需要判断convertView是否为空 View view= null; if(convertView == null){ //创建view对象 view = View.inflate(OutActivity.this, R.layout.item, null); }else{ //复用旧的convertView view = convertView; } //②找到要修改的控件的对象 注意要调用view.findViewById TextView tv_name = (TextView)view.findViewById(R.id.tv_name); TextView tv_tem = (TextView)view.findViewById(R.id.tv_tem); //③ 设置数据 //3.1通过position 到数据集合中把要显示的数据找到 Person person = persons.get(position); //3.2把要显示的内容展示到对应的View对象上 tv_name.setText(person.getName()); tv_tem.setText("上午:"+person.getTemon()+"下午:"+person.getTemunder()); return view; } } }
out_xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.study.temperature.OutActivity" > <ListView android:id="@+id/lv_list" android:layout_width="match_parent" android:layout_height="match_parent" android:fastScrollEnabled="true" /> </RelativeLayout>
只帖了主要的,完整见GitHub,欢迎提出不足之处。