基础界面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true"
        android:clickable="true"
        android:layout_alignParentLeft="true" />


</RelativeLayout>

内容相关代码

public class MainActivity extends AppCompatActivity {
    public static final String SP_SAFE_KEY = "SP_SAFE_KEY";
    public static final String isTracking = "SP_isTracking_KEY";
    public String istrack;
    SharedPreferences sp;
    private MapView mMapView = null;
    private BaiduMap baiduMap;
    int span = 5000;
    private LocationClient mLocationClient = null;
    private MyLocationListener myLocationListener;
    private double currentLat;
    private double currentLng;//当前经纬度(纬度,经度)
    private String currentAddr;//当前所在的地址
    private DatabaseAdapter dbAdapter;
    private GeoCoder geoCoder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
        //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
        SDKInitializer.setCoordType(CoordType.BD09LL);
        //初始化Bmob
        Bmob.initialize(this, "m7PCUh4QLmGBUt04R1xEtfeHaotan7KD");
        setContentView(R.layout.activity_main);
        mMapView = (MapView) findViewById(R.id.bmapView);
        initBaiduMap();
        dbAdapter = new DatabaseAdapter(this);

        SPUtils.putValue(MainActivity.this, isTracking, "2");
        sp = this.getSharedPreferences("Test", Context.MODE_PRIVATE);
        istrack = sp.getString("SP_isTracking_KEY", "");
        System.out.println(istrack);
        Intent intent = new Intent(MainActivity.this, MyService.class);
        intent.putExtra("lat", currentLat);
        intent.putExtra("lng", currentLng);
        intent.putExtra("ist", istrack);
        startService(intent);
    }

    private void initBaiduMap() {
        baiduMap = mMapView.getMap();
        baiduMap.setMyLocationEnabled(true);//打开定位图层
        mLocationClient = new LocationClient(getApplicationContext());//声明LocationClient类
        myLocationListener = new MyLocationListener();
        mLocationClient.registerLocationListener((BDLocationListener) myLocationListener);//注册监听函数
        initLocation();
        mLocationClient.start();
        mLocationClient.requestLocation();//发起定位请求 回到监听事件
        //地理编码  用于转换地理编码的监听器
        geoCoder = GeoCoder.newInstance();
        geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
            @Override
            public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {

            }

            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
                if (reverseGeoCodeResult == null || reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
                    //没有检索到结果
                } else {
                    //获取地理编码结果
                    System.out.println(reverseGeoCodeResult.getAddress());
                    currentAddr = reverseGeoCodeResult.getAddress();
                }
            }
        });
        boolean flag = true;
        final boolean istracking = true;

        //模拟跟踪的线程
        class TrackThread implements Runnable {
            @Override
            public void run() {
                System.out.println("TrackThread");
                while (istracking) {
                    istrack = sp.getString("SP_isTracking_KEY", "");
                    while (istrack == "1") {

                        CurrentAddr p = new CurrentAddr();
                        p.setLat(currentLat);
                        p.setLan(currentLng);
                        p.save(new SaveListener<String>() {
                            @Override
                            public void done(String s, BmobException e) {
                                if (e == null) {
                                    System.out.println("添加数据成功");
                                } else {
                                    System.out.println("添加数据失败");
                                }
                            }

                        });
                        System.out.println("istrack" + istrack);
                        System.out.println("lat:" + currentLat + "lan:" + currentLng);
                        istrack = sp.getString("SP_isTracking_KEY", "");
                        try {
                            Thread.sleep(span);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        }
    }

    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
        option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于5000ms才是有效的
        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
        option.setOpenGps(true);//可选,默认false,设置是否使用gps
        option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
        mLocationClient.setLocOption(option);
    }

    //位置监听器
    public class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {//接收位置信息的回调方法

            if (location != null) {
                currentLat = location.getLatitude();//当前的纬度
                currentLng = location.getLongitude();//当前的经度
                currentAddr = location.getAddrStr();//地址信息
                //System.out.println("currentAddr="+currentAddr);
                //构造我的当前位置信息
                MyLocationData.Builder builder = new MyLocationData.Builder();
                builder.latitude(location.getLatitude());//设置纬度
                builder.longitude(location.getLongitude());//设置经度
                builder.accuracy(location.getRadius());//设置精度(半径)
                builder.direction(location.getDirection());//设置方向
                builder.speed(location.getSpeed());//设置速度
                MyLocationData locationData = builder.build();

                //把我的位置信息设置到地图上
                baiduMap.setMyLocationData(locationData);

                //配置我的位置  当前经纬度
                LatLng latLng = new LatLng(currentLat, currentLng);
                //(跟随态,允不允许显示方向,默认图标)
                baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, null));
                //设置我的位置为地图的中心点,16表示缩放级别  3--20
                baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(latLng, 16));

            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    //功能菜单项
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.safenumber:
                saveClick();//保存安全号码
                break;
            case R.id.time:
                startTrack();//间隔时间
                break;
            default:
                break;
        }
        return true;
    }

    //设置间隔时间
    private void startTrack() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("间隔时间");
        builder.setCancelable(true);
        final View view = getLayoutInflater().inflate(R.layout.time, null);
        builder.setView(view);
        builder.setPositiveButton("保存", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                EditText et_track_time = view.findViewById(R.id.editText1_time);
                span = Integer.parseInt(et_track_time.getText().toString());
                System.out.println(span);

            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.show();
    }

    //安全号码
    private void saveClick() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("安全号码");
        builder.setCancelable(true);
        final View view = getLayoutInflater().inflate(R.layout.safe, null);
        builder.setView(view);
        SharedPreferences sp = this.getSharedPreferences("Test", Context.MODE_PRIVATE);
        String safenumber = sp.getString("SP_SAFE_KEY", "");
        final EditText et_track_time = view.findViewById(R.id.editText_num);
        et_track_time.setText(safenumber);
        builder.setPositiveButton("保存", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                String safe = et_track_time.getText().toString();
                SPUtils.putValue(MainActivity.this, SP_SAFE_KEY, safe);//存入安全号码
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.show();

    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
        new Thread(new Thread()).start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
        Intent intent = new Intent(MainActivity.this, MyService.class);
        stopService(intent);
    }

}

广播的设置

public class BootBroadcastReceiver extends BroadcastReceiver {
    public BootBroadcastReceiver(){

    }
    String ACTION = "android.intent.action.BOOT_COMPLETED";
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ACTION)){
            Intent sayHelloIntent=new Intent(context,MainActivity.class);
            sayHelloIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            context.startActivity(sayHelloIntent);
            Toast.makeText(context,"重启成功",Toast.LENGTH_SHORT).show();
        }
    }
}
public class DatabaseAdapter {
    private DatabaseHelper dbHelper;
    public DatabaseAdapter(Context context){dbHelper=new DatabaseHelper(context);}
}
class DatabaseHelper extends SQLiteOpenHelper {
    private static String DB_NAME = "track.db";
    //表名
    public static String TABLE_TRACK = "track";
    public static String TABLE_TRACK_DETAIL = "track_detail";

    //字段
    public static String ID = "_id";
    //跟踪表
    public static String TRACK_NAME = "track_name";
    public static String CREATE_DATE = "create_date";
    public static String START_LOC = "start_loc";
    public static String END_LOC = "end_loc";
    //明细表
    public static String TID = "tid";//线路的ID
    public static String LAT = "lat";//维度
    public static String LNG = "lng";//经度

    private static String CREATE_TABLE_TRACK = "create table track(_id integer primary key autoincrement,track_name text,create_date text,start_loc text,end_loc text)";
    private static String CREATE_TABLE_TRACK_DETAIL = "create table track_detail(_id integer primary key autoincrement,tid integer not null,lat real,lng real)";
    private static int VERSION = 1;


    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE_TRACK);
        db.execSQL(CREATE_TABLE_TRACK_DETAIL);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        if (newVersion > oldVersion) {
            db.execSQL("drop table if exists track");
            db.execSQL("drop table if exists track_detail");
            db.execSQL(CREATE_TABLE_TRACK);
            db.execSQL(CREATE_TABLE_TRACK_DETAIL);

        }
    }

Bmob的权限设置及相关

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://raw.github.com/bmob/bmob-android-sdk/master" }
    }
}
//build.gradle中的是设置
 implementation files('libs/BaiduLBS_Android.jar')
    implementation 'cn.bmob.android:bmob-sdk:3.7.3-rc1'
    implementation "io.reactivex.rxjava2:rxjava:2.2.2"
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    implementation 'com.squareup.okio:okio:2.1.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.squareup.okhttp3:okhttp:3.12.0'

短信识别

public class SmsMessageReceiver extends BroadcastReceiver {
    TelephonyManager tm;
    DevicePolicyManager mDPM;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Bundle bundle = intent.getExtras();
        Object messages[] = (Object[]) bundle.get("pdus");
        SmsMessage smsMessage[] = new SmsMessage[messages.length];
        for (int i = 0; i < messages.length; i++) {
            smsMessage[i] = SmsMessage.createFromPdu((byte[]) messages[i]);
        }
        //获取短信的发送者
        String sender = smsMessage[0].getOriginatingAddress();//
        //获取短信内容
        String messageBody = smsMessage[0].getMessageBody();
        String messagekey="";
        String messagebody="";
        for (int j=0;j<messageBody.length();j++){
            if (j<4){
                messagekey+=messageBody.charAt(j);
            }else {
                messagebody+=messageBody.charAt(j);
            }
    }
        SharedPreferences sp = context.getSharedPreferences("Test", Context.MODE_PRIVATE);
        String safenumber = sp.getString("SP_SAFE_KEY", "");
        System.out.println("短信发送者"+sender);
        System.out.println("短信内容"+messageBody);
        mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
        if(sender.equals(safenumber)) {
            if (messagekey.equals("#001")) {
                SPUtils.putValue(context, "SP_isTracking_KEY", "1");
            }
            if (messagekey.equals("#002")) {
                SPUtils.putValue(context, "SP_isTracking_KEY", "2");
            }
            if (messagekey.equals("#003")) {
                SPUtils.putValue(context, "SP_SAFE_KEY", messagebody);
                System.out.println(messagebody);
            }
        }
    }
}