Jireh程序猿的那些事 Jireh程序猿的那些事

记录分享生活、程序、信息的精彩人生

目录
Android实现实时定位并发送信息至服务器之定位功能(一)
/    

Android实现实时定位并发送信息至服务器之定位功能(一)

这段时间公司里面正好有搞这样的一个平台,不过之前并没有专门搞过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 &amp;&amp; !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 &amp;&amp; locationClient.isStarted()){
      locationClient.stop();
    }
    locationClient.unRegisterLocationListener(locationListener);
  }

  @Override
  public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
  }

}

第二步,实现BDGpsServiceListener监听

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&lt;NeighboringCellInfo&gt; 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&lt;String,String&gt; map = new HashMap&lt;String, String&gt;();
      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主键,然后保存在本地配置文件当中,读取配置文件的功能。


如果觉得这篇文章不错的话,请我喝一杯 咖啡☕吧
标题:Android实现实时定位并发送信息至服务器之定位功能(一)
作者:Jireh
地址:https://www.lyile.cn/articles/2020/03/09/1583760467157.html
本作品由 Jireh 采用 署名 – 非商业性使用 – 禁止演绎 4.0 国际许可协议进行许可,转载请注明出处。