From b06b6a0c896a240b610bb4a50e959da524345c58 Mon Sep 17 00:00:00 2001 From: dantifer Date: Tue, 22 Sep 2026 22:08:37 +0800 Subject: [PATCH 1/3] bring the app up to current Google Play requirements Play flagged the published build (234) for an outdated androidx.activity and the target API deadline (API 36 from 31 Aug 2026) is in force. This brings the project to the current baseline: Build - AGP 8.9.3, Gradle 8.11.1, compileSdk/targetSdk 36 - AndroidX to current stable: appcompat 1.7.0, activity 1.9.3, fragment 1.8.5, material 1.12.0, constraintlayout 2.2.0, navigation 2.8.5, preference 1.2.1, lifecycle-viewmodel/livedata 2.8.7 (replacing the discontinued lifecycle-extensions), gson 2.11.0, test libs - Jetifier off: every dependency is AndroidX or plain Java Manifest / policy - drop READ/WRITE_EXTERNAL_STORAGE, SYSTEM_ALERT_WINDOW, REQUEST_IGNORE_BATTERY_OPTIMIZATIONS and QUERY_ALL_PACKAGES: none is used. Overlays are accessibility-service windows, the battery page is opened via ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS, and package visibility for launcher apps, home apps and input methods now comes from instead of the restricted QUERY_ALL_PACKAGES - accessibility service declares isAccessibilityTool="false" - prominent disclosure dialog before sending the user to the accessibility settings (what is read, that nothing leaves the device) - remove the ignored android:persistent UI - edge-to-edge (enforced from targetSdk 35): the window ActionBar drew over the content and the content under the status bar. The activity now uses a NoActionBar theme with its own Toolbar, fitsSystemWindows on the root, and light system bars matching the white toolbar and bottom navigation - ViewModelProviders -> ViewModelProvider, PackageInfo.versionCode -> PackageInfoCompat.getLongVersionCode, unused imports removed Verified on a real device (Android 16): layout, disclosure dialog, service binding and ad skipping; 64 unit tests pass. --- app/build.gradle | 28 +++++----- app/src/main/AndroidManifest.xml | 23 +++++--- .../com/zfdang/touchhelper/MainActivity.java | 4 ++ .../touchhelper/ui/about/AboutFragment.java | 7 ++- .../touchhelper/ui/home/HomeFragment.java | 54 +++++++++---------- app/src/main/res/layout/activity_main.xml | 27 ++++++++-- app/src/main/res/values/dimens.xml | 2 - app/src/main/res/values/strings.xml | 4 ++ app/src/main/res/values/styles.xml | 9 +++- .../res/xml/accessibility_service_config.xml | 1 + build.gradle | 2 +- gradle.properties | 6 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- 13 files changed, 107 insertions(+), 62 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5adf81e..3bc67c9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ def appVersion = getDate() android { namespace "com.zfdang.touchhelper" - compileSdkVersion 35 + compileSdkVersion 36 buildFeatures { buildConfig true @@ -23,7 +23,7 @@ android { defaultConfig { applicationId "com.zfdang.touchhelper" minSdkVersion 26 - targetSdkVersion 35 + targetSdkVersion 36 versionCode gitVersion versionName appVersion @@ -81,21 +81,25 @@ android { dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.2.1' - implementation 'androidx.constraintlayout:constraintlayout:2.0.2' - implementation 'androidx.navigation:navigation-fragment:2.1.0' - implementation 'androidx.navigation:navigation-ui:2.1.0' - implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'androidx.activity:activity:1.9.3' + implementation 'androidx.fragment:fragment:1.8.5' + implementation 'com.google.android.material:material:1.12.0' + implementation 'androidx.constraintlayout:constraintlayout:2.2.0' + implementation 'androidx.navigation:navigation-fragment:2.8.5' + implementation 'androidx.navigation:navigation-ui:2.8.5' + // lifecycle-extensions is discontinued; ViewModel / LiveData ship as separate artifacts + implementation 'androidx.lifecycle:lifecycle-viewmodel:2.8.7' + implementation 'androidx.lifecycle:lifecycle-livedata:2.8.7' testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.14.1' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' - implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.google.code.gson:gson:2.11.0' // https://developer.android.com/jetpack/androidx/releases/preference?hl=zh-cn - implementation 'androidx.preference:preference:1.1.1' + implementation 'androidx.preference:preference:1.2.1' // https://mvnrepository.com/artifact/com.belerweb/pinyin4j implementation group: 'com.belerweb', name: 'pinyin4j', version: '2.5.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e28d34d..7fd28d4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,15 +1,25 @@ - - - - - - + + + + + + + + + @@ -20,7 +30,6 @@ android:label="@string/app_name" android:roundIcon="@drawable/ic_touch_helper_icon" android:supportsRtl="true" - android:persistent="true" android:theme="@style/AppTheme"> showAccessibilityDisclosure()); final ImageButton btPowerPermission = root.findViewById(R.id.button_power_permission); btPowerPermission.setOnClickListener(new View.OnClickListener() { @@ -118,14 +101,31 @@ public void onResume() { super.onResume(); } - public void checkServiceStatus(){ + /** + * Google Play requires a prominent in-app disclosure before an app sends the user to enable + * an accessibility service that is not an assistive tool: what the service reads, what it + * does with it, and that nothing leaves the device. + */ + private void showAccessibilityDisclosure() { + if (TouchHelperService.isServiceRunning()) { + openAccessibilitySettings(); + return; + } + new AlertDialog.Builder(requireContext()) + .setTitle(R.string.accessibility_disclosure_title) + .setMessage(R.string.accessibility_disclosure_message) + .setPositiveButton(R.string.accessibility_disclosure_agree, (dialog, which) -> openAccessibilitySettings()) + .setNegativeButton(R.string.accessibility_disclosure_cancel, null) + .show(); + } - // detect the app storage permission - boolean bAppPermission = - ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; - MutableLiveData liveData = homeViewModel.getAppPermission(); - liveData.setValue(bAppPermission); + private void openAccessibilitySettings() { + Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } + public void checkServiceStatus(){ // detect the accessibility permission MutableLiveData accessibility = homeViewModel.getAccessibilityPermission(); accessibility.setValue(TouchHelperService.isServiceRunning()); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2a6a189..ca89df4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,28 @@ android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingTop="@dimen/navigation_view_padding_top"> + android:fitsSystemWindows="true"> + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index a641426..02d4637 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -3,6 +3,4 @@ 16dp 16dp - 0dp - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3fa0dcc..3d52419 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,4 +29,8 @@ Copyright © 2022 Zhengfa Dang 版本: %s (%d) + 开启无障碍服务前请了解 + \"开屏跳过\"通过安卓无障碍服务读取当前屏幕上的界面内容(控件文字、描述和位置),用于识别并自动点击开屏广告的\"跳过\"按钮。\n\n这些内容只在本机内存中即时比对,不会被保存、收集或上传;本程序不申请网络权限。\n\n点击\"同意并前往设置\"后,请在系统无障碍设置中找到\"开屏跳过\"并开启。 + 同意并前往设置 + 取消 \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index fac9291..9abd15b 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,10 +1,17 @@ - + +