这段时间公司里面正好有搞这样的一个平台,不过之前并没有专门搞过android的这块,也是边做边研究喽。
讲一下app的简单功能,就是用户通过手机开启app,在前台和后台的时候能实时的发送当前位置的经纬度、手机号等一些信息,并以Post的方式上传服务器。
当然后面会加上其他的一些功能略 。
服务器这块并不是我这负责,是.net开发的同事专门负责的,如果后面有机会,我会写一个简单的服务端,就是数据Post到服务器处理并存储到数据库,到时候会用到Spring+Spring Boot+Mybatis,当然可能会附加上一些读写分离二级缓存用到Redis的一些功能。
应用使用的是百度定位的SDK,当然其他的也是同理。然后我的IDE是intelliJ idea,个人感觉这款ide不错,开发也是比较方便。要是要需要的可以评论留言,我会把安装包和激活的地址发出来哈。
1、首先到百度地图开放平台,注册登陆自己的帐号,申请创建AK。
具体的在百度的开发指南中有比较详细的介绍和流程。
http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/key
2、然后新建项目,在intelliJ idea中导入jar包,在File - Project Structure - Modules - app - Dependencies 中添加jar包,然后在app - lib中添加百度定位SDK的so文件。
使用了IntelliJ和AndroidStutio的开发者还需要在build.gradle中配置SO文件的使用
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
在AndroidManifest.xml当中需要设置
声明service组件
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"> </service>
使用权限声明
<!-- 这个权限用于进行网络定位--> <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.ACCESS_WIFI_STATE"></uses-permission> <!-- 获取运营商信息,用于支持提供运营商信息相关的接口--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></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> <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <!-- 访问网络,网络定位需要上网--> <uses-permission android:name="android.permission.INTERNET" /> <!-- SD卡读取权限,用户写入离线定位数据--> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
Application标签中加入并设置AcessKey
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="AK" /> //key:开发者申请的Key
详情可以去百度地图开发指南中查阅 http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/buildprojec
接下来才是正主,第一把新建Server类BDGpsService
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.google.gson.Gson;
import com.yyxt.jireh.gpst2.GsonBean.SetingBean;
import com.yyxt.jireh.gpst2.Util.HttpUtil;
import org.json.JSONException;
public class BDGpsService extends Service {
private static final int minTime = 60000;
private LocationClient locationClient;
private BDLocationListener locationListener;
private LocationClientOption lco;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.i("BDGpsService", "********BDGpsService onCreate*******");
lco = new LocationClientOption();
lco.setLocationMode(LocationMode.Hight_Accuracy);//定位模式 默认高精度,设置定位模式,高精度,低功耗,仅设备
lco.setScanSpan(minTime);//扫描间隔
lco.setCoorType("bd09ll");//设置返回的定位结果坐标系
lco.setOpenGps(true);//设置是否使用gps
lco.setIsNeedAddress(true);//设置是否需要地址信息
locationListener = new BDGpsServiceListener(getApplicationContext());
locationClient = new LocationClient(getApplicationContext());
locationClient.setLocOption(lco);
locationClient.registerLocationListener(locationListener);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i("BDGpsService", "********BDGpsService onStartCommand*******");
if (locationClient != null && !locationClient.isStarted()){
locationClient.start();
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("BDGpsService", "********BDGpsService onDestroy*******");
if (locationClient != null && locationClient.isStarted()){
locationClient.stop();
}
locationClient.unRegisterLocationListener(locationListener);
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.util.Log;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import static android.content.Context.MODE_PRIVATE;
public class BDGpsServiceListener implements BDLocationListener {
private Context context;
public BDGpsServiceListener(){
super();
}
public BDGpsServiceListener(Context context){
super();
this.context = context;
}
//发送广播,提示更新界面
private void sendToActivity(String str){
Intent intent = new Intent();
intent.putExtra("newLoca", str);
intent.setAction("NEW LOCATION SENT");
context.sendBroadcast(intent);
}
@Override
public void onReceiveLocation(BDLocation location) {
// TODO Auto-generated method stub
Log.i("Listener", "********BDGpsServiceListener onReceiveLocation*******");
StringBuffer sb = new StringBuffer();
if(location == null){return;}
sb.append("经度=").append(location.getLongitude());
sb.append("\n纬度=").append(location.getLatitude());
sb.append("\n时间=").append(location.getTime());
sb.append("\n运营商=").append(location.getOperators());
sb.append("\nERR Code=").append(location.getLocType());
sb.append("\n手机型号:").append(android.os.Build.MODEL);
List<NeighboringCellInfo> infos=tm.getNeighboringCellInfo();
for(NeighboringCellInfo info:infos){
//获取邻居小区号
int cid=info.getCid();
sb.append("\n========小区信息=========\nCid=").append(cid);
//获取邻居小区LAC,LAC: 位置区域码。为了确定移动台的位置,每个GSM/PLMN的覆盖区都被划分成许多位置区,LAC则用于标识不同的位置区。
sb.append("\nLac=").append(info.getLac());
sb.append("\nNetworkType=").append(info.getNetworkType());
sb.append("\nPsc=").append(info.getPsc());
//获取邻居小区信号强度
sb.append("\nRssi=").append(info.getRssi());
}
if (location.hasRadius()){
sb.append("\n定位精度=").append(location.getRadius());
}
if (location.getLocType() == BDLocation.TypeGpsLocation){
sb.append("\n速度=");
sb.append(location.getSpeed());
sb.append("\n卫星=");
sb.append(location.getSatelliteNumber());
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
sb.append("\n位置=").append(location.getAddrStr());
sb.append("\n省=").append(location.getProvince());
sb.append("\n市=").append(location.getCity());
sb.append("\n市Code=").append(location.getCityCode());
sb.append("\n区县=").append(location.getDistrict());
}
try {
Map<String,String> map = new HashMap<String, String>();
map.put("lng", location.getLongitude()+"");
map.put("lat", location.getLatitude()+"");
map.put("time", location.getTime()+"");
} catch (Exception e) {
e.printStackTrace();
}
sendToActivity(sb.toString());
}
}
在MainActive中实现显示定位的信息,经纬度,位置信息,速度,定位时间等等的信息
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.*;
import android.os.Build;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String LOCSTART = "START_LOCATING";
private Button startBtn;
private Button endBtn;
private Button endApp;
private TextView content;
private LocationReceiver lr;
private AlarmManager alarmManager;
private PendingIntent pi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("MainActivity", "********MainActivity onCreate*******");
startBtn = (Button) findViewById(R.id.startServBtn);
endBtn = (Button) findViewById(R.id.endServBtn);
endApp = (Button) findViewById(R.id.endApp);
content = (TextView) findViewById(R.id.content);
content.setMovementMethod(ScrollingMovementMethod.getInstance());
alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
startBtn.setOnClickListener(new OnClickListener() {
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(),"有权限",Toast.LENGTH_SHORT).show();
Log.i("MainActivity", "********MainActivity startBtn onClick*******");
Intent intent = new Intent(LOCSTART);
pi = PendingIntent.getService(getApplicationContext(), 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10000, pi);
Toast.makeText(getApplicationContext(), "GPS测试开始"+ph.getString("phoneID","none"), Toast.LENGTH_SHORT).show();
}
});
endBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Log.i("MainActivity", "********MainActivity endBtn onClick*******");
alarmManager.cancel(pi);
Intent intent = new Intent(LOCSTART);
stopService(intent);
Toast.makeText(getApplicationContext(), "GPS测试结束", Toast.LENGTH_SHORT).show();
}
});
endApp.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
android.os.Process.killProcess(android.os.Process.myPid());
}
});
lr = new LocationReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("NEW LOCATION SENT");
registerReceiver(lr, intentFilter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("MainActivity", "********MainActivity onDestroy*******");
unregisterReceiver(lr);
}
class LocationReceiver extends BroadcastReceiver {
String locationMsg = "";
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
locationMsg = intent.getStringExtra("newLoca");
content.setText(locationMsg);
}
}
}
最后是我们的界面文件
<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=".MainActivity"
android:focusable="true"
android:focusableInTouchMode="true" >
<Button
android:id="@+id/startServBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/startServ"
android:layout_below="@+id/phoneTextEdit"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<Button
android:id="@+id/endServBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/endServ"
android:layout_below="@+id/startServBtn"
android:layout_alignRight="@+id/endApp"
android:layout_alignEnd="@+id/endApp"
android:visibility="gone">
<Button
android:id="@+id/endApp"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/endApp" >
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/gpsData"
android:maxLines="22"
android:scrollbars="vertical"
android:layout_below="@+id/startServBtn"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</RelativeLayout>
然后到这里就可以实现了基本上定位的功能,用户点击开始定位,然后定位的数据在TextView中可以自动换行显示出来。 嗯~,然后编译的当中,有问题的也可以评论回复我,有时间的话也帮大家找看看。
下面一篇讲一下,获取用户的手机号为id主键,然后保存在本地配置文件当中,读取配置文件的功能。