From 964358d2640a9d453983262b6ddbd4c4df54792d Mon Sep 17 00:00:00 2001 From: EricTeo Date: Sun, 22 Dec 2024 16:45:42 +0800 Subject: [PATCH] a few optimizations feat: floating window permission is optinal feat: jump to the last position when starting feat: welcome activity is only displayed at the first time feat: add commit hash to version fix: the HTTP request cannot retrieve the address information --- app/build.gradle | 8 +- .../java/com/zcshou/gogogo/MainActivity.java | 189 +++++++----------- .../com/zcshou/gogogo/WelcomeActivity.java | 3 +- .../java/com/zcshou/joystick/JoyStick.java | 4 + .../java/com/zcshou/service/ServiceGo.java | 1 + .../main/java/com/zcshou/utils/GoUtils.java | 25 +++ .../main/res/drawable/ic_menu_overlays.xml | 9 + app/src/main/res/menu/menu_nav.xml | 4 + app/src/main/res/values/strings.xml | 1 + 9 files changed, 125 insertions(+), 119 deletions(-) create mode 100644 app/src/main/res/drawable/ic_menu_overlays.xml diff --git a/app/build.gradle b/app/build.gradle index 714f7f1..71df64b 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/MainActivity.java b/app/src/main/java/com/zcshou/gogogo/MainActivity.java index 7c8d6c0..cc73a04 100644 --- a/app/src/main/java/com/zcshou/gogogo/MainActivity.java +++ b/app/src/main/java/com/zcshou/gogogo/MainActivity.java @@ -109,7 +109,6 @@ import io.noties.markwon.Markwon; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; -import okhttp3.Response; import okhttp3.ResponseBody; public class MainActivity extends BaseActivity implements SensorEventListener { @@ -137,7 +136,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 +156,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 +220,22 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 name = cursor.getString(1); + String bd09Longitude = cursor.getString(5); + String bd09Latitude = cursor.getString(6); + MainActivity.showLocation(name, bd09Longitude, bd09Latitude); + isFirstLoc = false; + } + cursor.close(); + } catch (Exception ignored) { + } + // 开始定位 + mLocClient.start(); } @Override @@ -434,8 +449,16 @@ public class MainActivity extends BaseActivity implements SensorEventListener { } 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 +720,6 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 +801,6 @@ public class MainActivity extends BaseActivity implements SensorEventListener { LocationClientOption locationOption = getLocationClientOption(); //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用 mLocClient.setLocOption(locationOption); - //开始定位 - mLocClient.start(); } catch (Exception e) { XLog.e("ERROR: initMapLocation"); } @@ -875,8 +895,6 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 +932,7 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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())); } @@ -992,13 +1010,15 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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); + MapStatus.Builder builder = new MapStatus.Builder(); + builder.target(mMarkLatLngMap).zoom(18).rotate(0); + mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); } } catch (Exception e) { ret = false; @@ -1046,33 +1066,19 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 +1086,14 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 +1111,21 @@ public class MainActivity extends BaseActivity implements SensorEventListener { } 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 +1157,16 @@ public class MainActivity extends BaseActivity implements SensorEventListener { // 记录请求的位置信息 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 +1178,7 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 +1191,7 @@ public class MainActivity extends BaseActivity implements SensorEventListener { // 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 +1215,6 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 +1344,24 @@ public class MainActivity extends BaseActivity implements SensorEventListener { 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 +1416,11 @@ public class MainActivity extends BaseActivity implements SensorEventListener { }); } } 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 8d822a5..3aa64bc 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 @@ public class WelcomeActivity extends AppCompatActivity { 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 859b9ef..47616be 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.content.SharedPreferences; 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 class JoyStick extends View { } 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 6218cac..2e159ea 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 class ServiceGo extends Service { 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 9770869..bb4fb22 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.Build; 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 class GoUtils { .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 0000000..5cc7d91 --- /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 e280631..c2a1600 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" /> + 历史记录 设置 开发人员选项 + 悬浮窗权限 更多 检测更新 问题反馈