diff --git a/app/build.gradle b/app/build.gradle index 714f7f18..71df64b3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,11 @@ apply plugin: 'com.android.application' +def getGitCommitHash() { + return providers.exec { + commandLine 'git', 'rev-parse', '--short', 'HEAD' + }.standardOutput.asText.get().trim() +} + android { signingConfigs { debug { @@ -24,7 +30,7 @@ android { //noinspection ExpiredTargetSdkVersion targetSdkVersion 32 versionCode 1121 - versionName '1.12.1' // https://semver.org/lang/zh-CN/ + versionName '1.12.1-' + getGitCommitHash() testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" resConfigs 'zh', 'zh-rCN', 'en', 'en-rUS' ndk { diff --git a/app/src/main/java/com/zcshou/gogogo/HistoryActivity.java b/app/src/main/java/com/zcshou/gogogo/HistoryActivity.java index f8e20060..e934a957 100644 --- a/app/src/main/java/com/zcshou/gogogo/HistoryActivity.java +++ b/app/src/main/java/com/zcshou/gogogo/HistoryActivity.java @@ -1,5 +1,7 @@ package com.zcshou.gogogo; +import android.app.Activity; +import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; @@ -28,8 +30,6 @@ import java.math.RoundingMode; import java.util.ArrayList; import java.util.HashMap; -import java.util.Objects; -import java.util.Locale; import java.util.List; import java.util.Map; @@ -48,7 +48,6 @@ public class HistoryActivity extends BaseActivity { private LinearLayout mSearchLayout; private SQLiteDatabase mHistoryLocationDB; private List> mAllRecord; - private SharedPreferences sharedPreferences; @Override protected void onCreate(Bundle savedInstanceState) { @@ -68,8 +67,6 @@ protected void onCreate(Bundle savedInstanceState) { actionBar.setDisplayHomeAsUpEnabled(true); } - sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); - initLocationDataBase(); initSearchView(); @@ -175,6 +172,7 @@ private List> fetchAllRecord() { private void recordArchive() { double limits; try { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); limits = Double.parseDouble(sharedPreferences.getString("setting_pos_history", getResources().getString(R.string.history_expiration))); } catch (NumberFormatException e) { // GOOD: The exception is caught. limits = 7; @@ -295,50 +293,20 @@ private void showInputDialog(String locID, String name) { builder.show(); } - private String[] randomOffset(String longitude, String latitude) { - String max_offset_default = getResources().getString(R.string.setting_random_offset_default); - double lon_max_offset = Double.parseDouble(Objects.requireNonNull(sharedPreferences.getString("setting_lon_max_offset", max_offset_default))); - double lat_max_offset = Double.parseDouble(Objects.requireNonNull(sharedPreferences.getString("setting_lat_max_offset", max_offset_default))); - double lon = Double.parseDouble(longitude); - double lat = Double.parseDouble(latitude); - - double randomLonOffset = (Math.random() * 2 - 1) * lon_max_offset; // Longitude offset (meters) - double randomLatOffset = (Math.random() * 2 - 1) * lat_max_offset; // Latitude offset (meters) - - lon += randomLonOffset / 111320; // (meters -> longitude) - lat += randomLatOffset / 110574; // (meters -> latitude) - - String offsetMessage = String.format(Locale.US, "经度偏移: %.2f米\n纬度偏移: %.2f米", randomLonOffset, randomLatOffset); - GoUtils.DisplayToast(this, offsetMessage); - - return new String[]{String.valueOf(lon), String.valueOf(lat)}; - } - private void initRecordListView() { noRecordText = findViewById(R.id.record_no_textview); mSearchLayout = findViewById(R.id.search_linear); mRecordListView = findViewById(R.id.record_list_view); mRecordListView.setOnItemClickListener((adapterView, view, i, l) -> { - String bd09Longitude; - String bd09Latitude; - String name; - name = (String) ((TextView) view.findViewById(R.id.LocationText)).getText(); String bd09LatLng = (String) ((TextView) view.findViewById(R.id.BDLatLngText)).getText(); bd09LatLng = bd09LatLng.substring(bd09LatLng.indexOf('[') + 1, bd09LatLng.indexOf(']')); String[] latLngStr = bd09LatLng.split(" "); - bd09Longitude = latLngStr[0].substring(latLngStr[0].indexOf(':') + 1); - bd09Latitude = latLngStr[1].substring(latLngStr[1].indexOf(':') + 1); - - // Random offset - if(sharedPreferences.getBoolean("setting_random_offset", false)) { - String[] offsetResult = randomOffset(bd09Longitude, bd09Latitude); - bd09Longitude = offsetResult[0]; - bd09Latitude = offsetResult[1]; - } - - if (!MainActivity.showLocation(name, bd09Longitude, bd09Latitude)) { - GoUtils.DisplayToast(this, getResources().getString(R.string.history_error_location)); - } + String bd09Longitude = latLngStr[0].substring(latLngStr[0].indexOf(':') + 1); + String bd09Latitude = latLngStr[1].substring(latLngStr[1].indexOf(':') + 1); + Intent resultIntent = new Intent(); + resultIntent.putExtra("bd09_lon", bd09Longitude); + resultIntent.putExtra("bd09_lat", bd09Latitude); + setResult(Activity.RESULT_OK, resultIntent); this.finish(); }); diff --git a/app/src/main/java/com/zcshou/gogogo/MainActivity.java b/app/src/main/java/com/zcshou/gogogo/MainActivity.java index 7c8d6c0a..cf2da956 100644 --- a/app/src/main/java/com/zcshou/gogogo/MainActivity.java +++ b/app/src/main/java/com/zcshou/gogogo/MainActivity.java @@ -1,5 +1,6 @@ package com.zcshou.gogogo; +import android.app.Activity; import android.app.DownloadManager; import android.content.BroadcastReceiver; import android.content.ClipData; @@ -46,6 +47,8 @@ import android.widget.SimpleAdapter; import android.widget.TextView; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AlertDialog; @@ -94,7 +97,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Objects; import com.zcshou.service.ServiceGo; import com.zcshou.database.DataBaseHistoryLocation; @@ -109,7 +114,6 @@ import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; -import okhttp3.Response; import okhttp3.ResponseBody; public class MainActivity extends BaseActivity implements SensorEventListener { @@ -137,7 +141,6 @@ public class MainActivity extends BaseActivity implements SensorEventListener { private MapView mMapView; private static BaiduMap mBaiduMap = null; private static LatLng mMarkLatLngMap = new LatLng(36.547743718042415, 117.07018449827267); // 当前标记的地图点 - private static String mMarkName = null; private GeoCoder mGeoCoder; private SensorManager mSensorManager; private Sensor mSensorAccelerometer; @@ -158,6 +161,8 @@ public class MainActivity extends BaseActivity implements SensorEventListener { private FloatingActionButton mButtonStart; /*============================== 历史记录 相关 ==============================*/ private SQLiteDatabase mLocationHistoryDB; + private GeoCoder mLocationHistoryGeoCoder; + private ContentValues mLocationHistoryValues; private SQLiteDatabase mSearchHistoryDB; /*============================== SearchView 相关 ==============================*/ private SearchView searchView; @@ -220,7 +225,21 @@ public void onServiceDisconnected(ComponentName name) { initUpdateVersion(); - checkUpdateVersion(false); + try { + Cursor cursor = mLocationHistoryDB.query(DataBaseHistoryLocation.TABLE_NAME, null, + DataBaseHistoryLocation.DB_COLUMN_ID + " > ?", new String[]{"0"}, + null, null, DataBaseHistoryLocation.DB_COLUMN_TIMESTAMP + " DESC", null); + if (cursor.moveToFirst()) { + String bd09Longitude = cursor.getString(5); + String bd09Latitude = cursor.getString(6); + showLocation(bd09Longitude, bd09Latitude); + isFirstLoc = false; + } + cursor.close(); + } catch (Exception ignored) { + } + // 开始定位 + mLocClient.start(); } @Override @@ -416,14 +435,22 @@ public void onAccuracyChanged(Sensor sensor, int i) { /*============================== NavigationView 相关 ==============================*/ private void initNavigationView() { + ActivityResultLauncher historyLauncher = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { + String lon = result.getData().getStringExtra("bd09_lon"); + String lat = result.getData().getStringExtra("bd09_lat"); + showLocation(lon, lat); + } + } + ); mNavigationView = findViewById(R.id.nav_view); mNavigationView.setNavigationItemSelectedListener(item -> { int id = item.getItemId(); - if (id == R.id.nav_history) { Intent intent = new Intent(MainActivity.this, HistoryActivity.class); - - startActivity(intent); + historyLauncher.launch(intent); } else if (id == R.id.nav_settings) { Intent intent = new Intent(MainActivity.this, SettingsActivity.class); startActivity(intent); @@ -434,8 +461,16 @@ private void initNavigationView() { } catch (Exception e) { GoUtils.DisplayToast(this, getResources().getString(R.string.app_error_dev)); } + } else if (id == R.id.nav_overlays) { + try { + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } catch (Exception e) { + GoUtils.DisplayToast(this, "无法跳转到悬浮窗权限设置界面"); + } } else if (id == R.id.nav_update) { - checkUpdateVersion(true); + checkUpdateVersion(); } else if (id == R.id.nav_feedback) { File file = new File(getExternalFilesDir("Logs"), GoApplication.LOG_FILE_NAME); ShareUtils.shareFile(this, file, item.getTitle().toString()); @@ -697,7 +732,6 @@ public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) if (reverseGeoCodeResult == null || reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) { XLog.i("逆地理位置失败!"); } else { - mMarkName = String.valueOf(reverseGeoCodeResult.getAddress()); poiLatitude.setText(String.valueOf(reverseGeoCodeResult.getLocation().latitude)); poiLongitude.setText(String.valueOf(reverseGeoCodeResult.getLocation().longitude)); poiAddress.setText(reverseGeoCodeResult.getAddress()); @@ -779,8 +813,6 @@ public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagn LocationClientOption locationOption = getLocationClientOption(); //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用 mLocClient.setLocOption(locationOption); - //开始定位 - mLocClient.start(); } catch (Exception e) { XLog.e("ERROR: initMapLocation"); } @@ -875,8 +907,6 @@ private void initMapButton() { double[] bdLonLat = MapUtils.wgs2bd09(dialog_lat_double, dialog_lng_double); mMarkLatLngMap = new LatLng(bdLonLat[1], bdLonLat[0]); } - mMarkName = "手动输入的坐标"; - markMap(); MapStatusUpdate mapstatusupdate = MapStatusUpdateFactory.newLatLng(mMarkLatLngMap); @@ -914,7 +944,7 @@ private void resetMap() { mBaiduMap.setMyLocationData(locData); MapStatus.Builder builder = new MapStatus.Builder(); - builder.target(new LatLng(mCurrentLat, mCurrentLon)).zoom(18.0f); + builder.target(new LatLng(mCurrentLat, mCurrentLon)).zoom(18.0f).rotate(0); mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); } @@ -987,25 +1017,35 @@ private void resetMap() { // } // 在地图上显示位置 - public static boolean showLocation(String name, String bd09Longitude, String bd09Latitude) { - boolean ret = true; - + void showLocation(String bd09Longitude, String bd09Latitude) { try { - if (!bd09Longitude.isEmpty() && !bd09Latitude.isEmpty()) { - mMarkName = name; - mMarkLatLngMap = new LatLng(Double.parseDouble(bd09Latitude), Double.parseDouble(bd09Longitude)); - MarkerOptions ooA = new MarkerOptions().position(mMarkLatLngMap).icon(mMapIndicator); - mBaiduMap.clear(); - mBaiduMap.addOverlay(ooA); - MapStatusUpdate mapstatusupdate = MapStatusUpdateFactory.newLatLng(mMarkLatLngMap); - mBaiduMap.setMapStatus(mapstatusupdate); + double lon = Double.parseDouble(bd09Longitude); + double lat = Double.parseDouble(bd09Latitude); + // Random offset + if (sharedPreferences.getBoolean("setting_random_offset", false)) { + String max_offset_default = getResources().getString(R.string.setting_random_offset_default); + double lon_max_offset = Double.parseDouble(Objects.requireNonNull(sharedPreferences.getString("setting_lon_max_offset", max_offset_default))); + double lat_max_offset = Double.parseDouble(Objects.requireNonNull(sharedPreferences.getString("setting_lat_max_offset", max_offset_default))); + double randomLonOffset = (Math.random() * 2 - 1) * lon_max_offset; // Longitude offset (meters) + double randomLatOffset = (Math.random() * 2 - 1) * lat_max_offset; // Latitude offset (meters) + lon += randomLonOffset / 111320; // (meters -> longitude) + lat += randomLatOffset / 110574; // (meters -> latitude) + String msg = String.format(Locale.US, "经度偏移: %.2f米\n纬度偏移: %.2f米", randomLonOffset, randomLatOffset); + GoUtils.DisplayToast(this, msg); } + mMarkLatLngMap = new LatLng(lat, lon); + MarkerOptions ooA = new MarkerOptions().position(mMarkLatLngMap).icon(mMapIndicator); + mBaiduMap.clear(); + mBaiduMap.addOverlay(ooA); + MapStatusUpdate mapstatusupdate = MapStatusUpdateFactory.newLatLng(mMarkLatLngMap); + mBaiduMap.setMapStatus(mapstatusupdate); + MapStatus.Builder builder = new MapStatus.Builder(); + builder.target(mMarkLatLngMap).zoom(18).rotate(0); + mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); } catch (Exception e) { - ret = false; XLog.e("ERROR: showHistoryLocation"); + GoUtils.DisplayToast(this, getResources().getString(R.string.history_error_location)); } - - return ret; } private void initGoBtn() { @@ -1046,33 +1086,19 @@ private void doGoLocation(View v) { return; } - if (!Settings.canDrawOverlays(getApplicationContext())) {//悬浮窗权限判断 - GoUtils.showEnableFloatWindowDialog(this); - XLog.e("无悬浮窗权限!"); - return; - } - if (isMockServStart) { if (mMarkLatLngMap == null) { stopGoLocation(); - Snackbar.make(v, "模拟位置已终止", Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); + Snackbar.make(v, "模拟位置已终止", Snackbar.LENGTH_LONG).show(); mButtonStart.setImageResource(R.drawable.ic_position); } else { double[] latLng = MapUtils.bd2wgs(mMarkLatLngMap.longitude, mMarkLatLngMap.latitude); double alt = Double.parseDouble(sharedPreferences.getString("setting_altitude", "55.0")); mServiceBinder.setPosition(latLng[0], latLng[1], alt); - Snackbar.make(v, "已传送到新位置", Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); - recordCurrentLocation(mMarkLatLngMap.longitude, mMarkLatLngMap.latitude); - mBaiduMap.clear(); mMarkLatLngMap = null; - - if (GoUtils.isWifiEnabled(MainActivity.this)) { - GoUtils.showDisableWifiDialog(MainActivity.this); - } + GoUtils.showLocationNotice(this, v, true); } } else { if (!GoUtils.isAllowMockLocation(this)) { @@ -1080,21 +1106,14 @@ private void doGoLocation(View v) { XLog.e("无模拟位置权限!"); } else { if (mMarkLatLngMap == null) { - Snackbar.make(v, "请先点击地图位置或者搜索位置", Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); + Snackbar.make(v, "请先点击地图位置或者搜索位置", Snackbar.LENGTH_LONG).show(); } else { startGoLocation(); mButtonStart.setImageResource(R.drawable.ic_fly); - Snackbar.make(v, "模拟位置已启动", Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); - recordCurrentLocation(mMarkLatLngMap.longitude, mMarkLatLngMap.latitude); mBaiduMap.clear(); mMarkLatLngMap = null; - - if (GoUtils.isWifiEnabled(MainActivity.this)) { - GoUtils.showDisableWifiDialog(MainActivity.this); - } + GoUtils.showLocationNotice(this, v, false); } } } @@ -1112,6 +1131,21 @@ private void initStoreHistory() { } catch (Exception e) { XLog.e("ERROR: sqlite init error"); } + mLocationHistoryValues = new ContentValues(); + mLocationHistoryGeoCoder = GeoCoder.newInstance(); + mLocationHistoryGeoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() { + @Override + public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) { + } + + @Override + public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) { + if (reverseGeoCodeResult != null && reverseGeoCodeResult.error == SearchResult.ERRORNO.NO_ERROR) { + mLocationHistoryValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, reverseGeoCodeResult.getSematicDescription()); + DataBaseHistoryLocation.saveHistoryLocation(mLocationHistoryDB, mLocationHistoryValues); + } + } + }); } //获取查询历史 @@ -1143,80 +1177,16 @@ private List> getSearchHistory() { // 记录请求的位置信息 private void recordCurrentLocation(double lng, double lat) { - //参数坐标系:bd09 - final String safeCode = getResources().getString(R.string.safecode); - final String ak = getResources().getString(R.string.ak); + // 参数坐标系:bd09 double[] latLng = MapUtils.bd2wgs(lng, lat); - //bd09坐标的位置信息 - String mapApiUrl = "https://api.map.baidu.com/reverse_geocoding/v3/?ak=" + ak + "&output=json&coordtype=bd09ll" + "&location=" + lat + "," + lng + "&mcode=" + safeCode; - - okhttp3.Request request = new okhttp3.Request.Builder().url(mapApiUrl).get().build(); - final Call call = mOkHttpClient.newCall(request); - call.enqueue(new Callback() { - @Override - public void onFailure(@NonNull Call call, @NonNull IOException e) { - //http 请求失败 - XLog.e("HTTP: HTTP GET FAILED"); - //插表参数 - ContentValues contentValues = new ContentValues(); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, mMarkName); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_WGS84, String.valueOf(latLng[0])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_WGS84, String.valueOf(latLng[1])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_TIMESTAMP, System.currentTimeMillis() / 1000); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_CUSTOM, Double.toString(lng)); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_CUSTOM, Double.toString(lat)); - - DataBaseHistoryLocation.saveHistoryLocation(mLocationHistoryDB, contentValues); - } - - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { - ResponseBody responseBody = response.body(); - if (responseBody != null) { - String resp = responseBody.string(); - try { - JSONObject getRetJson = new JSONObject(resp); - - //位置获取成功 - if (Integer.parseInt(getRetJson.getString("status")) == 0) { - JSONObject posInfoJson = getRetJson.getJSONObject("result"); - String formatted_address = posInfoJson.getString("formatted_address"); - //插表参数 - ContentValues contentValues = new ContentValues(); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, formatted_address); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_WGS84, String.valueOf(latLng[0])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_WGS84, String.valueOf(latLng[1])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_TIMESTAMP, System.currentTimeMillis() / 1000); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_CUSTOM, Double.toString(lng)); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_CUSTOM, Double.toString(lat)); - DataBaseHistoryLocation.saveHistoryLocation(mLocationHistoryDB, contentValues); - } else { - ContentValues contentValues = new ContentValues(); - // contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, getResources().getString(R.string.history_location_default_name)); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, mMarkName); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_WGS84, String.valueOf(latLng[0])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_WGS84, String.valueOf(latLng[1])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_TIMESTAMP, System.currentTimeMillis() / 1000); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_CUSTOM, Double.toString(lng)); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_CUSTOM, Double.toString(lat)); - DataBaseHistoryLocation.saveHistoryLocation(mLocationHistoryDB, contentValues); - } - } catch (JSONException e) { - XLog.e("JSON: resolve json error"); - //插表参数 - ContentValues contentValues = new ContentValues(); - // contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, getResources().getString(R.string.history_location_default_name)); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, mMarkName); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_WGS84, String.valueOf(latLng[0])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_WGS84, String.valueOf(latLng[1])); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_TIMESTAMP, System.currentTimeMillis() / 1000); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_CUSTOM, Double.toString(lng)); - contentValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_CUSTOM, Double.toString(lat)); - DataBaseHistoryLocation.saveHistoryLocation(mLocationHistoryDB, contentValues); - } - } - } - }); + mLocationHistoryValues.put(DataBaseHistoryLocation.DB_COLUMN_LOCATION, ""); + mLocationHistoryValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_WGS84, String.valueOf(latLng[0])); + mLocationHistoryValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_WGS84, String.valueOf(latLng[1])); + mLocationHistoryValues.put(DataBaseHistoryLocation.DB_COLUMN_TIMESTAMP, System.currentTimeMillis() / 1000); + mLocationHistoryValues.put(DataBaseHistoryLocation.DB_COLUMN_LONGITUDE_CUSTOM, Double.toString(lng)); + mLocationHistoryValues.put(DataBaseHistoryLocation.DB_COLUMN_LATITUDE_CUSTOM, Double.toString(lat)); + DataBaseHistoryLocation.saveHistoryLocation(mLocationHistoryDB, mLocationHistoryValues); + mLocationHistoryGeoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(lat, lng))); } /*============================== SearchView 相关 ==============================*/ @@ -1228,7 +1198,7 @@ private void initSearchView() { mSearchList.setOnItemClickListener((parent, view, position, id) -> { String lng = ((TextView) view.findViewById(R.id.poi_longitude)).getText().toString(); String lat = ((TextView) view.findViewById(R.id.poi_latitude)).getText().toString(); - mMarkName = ((TextView) view.findViewById(R.id.poi_name)).getText().toString(); + String markName = ((TextView) view.findViewById(R.id.poi_name)).getText().toString(); mMarkLatLngMap = new LatLng(Double.parseDouble(lat), Double.parseDouble(lng)); MapStatusUpdate mapstatusupdate = MapStatusUpdateFactory.newLatLng(mMarkLatLngMap); mBaiduMap.setMapStatus(mapstatusupdate); @@ -1241,7 +1211,7 @@ private void initSearchView() { // mSearchList.setVisibility(View.GONE); //搜索历史 插表参数 ContentValues contentValues = new ContentValues(); - contentValues.put(DataBaseHistorySearch.DB_COLUMN_KEY, mMarkName); + contentValues.put(DataBaseHistorySearch.DB_COLUMN_KEY, markName); contentValues.put(DataBaseHistorySearch.DB_COLUMN_DESCRIPTION, ((TextView) view.findViewById(R.id.poi_address)).getText().toString()); contentValues.put(DataBaseHistorySearch.DB_COLUMN_IS_LOCATION, DataBaseHistorySearch.DB_SEARCH_TYPE_RESULT); contentValues.put(DataBaseHistorySearch.DB_COLUMN_LONGITUDE_CUSTOM, lng); @@ -1265,7 +1235,6 @@ private void initSearchView() { if (searchIsLoc.equals("1")) { String lng = ((TextView) view.findViewById(R.id.search_longitude)).getText().toString(); String lat = ((TextView) view.findViewById(R.id.search_latitude)).getText().toString(); - // mMarkName = ((TextView) view.findViewById(R.id.poi_name)).getText().toString(); mMarkLatLngMap = new LatLng(Double.parseDouble(lat), Double.parseDouble(lng)); MapStatusUpdate mapstatusupdate = MapStatusUpdateFactory.newLatLng(mMarkLatLngMap); mBaiduMap.setMapStatus(mapstatusupdate); @@ -1395,15 +1364,24 @@ public void onReceive(Context context, Intent intent) { registerReceiver(mDownloadBdRcv, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); } - private void checkUpdateVersion(boolean result) { + private void checkUpdateVersion() { String mapApiUrl = "https://api.github.com/repos/zcshou/gogogo/releases/latest"; okhttp3.Request request = new okhttp3.Request.Builder().url(mapApiUrl).get().build(); final Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { + private void showFail() { + View v = findViewById(android.R.id.content); + Snackbar.make(v, "获取更新信息失败", Snackbar.LENGTH_LONG).setAction("去浏览器看看", view -> { + Uri uri = Uri.parse("https://github.com/ZCShou/GoGoGo/releases"); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); + }).show(); + } @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { XLog.i("更新检测失败"); + showFail(); } @Override @@ -1458,12 +1436,11 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t }); } } else { - if (result) { - GoUtils.DisplayToast(MainActivity.this, getResources().getString(R.string.update_last)); - } + GoUtils.DisplayToast(MainActivity.this, getResources().getString(R.string.update_last)); } } catch (JSONException e) { XLog.e("ERROR: resolve json"); + showFail(); } }); } diff --git a/app/src/main/java/com/zcshou/gogogo/WelcomeActivity.java b/app/src/main/java/com/zcshou/gogogo/WelcomeActivity.java index 8d822a57..3aa64bc7 100644 --- a/app/src/main/java/com/zcshou/gogogo/WelcomeActivity.java +++ b/app/src/main/java/com/zcshou/gogogo/WelcomeActivity.java @@ -276,8 +276,7 @@ private void checkAgreementAndPrivacy() { if (mPrivacy && mAgreement) { checkBox.setChecked(true); checkDefaultPermissions(); - } else { - checkBox.setChecked(false); + startMainActivity(); } } diff --git a/app/src/main/java/com/zcshou/joystick/JoyStick.java b/app/src/main/java/com/zcshou/joystick/JoyStick.java index 859b9efc..47616bec 100644 --- a/app/src/main/java/com/zcshou/joystick/JoyStick.java +++ b/app/src/main/java/com/zcshou/joystick/JoyStick.java @@ -6,6 +6,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.PixelFormat; +import android.provider.Settings; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; @@ -159,6 +160,9 @@ public void setCurrentPosition(double lng, double lat, double alt) { } public void show() { + if (!Settings.canDrawOverlays(mContext)) { + return; + } switch (mCurWin) { case WINDOW_TYPE_MAP: if (mJoystickLayout.getParent() != null) { diff --git a/app/src/main/java/com/zcshou/service/ServiceGo.java b/app/src/main/java/com/zcshou/service/ServiceGo.java index 6218cac7..2e159ea4 100644 --- a/app/src/main/java/com/zcshou/service/ServiceGo.java +++ b/app/src/main/java/com/zcshou/service/ServiceGo.java @@ -192,6 +192,7 @@ public void handleMessage(@NonNull Message msg) { sendEmptyMessage(HANDLER_MSG_ID); } + mJoyStick.show(); } catch (InterruptedException e) { XLog.e("SERVICEGO: ERROR - handleMessage"); Thread.currentThread().interrupt(); diff --git a/app/src/main/java/com/zcshou/utils/GoUtils.java b/app/src/main/java/com/zcshou/utils/GoUtils.java index 97708694..bb4fb22e 100644 --- a/app/src/main/java/com/zcshou/utils/GoUtils.java +++ b/app/src/main/java/com/zcshou/utils/GoUtils.java @@ -18,10 +18,13 @@ import android.os.CountDownTimer; import android.provider.Settings; import android.view.Gravity; +import android.view.View; import android.widget.Toast; import androidx.appcompat.app.AlertDialog; +import com.google.android.material.snackbar.Snackbar; + import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @@ -246,6 +249,28 @@ public static void showDisableWifiDialog(Context context) { .show(); } + public static void showLocationNotice(Context context, View view, boolean started) { + String text = started ? "已传送到新位置" : "模拟位置已启动"; + if (Settings.canDrawOverlays(context)) { + Snackbar.make(view, text, Snackbar.LENGTH_LONG).show(); + } else { + text += ";为了模拟定位的稳定性,建议开启\"显示悬浮窗\"权限"; + Snackbar.make(view, text, Snackbar.LENGTH_LONG).setAction("去设置", v -> { + try { + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + context.getPackageName())); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } catch (Exception e) { + DisplayToast(context, "无法跳转到悬浮窗权限设置界面"); + } + }).show(); + } + if (isWifiEnabled(context) && !started) { + Toast.makeText(context, "开启 WIFI (即使未连接) 可能导致虚拟定位失败", Toast.LENGTH_SHORT).show(); + } + } + public static void DisplayToast(Context context, String str) { Toast toast = Toast.makeText(context, str, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 0, 100); diff --git a/app/src/main/res/drawable/ic_menu_overlays.xml b/app/src/main/res/drawable/ic_menu_overlays.xml new file mode 100644 index 00000000..5cc7d91d --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_overlays.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_nav.xml b/app/src/main/res/menu/menu_nav.xml index e2806319..c2a16001 100644 --- a/app/src/main/res/menu/menu_nav.xml +++ b/app/src/main/res/menu/menu_nav.xml @@ -17,6 +17,10 @@ android:id="@+id/nav_settings" android:icon="@drawable/ic_menu_settings" android:title="@string/nav_menu_settings" /> + 历史记录 设置 开发人员选项 + 悬浮窗权限 更多 检测更新 问题反馈 diff --git a/app/src/main/res/xml/preferences_main.xml b/app/src/main/res/xml/preferences_main.xml index 1b3388d1..2cf12e15 100644 --- a/app/src/main/res/xml/preferences_main.xml +++ b/app/src/main/res/xml/preferences_main.xml @@ -55,13 +55,13 @@ app:defaultValue="false" app:iconSpaceReserved="false"/>