diff --git a/.github/workflows/upload_released.yml b/.github/workflows/upload_released.yml index 943de73..654a31f 100644 --- a/.github/workflows/upload_released.yml +++ b/.github/workflows/upload_released.yml @@ -33,6 +33,6 @@ jobs: sudo apt-get install tree tree app/build/outputs - name: Upload apk file - run: gh release upload ${{steps.version.outputs.VERSION}} app/build/outputs/apk/release/app-release-unsigned.apk + run: gh release upload ${{steps.version.outputs.VERSION}} app/build/outputs/apk/release/app-release.apk env: GH_TOKEN: ${{ github.token }} diff --git a/app/build.gradle b/app/build.gradle index b815a4b..48990d4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,15 +4,22 @@ plugins { } android { + signingConfigs { + release { + storePassword System.getenv("jkspwd") + storeFile file('..\\keystore.jks') + keyAlias "onceshot" + keyPassword System.getenv("jkspwd") + } + } namespace 'org.aquarngd.onceshot' compileSdk 34 - defaultConfig { applicationId "org.aquarngd.onceshot" minSdk 24 targetSdk 34 - versionCode 1030000 - versionName "1.3.0.0" + versionCode 1040000 + versionName "1.4.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -24,6 +31,7 @@ android { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release } } compileOptions { diff --git a/app/release/app-release.apk b/app/release/app-release.apk new file mode 100644 index 0000000..678da18 Binary files /dev/null and b/app/release/app-release.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json new file mode 100644 index 0000000..918d723 --- /dev/null +++ b/app/release/output-metadata.json @@ -0,0 +1,20 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "org.aquarngd.onceshot", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 1040000, + "versionName": "1.4.0.0", + "outputFile": "app-release.apk" + } + ], + "elementType": "File" +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9828920..12bae89 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + + + + + + + + + + + + diff --git a/app/src/main/java/org/aquarngd/onceshot/ActivityAccessibilityService.kt b/app/src/main/java/org/aquarngd/onceshot/ActivityAccessibilityService.kt new file mode 100644 index 0000000..18c7898 --- /dev/null +++ b/app/src/main/java/org/aquarngd/onceshot/ActivityAccessibilityService.kt @@ -0,0 +1,14 @@ +package org.aquarngd.onceshot + +import android.accessibilityservice.AccessibilityService +import android.view.accessibility.AccessibilityEvent + +class ActivityAccessibilityService: AccessibilityService() { + override fun onAccessibilityEvent(event: AccessibilityEvent?) { + TODO("Not yet implemented") + } + + override fun onInterrupt() { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/app/src/main/java/org/aquarngd/onceshot/BootBroadcastReceiver.kt b/app/src/main/java/org/aquarngd/onceshot/BootBroadcastReceiver.kt new file mode 100644 index 0000000..604bb2c --- /dev/null +++ b/app/src/main/java/org/aquarngd/onceshot/BootBroadcastReceiver.kt @@ -0,0 +1,25 @@ +package org.aquarngd.onceshot + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log + +class BootBroadcastReceiver:BroadcastReceiver() { + companion object{ + const val classTag="BootBroadcastReceiver" + } + override fun onReceive(context: Context?, intent: Intent?) { + if(intent?.action.equals("android.intent.action.BOOT_COMPLETED")){ + Intent(context, ForegroundService::class.java).apply { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Log.d(classTag, "Call startForegroundService") + context?.startForegroundService(this) + } else { + context?.startService(this) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/aquarngd/onceshot/FloatingDialogService.kt b/app/src/main/java/org/aquarngd/onceshot/FloatingDialogService.kt index 9d72adb..f5b76f2 100644 --- a/app/src/main/java/org/aquarngd/onceshot/FloatingDialogService.kt +++ b/app/src/main/java/org/aquarngd/onceshot/FloatingDialogService.kt @@ -134,7 +134,6 @@ class FloatingDialogService : Service() { private fun onClickShareDeleteButton(contentView: View) { shareImage() - fadeOut(contentView) Handler(Looper.getMainLooper()).postDelayed({ deleteImage() @@ -218,7 +217,7 @@ class FloatingDialogService : Service() { MotionEvent.ACTION_UP -> { if (lastTouchAction == MotionEvent.ACTION_DOWN) { Log.d(classTag, "performClick because of ACTION_DOWN") - view.performClick() + //view.performClick() return@OnTouchListener false } else { @@ -227,7 +226,7 @@ class FloatingDialogService : Service() { classTag, "performClick because of distance < 400, ${(clickX * clickX - event.rawX * event.rawX) + (clickY * clickY - event.rawY * event.rawY)}" ) - view.performClick() + //view.performClick() return@OnTouchListener false } if ((event.rawX - 20) < -20) { @@ -305,6 +304,7 @@ class FloatingDialogService : Service() { private fun collectUsageData(key: UsageDataKey){ dataCollector?.collect(key) analysisService.tryUpload(applicationContext) + val d=dataCollector?.getSharedPreference()?.getInt(key.key,-1) Log.d(classTag,"collect ${key.key} ${dataCollector==null} ${dataCollector?.getSharedPreference()?.getInt(key.key,-1)}") } private fun closeFloatingDialogBuiltin() { diff --git a/app/src/main/java/org/aquarngd/onceshot/ForegroundService.kt b/app/src/main/java/org/aquarngd/onceshot/ForegroundService.kt index 9d0c9f7..d3326bb 100644 --- a/app/src/main/java/org/aquarngd/onceshot/ForegroundService.kt +++ b/app/src/main/java/org/aquarngd/onceshot/ForegroundService.kt @@ -165,7 +165,6 @@ class ForegroundService : Service() { private fun sendNotification(id: Long) { val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel(notificationId, channelId, NotificationManager.IMPORTANCE_HIGH) diff --git a/app/src/main/java/org/aquarngd/onceshot/MainActivity.kt b/app/src/main/java/org/aquarngd/onceshot/MainActivity.kt index f7f67da..554a7d2 100644 --- a/app/src/main/java/org/aquarngd/onceshot/MainActivity.kt +++ b/app/src/main/java/org/aquarngd/onceshot/MainActivity.kt @@ -68,16 +68,18 @@ import androidx.compose.ui.unit.sp import com.tencent.bugly.crashreport.CrashReport import org.aquarngd.onceshot.ui.theme.OnceShotTheme import org.aquarngd.stackbricks.StackbricksCompose +import org.aquarngd.stackbricks.msgpvder.GithubApiMsgPvder import org.aquarngd.stackbricks.msgpvder.WeiboCommentsMsgPvder import java.util.UUID class MainActivity : ComponentActivity() { var status = ForegroundServiceStatus.STATUS_INIT - val permissionList = mutableStateMapOf( + private val permissionList = mutableStateMapOf( Manifest.permission.SYSTEM_ALERT_WINDOW to false, "android.permission.READ_MEDIA_IMAGES" to false, "android.permission.MANAGE_EXTERNAL_STORAGE" to false, "android.permission.MANAGE_MEDIA" to false, + "android.permission.POST_NOTIFICATIONS" to false, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS to false ) private var permissionCheckCounter = false @@ -91,6 +93,7 @@ class MainActivity : ComponentActivity() { const val REQUEST_PERMISSION_IMAGE = 1002 const val SPKEY_DURATION = "duration" const val SPKEY_DEVICEID = "device_id" + const val SPKEY_BOOT_PERMISSION="boot_permission" const val SPNAME = "onceshot" const val classTag = "MainActivity" } @@ -263,8 +266,6 @@ class MainActivity : ComponentActivity() { color = colorResource(id = R.color.red_zhuhong) ) } - - checkPermissionPassed = true } } @@ -272,16 +273,35 @@ class MainActivity : ComponentActivity() { packageName ) ) { + permissionList[Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS] = true + if(permissionList[Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS] == true){ + CreateCardButton( + onClick = { + startActivity(Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { + data = Uri.parse("package:$packageName") + }) + }, + icon = painterResource(id = R.drawable.icon_battery), + title = stringResource(R.string.mainwindow_requirepermission_battery_title), + text = stringResource(R.string.mainwindow_requirepermission_battery_text), + color = colorResource(id = R.color.red_zhuhong) + ) + } + } + if(!getSharedPreferences(SPNAME,Context.MODE_PRIVATE).getBoolean(SPKEY_BOOT_PERMISSION,false)){ CreateCardButton( onClick = { - startActivity(Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { - data = Uri.parse("package:$packageName") + startActivity(Intent(Intent.ACTION_VIEW).apply { + setClassName("com.android.settings","com.android.settings.InstalledAppDetails") + putExtra("com.android.settings.ApplicationPkgName", packageName) }) + getSharedPreferences(SPNAME,Context.MODE_PRIVATE).edit().putBoolean( + SPKEY_BOOT_PERMISSION,true).apply() }, - icon = painterResource(id = R.drawable.icon_battery), - title = stringResource(R.string.mainwindow_requirepermission_battery_title), - text = stringResource(R.string.mainwindow_requirepermission_battery_text), - color = colorResource(id = R.color.red_zhuhong) + icon = painterResource(id = R.drawable.icon_boot), + title = "推荐为应用添加自启动权限", + text = "自启动权限可以保证 OnceShot 的持续后台运行", + color = colorResource(id = R.color.yellow_youcaihuahuang) ) } return checkPermissionPassed @@ -361,7 +381,7 @@ class MainActivity : ComponentActivity() { checkPermissionPassed = drawPermissionCheckContent() StackbricksCompose( rememberCoroutineScope(), - LocalContext.current, WeiboCommentsMsgPvder.MsgPvderID, "5001248562483153" + LocalContext.current, GithubApiMsgPvder.MsgPvderID, "aquamarine5/OnceShot" ).DrawCompose() drawDurationSettingCard() drawUsageDataShower() @@ -473,7 +493,18 @@ class MainActivity : ComponentActivity() { Text(it.value.toString(), fontWeight = FontWeight.Bold, fontSize = 14.sp) } } - Text("OnceShot 收集您的使用数据并每日传输至服务器,请放心,这不会泄露您的个人隐私", modifier = Modifier.padding(0.dp,5.dp), fontSize = 12.sp, lineHeight = 15.sp) + Button(onClick = { + for ((index,element) in AnalysisService.UPLOAD_USAGE_VALUES.withIndex()){ + usageDataList[index] = AnalysisDataClass( + element, + AnalysisService.USAGE_VALUES_STRING[element] ?: "", + sp.getInt(element.key, 0) + ) + } + }){ + Text("刷新") + } + //Text("OnceShot 收集您的使用数据并每日传输至服务器,请放心,这不会泄露您的个人隐私", modifier = Modifier.padding(0.dp,5.dp), fontSize = 12.sp, lineHeight = 15.sp) } } @@ -520,7 +551,7 @@ class MainActivity : ComponentActivity() { colors = CardDefaults.cardColors(colorResource(id = R.color.blue_jiqing)) ) { Text( - "v1.2 Reanimated", + "v1.4 Improvement", style = TextStyle(color = Color.Yellow), modifier = Modifier.padding(5.dp, 2.dp), fontWeight = FontWeight.Bold @@ -528,7 +559,7 @@ class MainActivity : ComponentActivity() { } //Text(" Build version: 3") } - Text("Build version: 第 269 次测试") + Text("Build version: 第 417 次测试") } } } @@ -637,7 +668,6 @@ class MainActivity : ComponentActivity() { } } } - @Composable fun CreateCardButton( icon: Painter, diff --git a/app/src/main/res/drawable/icon_boot.xml b/app/src/main/res/drawable/icon_boot.xml new file mode 100644 index 0000000..dfc7834 --- /dev/null +++ b/app/src/main/res/drawable/icon_boot.xml @@ -0,0 +1,5 @@ + + + diff --git a/keystore.jks b/keystore.jks new file mode 100644 index 0000000..98a587e Binary files /dev/null and b/keystore.jks differ