添加libgpsrelaysentinel类库初始源码
This commit is contained in:
@@ -56,6 +56,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
api project(':libgpsrelaysentinel')
|
||||||
|
|
||||||
api 'com.google.code.gson:gson:2.10.1'
|
api 'com.google.code.gson:gson:2.10.1'
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,15 @@ import android.content.Intent;
|
|||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationListener;
|
import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.manager.GpsSubscribeManager;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.manager.SubscribeLocationManager;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeMsg;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class MainService extends Service {
|
public class MainService extends Service {
|
||||||
|
|
||||||
@@ -72,6 +75,31 @@ public class MainService extends Service {
|
|||||||
String gpsInfo = "Lat: " + location.getLatitude() + ", Lng: " + location.getLongitude();
|
String gpsInfo = "Lat: " + location.getLatitude() + ", Lng: " + location.getLongitude();
|
||||||
LogUtils.d(TAG, "Location changed: " + gpsInfo);
|
LogUtils.d(TAG, "Location changed: " + gpsInfo);
|
||||||
updateNotification(gpsInfo);
|
updateNotification(gpsInfo);
|
||||||
|
|
||||||
|
//管理器初始化
|
||||||
|
GpsSubscribeManager subscribeManager = GpsSubscribeManager.getInstance();
|
||||||
|
SubscribeLocationManager locationManager = SubscribeLocationManager.getInstance();
|
||||||
|
|
||||||
|
//遍历所有订阅者做距离判断+定点更新
|
||||||
|
Map<String, GpsSubscribeMsg> subscribeMap = subscribeManager.getSubscribeMap();
|
||||||
|
for (Map.Entry<String, GpsSubscribeMsg> entry : subscribeMap.entrySet()) {
|
||||||
|
String sid = entry.getKey();
|
||||||
|
GpsSubscribeMsg subscribeMsg = entry.getValue();
|
||||||
|
|
||||||
|
double nowLat = location.getLatitude();
|
||||||
|
double nowLng = location.getLongitude();
|
||||||
|
|
||||||
|
//判断是否满足推送
|
||||||
|
boolean canPush = locationManager.isNeedPush(sid, nowLat, nowLng);
|
||||||
|
if (canPush) {
|
||||||
|
//执行发送GPS广播
|
||||||
|
//sendGpsBroadcast(...);
|
||||||
|
|
||||||
|
//推送成功立刻刷新订阅者基准坐标
|
||||||
|
locationManager.updateSubscriberPoint(sid, nowLat, nowLng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
1
libgpsrelaysentinel/.gitignore
vendored
Normal file
1
libgpsrelaysentinel/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
25
libgpsrelaysentinel/build.gradle
Normal file
25
libgpsrelaysentinel/build.gradle
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'maven-publish'
|
||||||
|
apply from: '../.winboll/winboll_lib_build.gradle'
|
||||||
|
apply from: '../.winboll/winboll_lint_build.gradle'
|
||||||
|
|
||||||
|
android {
|
||||||
|
// 适配MIUI12
|
||||||
|
compileSdkVersion 30
|
||||||
|
buildToolsVersion "30.0.3"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 21
|
||||||
|
targetSdkVersion 30
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
}
|
||||||
8
libgpsrelaysentinel/build.properties
Normal file
8
libgpsrelaysentinel/build.properties
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
|
#Fri May 01 17:09:11 HKT 2026
|
||||||
|
stageCount=57
|
||||||
|
libraryProject=libdebugtemp
|
||||||
|
baseVersion=15.0
|
||||||
|
publishVersion=15.0.56
|
||||||
|
buildCount=0
|
||||||
|
baseBetaVersion=15.0.57
|
||||||
17
libgpsrelaysentinel/proguard-rules.pro
vendored
Normal file
17
libgpsrelaysentinel/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in C:/tools/adt-bundle-windows-x86_64-20131030/sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
27
libgpsrelaysentinel/src/main/AndroidManifest.xml
Normal file
27
libgpsrelaysentinel/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="cc.winboll.studio.libgpsrelaysentinel">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<service
|
||||||
|
android:name=".service.GpsSubscribeReceiverService"
|
||||||
|
android:exported="true"
|
||||||
|
android:enabled="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="cc.winboll.studio.libgpsrelaysentinel.action.RECEIVE" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<receiver android:name=".receiver.GpsSubscribeObserverReceiver">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name=".receiver.GpsSubscribeObserverReceiver"/>
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</receiver>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:25
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeConst;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeMsg;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeResult;
|
||||||
|
|
||||||
|
public final class GpsSubscribeManager {
|
||||||
|
|
||||||
|
private static GpsSubscribeManager instance;
|
||||||
|
private final Map<String,GpsSubscribeMsg> subscribeMap;
|
||||||
|
private Context appContext;
|
||||||
|
|
||||||
|
private GpsSubscribeManager(){
|
||||||
|
subscribeMap = new HashMap<String, GpsSubscribeMsg>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GpsSubscribeManager getInstance(){
|
||||||
|
if(instance == null){
|
||||||
|
instance = new GpsSubscribeManager();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initContext(final Context context){
|
||||||
|
this.appContext = context.getApplicationContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSubscribe(final GpsSubscribeMsg subscribeMsg){
|
||||||
|
if(subscribeMsg == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subscribeMap.put(subscribeMsg.getSubscribeUniqueId(),subscribeMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSubscribe(final String sid){
|
||||||
|
if(sid == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subscribeMap.remove(sid);
|
||||||
|
SubscribeLocationManager.getInstance().removeSubscribe(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSubscribeExist(final String sid){
|
||||||
|
return subscribeMap.containsKey(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendSubscribeResult(final GpsSubscribeResult result){
|
||||||
|
if(appContext == null || result == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Intent intent = new Intent(GpsSubscribeConst.ACTION_SUBSCRIBE_CALLBACK);
|
||||||
|
intent.putExtra("data",result);
|
||||||
|
appContext.sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAllSubscribe(){
|
||||||
|
subscribeMap.clear();
|
||||||
|
SubscribeLocationManager.getInstance().clearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, GpsSubscribeMsg> getSubscribeMap() {
|
||||||
|
return subscribeMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:26
|
||||||
|
*/
|
||||||
|
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeConst;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeMsg;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.LocationPoint;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public final class SubscribeLocationManager {
|
||||||
|
|
||||||
|
private static SubscribeLocationManager instance;
|
||||||
|
private final Map<String,GpsSubscribeMsg> subscribeConfigMap;
|
||||||
|
private final Map<String,LocationPoint> subscriberPointMap;
|
||||||
|
|
||||||
|
private SubscribeLocationManager(){
|
||||||
|
subscribeConfigMap = new HashMap<String, GpsSubscribeMsg>();
|
||||||
|
subscriberPointMap = new HashMap<String, LocationPoint>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SubscribeLocationManager getInstance(){
|
||||||
|
if(instance == null){
|
||||||
|
instance = new SubscribeLocationManager();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putSubscribeConfig(final String sid,final GpsSubscribeMsg msg){
|
||||||
|
subscribeConfigMap.put(sid,msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initSubscriberPoint(final String sid,double lat,double lng){
|
||||||
|
subscriberPointMap.put(sid,new LocationPoint(lat,lng,System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateSubscriberPoint(final String sid,double lat,double lng){
|
||||||
|
subscriberPointMap.put(sid,new LocationPoint(lat,lng,System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationPoint getLastPoint(final String sid){
|
||||||
|
return subscriberPointMap.get(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GpsSubscribeMsg getSubscribeConfig(final String sid){
|
||||||
|
return subscribeConfigMap.get(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNeedPush(final String sid,double nowLat,double nowLng){
|
||||||
|
GpsSubscribeMsg config = getSubscribeConfig(sid);
|
||||||
|
if(config == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config.getSubscribeMode() == GpsSubscribeConst.SUB_TYPE_ALL){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationPoint lastPoint = getLastPoint(sid);
|
||||||
|
if(lastPoint == null){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double distance = calculateDistance(
|
||||||
|
lastPoint.getLatitude(),lastPoint.getLongitude(),
|
||||||
|
nowLat,nowLng
|
||||||
|
);
|
||||||
|
return distance >= config.getStepDistanceM();
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculateDistance(double lat1,double lng1,double lat2,double lng2){
|
||||||
|
double radLat1 = Math.toRadians(lat1);
|
||||||
|
double radLat2 = Math.toRadians(lat2);
|
||||||
|
double radLng1 = Math.toRadians(lng1);
|
||||||
|
double radLng2 = Math.toRadians(lng2);
|
||||||
|
|
||||||
|
double latDiff = radLat1 - radLat2;
|
||||||
|
double lngDiff = radLng1 - radLng2;
|
||||||
|
|
||||||
|
double result = 2 * Math.asin(Math.sqrt(
|
||||||
|
Math.pow(Math.sin(latDiff / 2),2)
|
||||||
|
+ Math.cos(radLat1) * Math.cos(radLat2)
|
||||||
|
* Math.pow(Math.sin(lngDiff / 2),2)
|
||||||
|
));
|
||||||
|
result = result * GpsSubscribeConst.EARTH_RADIUS;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSubscribe(final String sid){
|
||||||
|
subscribeConfigMap.remove(sid);
|
||||||
|
subscriberPointMap.remove(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAll(){
|
||||||
|
subscribeConfigMap.clear();
|
||||||
|
subscriberPointMap.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:22
|
||||||
|
* WinBoLL Studio
|
||||||
|
* Java7 | API26-30
|
||||||
|
*/
|
||||||
|
public final class GpsSubscribeConst {
|
||||||
|
|
||||||
|
// 新增:GPS定位推送广播
|
||||||
|
public static final String ACTION_GPS_LOCATION = "cc.winboll.studio.ACTION_GPS_LOCATION";
|
||||||
|
|
||||||
|
//订阅运行模式
|
||||||
|
public static final int SUB_TYPE_ALL = 1;
|
||||||
|
public static final int SUB_TYPE_STEP_DISTANCE = 2;
|
||||||
|
|
||||||
|
//原始数据订阅类型
|
||||||
|
public static final int SUBSCRIBE_TYPE_LOCATION = 1;
|
||||||
|
public static final int SUBSCRIBE_TYPE_SATELLITE = 2;
|
||||||
|
public static final int SUBSCRIBE_TYPE_NMEA = 3;
|
||||||
|
|
||||||
|
//订阅返回码
|
||||||
|
public static final int RESULT_SUCCESS = 0;
|
||||||
|
public static final int RESULT_PERMISSION_DENY = 1;
|
||||||
|
public static final int RESULT_PARAM_ERROR = 2;
|
||||||
|
public static final int RESULT_GPS_NOT_AVAILABLE = 3;
|
||||||
|
public static final int RESULT_SYSTEM_LIMIT = 4;
|
||||||
|
|
||||||
|
//GPS设备状态
|
||||||
|
public static final int GPS_STATE_CLOSE = 0;
|
||||||
|
public static final int GPS_STATE_SCANNING = 1;
|
||||||
|
public static final int GPS_STATE_LOCATED = 2;
|
||||||
|
public static final int GPS_STATE_SIGNAL_WEAK = 3;
|
||||||
|
|
||||||
|
//广播Action
|
||||||
|
public static final String ACTION_SUBSCRIBE_REQUEST = "cc.winboll.studio.GPS_SUBSCRIBE_REQUEST";
|
||||||
|
public static final String ACTION_SUBSCRIBE_CALLBACK = "cc.winboll.studio.GPS_SUBSCRIBE_CALLBACK";
|
||||||
|
|
||||||
|
//超时毫秒
|
||||||
|
public static final long SUBSCRIBE_TIME_OUT = 5000;
|
||||||
|
|
||||||
|
//地球半径 距离计算常量
|
||||||
|
public static final double EARTH_RADIUS = 6378137.0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:24
|
||||||
|
*/
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public final class GpsSubscribeMsg implements Parcelable {
|
||||||
|
|
||||||
|
private final String subscribePackage;
|
||||||
|
private final int subscribeMode;
|
||||||
|
private final float stepDistanceM;
|
||||||
|
|
||||||
|
private final int subscribeType;
|
||||||
|
private final long updateInterval;
|
||||||
|
private final float minDistance;
|
||||||
|
private final boolean backgroundPush;
|
||||||
|
private final String subscribeUniqueId;
|
||||||
|
|
||||||
|
public GpsSubscribeMsg(String subscribePackage,
|
||||||
|
int subscribeMode,
|
||||||
|
float stepDistanceM,
|
||||||
|
int subscribeType,
|
||||||
|
long updateInterval,
|
||||||
|
float minDistance,
|
||||||
|
boolean backgroundPush,
|
||||||
|
String subscribeUniqueId) {
|
||||||
|
this.subscribePackage = subscribePackage;
|
||||||
|
this.subscribeMode = subscribeMode;
|
||||||
|
this.stepDistanceM = stepDistanceM;
|
||||||
|
this.subscribeType = subscribeType;
|
||||||
|
this.updateInterval = updateInterval;
|
||||||
|
this.minDistance = minDistance;
|
||||||
|
this.backgroundPush = backgroundPush;
|
||||||
|
this.subscribeUniqueId = subscribeUniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubscribePackage() {
|
||||||
|
return subscribePackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSubscribeMode() {
|
||||||
|
return subscribeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getStepDistanceM() {
|
||||||
|
return stepDistanceM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSubscribeType() {
|
||||||
|
return subscribeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getUpdateInterval() {
|
||||||
|
return updateInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMinDistance() {
|
||||||
|
return minDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBackgroundPush() {
|
||||||
|
return backgroundPush;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubscribeUniqueId() {
|
||||||
|
return subscribeUniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(subscribePackage);
|
||||||
|
dest.writeInt(subscribeMode);
|
||||||
|
dest.writeFloat(stepDistanceM);
|
||||||
|
dest.writeInt(subscribeType);
|
||||||
|
dest.writeLong(updateInterval);
|
||||||
|
dest.writeFloat(minDistance);
|
||||||
|
dest.writeByte((byte) (backgroundPush ? 1 : 0));
|
||||||
|
dest.writeString(subscribeUniqueId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<GpsSubscribeMsg> CREATOR = new Creator<GpsSubscribeMsg>() {
|
||||||
|
@Override
|
||||||
|
public GpsSubscribeMsg createFromParcel(Parcel in) {
|
||||||
|
return new GpsSubscribeMsg(
|
||||||
|
in.readString(),
|
||||||
|
in.readInt(),
|
||||||
|
in.readFloat(),
|
||||||
|
in.readInt(),
|
||||||
|
in.readLong(),
|
||||||
|
in.readFloat(),
|
||||||
|
in.readByte() == 1,
|
||||||
|
in.readString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GpsSubscribeMsg[] newArray(int size) {
|
||||||
|
return new GpsSubscribeMsg[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Bundle convertToBundle() {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("pkg", subscribePackage);
|
||||||
|
bundle.putInt("subMode",subscribeMode);
|
||||||
|
bundle.putFloat("stepM",stepDistanceM);
|
||||||
|
bundle.putInt("type", subscribeType);
|
||||||
|
bundle.putLong("interval", updateInterval);
|
||||||
|
bundle.putFloat("distance", minDistance);
|
||||||
|
bundle.putBoolean("bgPush", backgroundPush);
|
||||||
|
bundle.putString("sid", subscribeUniqueId);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GpsSubscribeMsg createByBundle(Bundle bundle) {
|
||||||
|
return new GpsSubscribeMsg(
|
||||||
|
bundle.getString("pkg"),
|
||||||
|
bundle.getInt("subMode"),
|
||||||
|
bundle.getFloat("stepM"),
|
||||||
|
bundle.getInt("type"),
|
||||||
|
bundle.getLong("interval"),
|
||||||
|
bundle.getFloat("distance"),
|
||||||
|
bundle.getBoolean("bgPush"),
|
||||||
|
bundle.getString("sid")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:25
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public final class GpsSubscribeResult implements Parcelable {
|
||||||
|
|
||||||
|
private final String subscribeUniqueId;
|
||||||
|
private final int resultCode;
|
||||||
|
private final String resultDesc;
|
||||||
|
private final int gpsRunningState;
|
||||||
|
private final long realEffectiveInterval;
|
||||||
|
private final long currentTimeStamp;
|
||||||
|
|
||||||
|
public GpsSubscribeResult(String subscribeUniqueId,
|
||||||
|
int resultCode,
|
||||||
|
String resultDesc,
|
||||||
|
int gpsRunningState,
|
||||||
|
long realEffectiveInterval,
|
||||||
|
long currentTimeStamp) {
|
||||||
|
this.subscribeUniqueId = subscribeUniqueId;
|
||||||
|
this.resultCode = resultCode;
|
||||||
|
this.resultDesc = resultDesc;
|
||||||
|
this.gpsRunningState = gpsRunningState;
|
||||||
|
this.realEffectiveInterval = realEffectiveInterval;
|
||||||
|
this.currentTimeStamp = currentTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubscribeUniqueId() {
|
||||||
|
return subscribeUniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getResultCode() {
|
||||||
|
return resultCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResultDesc() {
|
||||||
|
return resultDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGpsRunningState() {
|
||||||
|
return gpsRunningState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRealEffectiveInterval() {
|
||||||
|
return realEffectiveInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCurrentTimeStamp() {
|
||||||
|
return currentTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(subscribeUniqueId);
|
||||||
|
dest.writeInt(resultCode);
|
||||||
|
dest.writeString(resultDesc);
|
||||||
|
dest.writeInt(gpsRunningState);
|
||||||
|
dest.writeLong(realEffectiveInterval);
|
||||||
|
dest.writeLong(currentTimeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<GpsSubscribeResult> CREATOR = new Creator<GpsSubscribeResult>() {
|
||||||
|
@Override
|
||||||
|
public GpsSubscribeResult createFromParcel(Parcel in) {
|
||||||
|
return new GpsSubscribeResult(
|
||||||
|
in.readString(),
|
||||||
|
in.readInt(),
|
||||||
|
in.readString(),
|
||||||
|
in.readInt(),
|
||||||
|
in.readLong(),
|
||||||
|
in.readLong()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GpsSubscribeResult[] newArray(int size) {
|
||||||
|
return new GpsSubscribeResult[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Bundle convertToBundle() {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("sid", subscribeUniqueId);
|
||||||
|
bundle.putInt("code", resultCode);
|
||||||
|
bundle.putString("desc", resultDesc);
|
||||||
|
bundle.putInt("gpsState", gpsRunningState);
|
||||||
|
bundle.putLong("realInterval", realEffectiveInterval);
|
||||||
|
bundle.putLong("time", currentTimeStamp);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GpsSubscribeResult createByBundle(Bundle bundle) {
|
||||||
|
return new GpsSubscribeResult(
|
||||||
|
bundle.getString("sid"),
|
||||||
|
bundle.getInt("code"),
|
||||||
|
bundle.getString("desc"),
|
||||||
|
bundle.getInt("gpsState"),
|
||||||
|
bundle.getLong("realInterval"),
|
||||||
|
bundle.getLong("time")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:23
|
||||||
|
* 订阅者基准定点坐标
|
||||||
|
* 每次推送成功自动更新
|
||||||
|
*/
|
||||||
|
public final class LocationPoint {
|
||||||
|
|
||||||
|
private final double latitude;
|
||||||
|
private final double longitude;
|
||||||
|
private final long recordTime;
|
||||||
|
|
||||||
|
public LocationPoint(double latitude, double longitude, long recordTime) {
|
||||||
|
this.latitude = latitude;
|
||||||
|
this.longitude = longitude;
|
||||||
|
this.recordTime = recordTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRecordTime() {
|
||||||
|
return recordTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.receiver;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:27
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeConst;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeResult;
|
||||||
|
|
||||||
|
public final class GpsSubscribeObserverReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
private OnSubscribeResultListener listener;
|
||||||
|
|
||||||
|
public void setOnSubscribeResultListener(OnSubscribeResultListener listener){
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if(GpsSubscribeConst.ACTION_SUBSCRIBE_CALLBACK.equals(action)){
|
||||||
|
GpsSubscribeResult result = intent.getParcelableExtra("data");
|
||||||
|
if(listener != null && result != null){
|
||||||
|
listener.onResultBack(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnSubscribeResultListener{
|
||||||
|
void onResultBack(GpsSubscribeResult result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.service;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:46
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeConst;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeMsg;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeResult;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.LocationPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对外消息接收服务:外部App可bind或start
|
||||||
|
* 收到GPS消息后,通过本地广播回调给外部App
|
||||||
|
*/
|
||||||
|
public final class GpsSubscribeReceiverService extends Service {
|
||||||
|
|
||||||
|
// 外部回调监听
|
||||||
|
public interface GpsMessageListener {
|
||||||
|
void onGpsLocation(LocationPoint point, GpsSubscribeMsg config);
|
||||||
|
void onSubscribeResult(GpsSubscribeResult result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<GpsMessageListener> listeners = new CopyOnWriteArrayList<GpsMessageListener>();
|
||||||
|
private final IBinder localBinder = new LocalBinder();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 外部App绑定服务
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return localBinder;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 外部App startService 入口:接收订阅请求
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
if (intent != null && intent.getParcelableExtra("req") != null) {
|
||||||
|
GpsSubscribeMsg msg = intent.getParcelableExtra("req");
|
||||||
|
handleSubscribeRequest(msg);
|
||||||
|
}
|
||||||
|
return START_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理订阅请求:发送给管理器,并回执
|
||||||
|
private void handleSubscribeRequest(final GpsSubscribeMsg msg) {
|
||||||
|
// 加入订阅管理
|
||||||
|
cc.winboll.studio.libgpsrelaysentinel.manager.GpsSubscribeManager
|
||||||
|
.getInstance().addSubscribe(msg);
|
||||||
|
cc.winboll.studio.libgpsrelaysentinel.manager.SubscribeLocationManager
|
||||||
|
.getInstance().putSubscribeConfig(msg.getSubscribeUniqueId(), msg);
|
||||||
|
|
||||||
|
// 回执成功
|
||||||
|
GpsSubscribeResult result = new GpsSubscribeResult(
|
||||||
|
msg.getSubscribeUniqueId(),
|
||||||
|
GpsSubscribeConst.RESULT_SUCCESS,
|
||||||
|
"subscribe ok",
|
||||||
|
GpsSubscribeConst.GPS_STATE_LOCATED,
|
||||||
|
1000,
|
||||||
|
System.currentTimeMillis()
|
||||||
|
);
|
||||||
|
sendSubscribeResultBroadcast(result);
|
||||||
|
notifySubscribeResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 供内部(GPS服务)调用:推送定位消息
|
||||||
|
public void pushLocation(final LocationPoint point, final GpsSubscribeMsg config) {
|
||||||
|
sendLocationBroadcast(point, config);
|
||||||
|
notifyGpsLocation(point, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 广播回调(跨进程/外部App接收) ----------
|
||||||
|
private void sendLocationBroadcast(final LocationPoint point, final GpsSubscribeMsg config) {
|
||||||
|
Intent intent = new Intent(GpsSubscribeConst.ACTION_GPS_LOCATION);
|
||||||
|
intent.putExtra("point", point);
|
||||||
|
intent.putExtra("config", config);
|
||||||
|
sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendSubscribeResultBroadcast(final GpsSubscribeResult result) {
|
||||||
|
Intent intent = new Intent(GpsSubscribeConst.ACTION_SUBSCRIBE_CALLBACK);
|
||||||
|
intent.putExtra("data", result);
|
||||||
|
sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 本地Binder(同进程直接回调) ----------
|
||||||
|
public class LocalBinder extends Binder {
|
||||||
|
public GpsSubscribeReceiverService getService() {
|
||||||
|
return GpsSubscribeReceiverService.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(final GpsMessageListener l) {
|
||||||
|
if (l != null && !listeners.contains(l)) {
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeListener(final GpsMessageListener l) {
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyGpsLocation(final LocationPoint point, final GpsSubscribeMsg config) {
|
||||||
|
for (GpsMessageListener l : listeners) {
|
||||||
|
l.onGpsLocation(point, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifySubscribeResult(final GpsSubscribeResult result) {
|
||||||
|
for (GpsMessageListener l : listeners) {
|
||||||
|
l.onSubscribeResult(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
listeners.clear();
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:26
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
|
||||||
|
public final class TimeCountUtil {
|
||||||
|
|
||||||
|
private final Handler mHandler;
|
||||||
|
private long totalTime;
|
||||||
|
private boolean isRunning;
|
||||||
|
public static final int COUNT_FINISH = 1001;
|
||||||
|
|
||||||
|
public TimeCountUtil(final OnCountListener listener) {
|
||||||
|
mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
super.handleMessage(msg);
|
||||||
|
if(msg.what == COUNT_FINISH){
|
||||||
|
isRunning = false;
|
||||||
|
if(listener != null){
|
||||||
|
listener.onTimeOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start(long time){
|
||||||
|
if(isRunning){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
totalTime = time;
|
||||||
|
isRunning = true;
|
||||||
|
mHandler.sendEmptyMessageDelayed(COUNT_FINISH,totalTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(){
|
||||||
|
mHandler.removeMessages(COUNT_FINISH);
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnCountListener{
|
||||||
|
void onTimeOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
package cc.winboll.studio.libgpsrelaysentinel.view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
|
* @Date 2026/05/07 10:27
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.RadioGroup;
|
||||||
|
import android.widget.Switch;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.R;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeConst;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeMsg;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.model.GpsSubscribeResult;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.receiver.GpsSubscribeObserverReceiver;
|
||||||
|
import cc.winboll.studio.libgpsrelaysentinel.util.TimeCountUtil;
|
||||||
|
|
||||||
|
public final class GpsSubscribeControlView extends LinearLayout {
|
||||||
|
|
||||||
|
private RadioGroup rgSubMode;
|
||||||
|
private RadioButton rbAll;
|
||||||
|
private RadioButton rbStep;
|
||||||
|
private LinearLayout layoutStepSetting;
|
||||||
|
private EditText etStepMeter;
|
||||||
|
|
||||||
|
private Switch mSwitchSubscribe;
|
||||||
|
private TextView mTvCountTip;
|
||||||
|
|
||||||
|
private TimeCountUtil mTimeCountUtil;
|
||||||
|
private GpsSubscribeObserverReceiver mResultReceiver;
|
||||||
|
private String currentSubscribeSid;
|
||||||
|
private boolean isSubscribeSuccess;
|
||||||
|
|
||||||
|
public GpsSubscribeControlView(Context context) {
|
||||||
|
super(context);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GpsSubscribeControlView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initView(){
|
||||||
|
setOrientation(VERTICAL);
|
||||||
|
inflate(getContext(),R.layout.view_gps_subscribe_control,this);
|
||||||
|
|
||||||
|
rgSubMode = findViewById(R.id.rg_sub_mode);
|
||||||
|
rbAll = findViewById(R.id.rb_all);
|
||||||
|
rbStep = findViewById(R.id.rb_step);
|
||||||
|
layoutStepSetting = findViewById(R.id.layout_step_setting);
|
||||||
|
etStepMeter = findViewById(R.id.et_step_meter);
|
||||||
|
|
||||||
|
mSwitchSubscribe = findViewById(R.id.switch_subscribe);
|
||||||
|
mTvCountTip = findViewById(R.id.tv_count_tip);
|
||||||
|
|
||||||
|
initModeSwitch();
|
||||||
|
initCountUtil();
|
||||||
|
initReceiver();
|
||||||
|
initSwitchEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initModeSwitch(){
|
||||||
|
rgSubMode.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||||
|
layoutStepSetting.setVisibility(checkedId == R.id.rb_step ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initCountUtil(){
|
||||||
|
mTimeCountUtil = new TimeCountUtil(new TimeCountUtil.OnCountListener() {
|
||||||
|
@Override
|
||||||
|
public void onTimeOut() {
|
||||||
|
if(!isSubscribeSuccess){
|
||||||
|
mSwitchSubscribe.setChecked(false);
|
||||||
|
mTvCountTip.setText("订阅超时,已自动关闭");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initReceiver(){
|
||||||
|
mResultReceiver = new GpsSubscribeObserverReceiver();
|
||||||
|
mResultReceiver.setOnSubscribeResultListener(new GpsSubscribeObserverReceiver.OnSubscribeResultListener() {
|
||||||
|
@Override
|
||||||
|
public void onResultBack(GpsSubscribeResult result) {
|
||||||
|
if(currentSubscribeSid.equals(result.getSubscribeUniqueId())){
|
||||||
|
isSubscribeSuccess = true;
|
||||||
|
mTimeCountUtil.cancel();
|
||||||
|
mTvCountTip.setText("订阅已生效,通讯正常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(GpsSubscribeConst.ACTION_SUBSCRIBE_CALLBACK);
|
||||||
|
getContext().registerReceiver(mResultReceiver,filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSwitchEvent(){
|
||||||
|
mSwitchSubscribe.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
if(isChecked){
|
||||||
|
startSubscribe();
|
||||||
|
}else{
|
||||||
|
stopSubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startSubscribe(){
|
||||||
|
isSubscribeSuccess = false;
|
||||||
|
currentSubscribeSid = UUID.randomUUID().toString();
|
||||||
|
mTvCountTip.setText("等待订阅返回中...");
|
||||||
|
|
||||||
|
int subMode = GpsSubscribeConst.SUB_TYPE_ALL;
|
||||||
|
float stepMeter = 10.0f;
|
||||||
|
|
||||||
|
if(rbStep.isChecked()){
|
||||||
|
subMode = GpsSubscribeConst.SUB_TYPE_STEP_DISTANCE;
|
||||||
|
try{
|
||||||
|
stepMeter = Float.parseFloat(etStepMeter.getText().toString().trim());
|
||||||
|
}catch (Exception e){
|
||||||
|
stepMeter = 10.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GpsSubscribeMsg msg = new GpsSubscribeMsg(
|
||||||
|
getContext().getPackageName(),
|
||||||
|
subMode,
|
||||||
|
stepMeter,
|
||||||
|
GpsSubscribeConst.SUBSCRIBE_TYPE_LOCATION,
|
||||||
|
1000,
|
||||||
|
1.0f,
|
||||||
|
true,
|
||||||
|
currentSubscribeSid
|
||||||
|
);
|
||||||
|
|
||||||
|
Intent intent = new Intent(GpsSubscribeConst.ACTION_SUBSCRIBE_REQUEST);
|
||||||
|
intent.putExtra("req",msg);
|
||||||
|
getContext().sendBroadcast(intent);
|
||||||
|
|
||||||
|
mTimeCountUtil.start(GpsSubscribeConst.SUBSCRIBE_TIME_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopSubscribe(){
|
||||||
|
mTimeCountUtil.cancel();
|
||||||
|
isSubscribeSuccess = false;
|
||||||
|
mTvCountTip.setText("订阅已关闭");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void release(){
|
||||||
|
mTimeCountUtil.cancel();
|
||||||
|
if(mResultReceiver != null){
|
||||||
|
getContext().unregisterReceiver(mResultReceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BIN
libgpsrelaysentinel/src/main/res/drawable-hdpi/ic_launcher.png
Normal file
BIN
libgpsrelaysentinel/src/main/res/drawable-hdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
BIN
libgpsrelaysentinel/src/main/res/drawable-mdpi/ic_launcher.png
Normal file
BIN
libgpsrelaysentinel/src/main/res/drawable-mdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
BIN
libgpsrelaysentinel/src/main/res/drawable-xhdpi/ic_launcher.png
Normal file
BIN
libgpsrelaysentinel/src/main/res/drawable-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
libgpsrelaysentinel/src/main/res/drawable-xxhdpi/ic_launcher.png
Normal file
BIN
libgpsrelaysentinel/src/main/res/drawable-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,99 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="订阅模式:"
|
||||||
|
android:textSize="14sp"/>
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rg_sub_mode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_all"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="全消息订阅"
|
||||||
|
android:checked="true"/>
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_step"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="步长订阅"/>
|
||||||
|
</RadioGroup>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_step_setting"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="移动步长阈值(米):"
|
||||||
|
android:textSize="14sp"/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/et_step_meter"
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="numberDecimal"
|
||||||
|
android:text="10"
|
||||||
|
android:gravity="center"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="GPS订阅总开关"
|
||||||
|
android:textSize="14sp"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/switch_subscribe"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_count_tip"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="未订阅"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#666666"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
5
libgpsrelaysentinel/src/main/res/values-v21/styles.xml
Normal file
5
libgpsrelaysentinel/src/main/res/values-v21/styles.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="AppTheme" parent="@android:style/Theme.Material.Light">
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
8
libgpsrelaysentinel/src/main/res/values/strings.xml
Normal file
8
libgpsrelaysentinel/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="lib_name">libdebugtemp</string>
|
||||||
|
<string name="hello_world">Hello world!</string>
|
||||||
|
<string name="text_libraryactivity">LibraryActivity</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
5
libgpsrelaysentinel/src/main/res/values/styles.xml
Normal file
5
libgpsrelaysentinel/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="AppTheme" parent="@android:style/Theme.Holo.Light">
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
Reference in New Issue
Block a user