pref: 优化一键签到
This commit is contained in:
parent
39a6470f4d
commit
b2b85bfcda
|
|
@ -27,6 +27,7 @@
|
|||
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
|
||||
<uses-permission android:name="com.miui.personalassistant.permission.FAVORITE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
|
|
@ -57,6 +58,13 @@
|
|||
android:theme="@style/AppTheme"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:ignore="UnusedAttribute">
|
||||
<service
|
||||
android:name=".services.OKSignService"
|
||||
android:exported="true"
|
||||
android:enabled="true"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:process=":oksign" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.AppFontSizeActivity"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
|
|
@ -77,6 +85,7 @@
|
|||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"
|
||||
android:theme="@style/AppTheme.PhotoView"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<receiver
|
||||
android:name=".receivers.BootCompleteSignReceiver"
|
||||
android:enabled="true"
|
||||
|
|
@ -150,11 +159,11 @@
|
|||
</activity>
|
||||
|
||||
<activity-alias
|
||||
android:name=".MainActivityIconOld"
|
||||
android:name=".MainActivityIconInvert"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:icon="@mipmap/ic_launcher_new_invert"
|
||||
android:roundIcon="@mipmap/ic_launcher_new_invert_round"
|
||||
android:targetActivity=".MainActivityV2">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
@ -167,11 +176,11 @@
|
|||
android:resource="@xml/shortcut" />
|
||||
</activity-alias>
|
||||
<activity-alias
|
||||
android:name=".MainActivityIconInvert"
|
||||
android:name=".MainActivityIconOld"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/ic_launcher_new_invert"
|
||||
android:roundIcon="@mipmap/ic_launcher_new_invert_round"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:targetActivity=".MainActivityV2">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,235 @@
|
|||
package com.huanchengfly.tieba.post.services
|
||||
|
||||
import android.Manifest
|
||||
import android.app.IntentService
|
||||
import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationChannelCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.app.ServiceCompat
|
||||
import com.huanchengfly.tieba.post.R
|
||||
import com.huanchengfly.tieba.post.activities.LoginActivity
|
||||
import com.huanchengfly.tieba.post.activities.MainActivity
|
||||
import com.huanchengfly.tieba.post.api.models.SignResultBean
|
||||
import com.huanchengfly.tieba.post.models.SignDataBean
|
||||
import com.huanchengfly.tieba.post.pendingIntentFlagImmutable
|
||||
import com.huanchengfly.tieba.post.ui.common.theme.utils.ThemeUtils
|
||||
import com.huanchengfly.tieba.post.utils.AccountUtil
|
||||
import com.huanchengfly.tieba.post.utils.ProgressListener
|
||||
import com.huanchengfly.tieba.post.utils.SingleAccountSigner
|
||||
import com.huanchengfly.tieba.post.utils.addFlag
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class OKSignService : IntentService(TAG), CoroutineScope, ProgressListener {
|
||||
private var job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = Dispatchers.Main + job
|
||||
|
||||
private val notificationManager: NotificationManagerCompat by lazy {
|
||||
NotificationManagerCompat.from(this)
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Log.i(TAG, "onStartCommand")
|
||||
if (intent?.action == ACTION_START_SIGN) {
|
||||
startForeground(
|
||||
1,
|
||||
buildNotification(
|
||||
getString(R.string.title_loading_data),
|
||||
getString(R.string.text_please_wait)
|
||||
).build()
|
||||
)
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
override fun onHandleIntent(intent: Intent?) {
|
||||
Log.i(TAG, "onHandleWork")
|
||||
if (intent?.action == ACTION_START_SIGN) {
|
||||
val loginInfo = AccountUtil.getLoginInfo()
|
||||
if (loginInfo != null) {
|
||||
runBlocking {
|
||||
SingleAccountSigner(
|
||||
this@OKSignService,
|
||||
AccountUtil.getLoginInfo()!!
|
||||
)
|
||||
.apply {
|
||||
setProgressListener(this@OKSignService)
|
||||
}
|
||||
.start()
|
||||
}
|
||||
} else {
|
||||
updateNotification(
|
||||
getString(R.string.title_oksign_fail),
|
||||
getString(R.string.text_login_first),
|
||||
Intent(this, LoginActivity::class.java)
|
||||
)
|
||||
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_DETACH)
|
||||
}
|
||||
} else {
|
||||
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
notificationManager.createNotificationChannel(
|
||||
NotificationChannelCompat.Builder(
|
||||
NOTIFICATION_CHANNEL_ID,
|
||||
NotificationManagerCompat.IMPORTANCE_LOW
|
||||
)
|
||||
.setName(getString(R.string.title_oksign))
|
||||
.setLightsEnabled(false)
|
||||
.setShowBadge(false)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildNotification(title: String, text: String?): NotificationCompat.Builder {
|
||||
createNotificationChannel()
|
||||
return NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
|
||||
.setContentText(text)
|
||||
.setContentTitle(title)
|
||||
.setSubText(getString(R.string.title_oksign))
|
||||
.setSmallIcon(R.drawable.ic_oksign)
|
||||
.setAutoCancel(true)
|
||||
.setStyle(NotificationCompat.BigTextStyle())
|
||||
.setColor(ThemeUtils.getColorByAttr(this, R.attr.colorPrimary))
|
||||
}
|
||||
|
||||
private fun updateNotification(title: String, text: String, intent: Intent) {
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
return
|
||||
}
|
||||
notificationManager.notify(
|
||||
1,
|
||||
buildNotification(title, text)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
intent,
|
||||
pendingIntentFlagImmutable()
|
||||
)
|
||||
)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateNotification(title: String, text: String?) {
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
return
|
||||
}
|
||||
val notification = buildNotification(title, text)
|
||||
.build()
|
||||
notification.flags = notification.flags.addFlag(NotificationCompat.FLAG_ONGOING_EVENT)
|
||||
notificationManager.notify(1, notification)
|
||||
}
|
||||
|
||||
private fun clearNotification() {
|
||||
notificationManager.cancel(1)
|
||||
}
|
||||
|
||||
|
||||
override fun onStart(total: Int) {
|
||||
updateNotification(getString(R.string.title_start_sign), null)
|
||||
if (total > 0) Toast.makeText(
|
||||
this,
|
||||
R.string.toast_oksign_start,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
coroutineContext.cancel()
|
||||
}
|
||||
|
||||
override fun onProgressStart(signDataBean: SignDataBean, current: Int, total: Int) {
|
||||
updateNotification(
|
||||
getString(
|
||||
R.string.title_signing_progress,
|
||||
signDataBean.userName,
|
||||
current,
|
||||
total
|
||||
),
|
||||
getString(
|
||||
R.string.title_forum_name,
|
||||
signDataBean.forumName
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onProgressFinish(
|
||||
signDataBean: SignDataBean,
|
||||
signResultBean: SignResultBean,
|
||||
current: Int,
|
||||
total: Int
|
||||
) {
|
||||
updateNotification(
|
||||
getString(
|
||||
R.string.title_signing_progress,
|
||||
signDataBean.userName,
|
||||
current + 1,
|
||||
total
|
||||
),
|
||||
if (signResultBean.userInfo?.signBonusPoint != null)
|
||||
getString(
|
||||
R.string.text_singing_progress_exp,
|
||||
signDataBean.forumName,
|
||||
signResultBean.userInfo.signBonusPoint
|
||||
)
|
||||
else
|
||||
getString(R.string.text_singing_progress, signDataBean.forumName)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onFinish(success: Boolean, signedCount: Int, total: Int) {
|
||||
updateNotification(
|
||||
getString(R.string.title_oksign_finish),
|
||||
if (total > 0) getString(
|
||||
R.string.text_oksign_done,
|
||||
signedCount
|
||||
) else getString(R.string.text_oksign_no_signable),
|
||||
Intent(this, MainActivity::class.java)
|
||||
)
|
||||
sendBroadcast(Intent(ACTION_SIGN_SUCCESS_ALL))
|
||||
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_DETACH)
|
||||
}
|
||||
|
||||
override fun onFailure(current: Int, total: Int, errorCode: Int, errorMsg: String) {
|
||||
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_DETACH)
|
||||
updateNotification(getString(R.string.title_oksign_fail), errorMsg)
|
||||
}
|
||||
|
||||
companion object {
|
||||
// fun enqueueWork(context: Context, work: Intent) {
|
||||
// enqueueWork(context, OKSignService::class.java, JOB_ID, work)
|
||||
// }
|
||||
//
|
||||
// private const val JOB_ID = 233
|
||||
|
||||
const val TAG = "OKSignService"
|
||||
const val NOTIFICATION_CHANNEL_ID = "1"
|
||||
const val ACTION_SIGN_SUCCESS_ALL =
|
||||
"com.huanchengfly.tieba.post.service.action.SIGN_SUCCESS_ALL"
|
||||
const val ACTION_START_SIGN = "com.huanchengfly.tieba.post.service.action.ACTION_SIGN_START"
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,19 @@ package com.huanchengfly.tieba.post.utils
|
|||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.*
|
||||
import com.huanchengfly.tieba.post.*
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.floatPreferencesKey
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import androidx.datastore.preferences.core.longPreferencesKey
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import com.huanchengfly.tieba.post.dataStore
|
||||
import com.huanchengfly.tieba.post.getBoolean
|
||||
import com.huanchengfly.tieba.post.getFloat
|
||||
import com.huanchengfly.tieba.post.getInt
|
||||
import com.huanchengfly.tieba.post.getLong
|
||||
import com.huanchengfly.tieba.post.getString
|
||||
import com.huanchengfly.tieba.post.utils.ThemeUtil.TRANSLUCENT_THEME_LIGHT
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -21,6 +32,11 @@ open class AppPreferencesUtils(context: Context) {
|
|||
|
||||
var userLikeLastRequestUnix by DataStoreDelegates.long(defaultValue = 0L)
|
||||
|
||||
var appIcon by DataStoreDelegates.string(
|
||||
defaultValue = Icons.DEFAULT_ICON,
|
||||
key = AppIconUtil.PREF_KEY_APP_ICON
|
||||
)
|
||||
|
||||
var autoSign by DataStoreDelegates.boolean(defaultValue = false, key = "auto_sign")
|
||||
|
||||
var autoSignTime by DataStoreDelegates.string(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.huanchengfly.tieba.post.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.huanchengfly.tieba.post.api.TiebaApi
|
||||
import com.huanchengfly.tieba.post.api.models.MSignBean
|
||||
import com.huanchengfly.tieba.post.api.models.SignResultBean
|
||||
|
|
@ -118,6 +119,7 @@ class SingleAccountSigner(
|
|||
signData.clear()
|
||||
var userName: String by Delegates.notNull()
|
||||
var tbs: String by Delegates.notNull()
|
||||
Log.i(TAG, "start")
|
||||
AccountUtil.fetchAccountFlow(account)
|
||||
.flatMapConcat { account ->
|
||||
userName = account.name
|
||||
|
|
|
|||
|
|
@ -2,33 +2,35 @@ package com.huanchengfly.tieba.post.utils
|
|||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.*
|
||||
import android.content.ClipData
|
||||
import android.content.ClipDescription
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.PersistableBundle
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.OutOfQuotaPolicy
|
||||
import androidx.work.WorkManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.huanchengfly.tieba.post.R
|
||||
import com.huanchengfly.tieba.post.activities.WebViewActivity
|
||||
import com.huanchengfly.tieba.post.api.TiebaApi
|
||||
import com.huanchengfly.tieba.post.api.models.CheckReportBean
|
||||
import com.huanchengfly.tieba.post.components.dialogs.LoadingDialog
|
||||
import com.huanchengfly.tieba.post.components.workers.OKSignWork
|
||||
import com.huanchengfly.tieba.post.pendingIntentFlagImmutable
|
||||
import com.huanchengfly.tieba.post.receivers.AutoSignAlarm
|
||||
import com.huanchengfly.tieba.post.services.OKSignService
|
||||
import com.huanchengfly.tieba.post.toastShort
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import java.util.*
|
||||
import java.util.Calendar
|
||||
|
||||
object TiebaUtil {
|
||||
private fun ClipData.setIsSensitive(isSensitive: Boolean): ClipData {
|
||||
private fun ClipData.setIsSensitive(isSensitive: Boolean): ClipData = apply {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
description.extras = PersistableBundle().apply {
|
||||
putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, isSensitive)
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
|
@ -80,9 +82,8 @@ object TiebaUtil {
|
|||
@JvmStatic
|
||||
fun startSign(context: Context) {
|
||||
context.appPreferences.signDay = Calendar.getInstance()[Calendar.DAY_OF_MONTH]
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// try {
|
||||
// context.startForegroundService(
|
||||
// OKSignService.enqueueWork(
|
||||
// context,
|
||||
// Intent()
|
||||
// .setClassName(
|
||||
// context.packageName,
|
||||
|
|
@ -91,25 +92,21 @@ object TiebaUtil {
|
|||
// .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
// .setAction(OKSignService.ACTION_START_SIGN)
|
||||
// )
|
||||
// } catch (e: IllegalStateException) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// } else {
|
||||
// context.startService(
|
||||
// Intent()
|
||||
// .setClassName(
|
||||
// context.packageName,
|
||||
// "${context.packageName}.services.OKSignService"
|
||||
// )
|
||||
// .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
// .setAction(OKSignService.ACTION_START_SIGN)
|
||||
// )
|
||||
// }
|
||||
val okSignWork = OneTimeWorkRequestBuilder<OKSignWork>()
|
||||
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||
.build()
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork("OKSign", ExistingWorkPolicy.KEEP, okSignWork)
|
||||
ContextCompat.startForegroundService(
|
||||
context,
|
||||
Intent()
|
||||
.setClassName(
|
||||
context.packageName,
|
||||
"${context.packageName}.services.OKSignService"
|
||||
)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.setAction(OKSignService.ACTION_START_SIGN)
|
||||
)
|
||||
// val okSignWork = OneTimeWorkRequestBuilder<OKSignWork>()
|
||||
// .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||
// .build()
|
||||
// WorkManager.getInstance(context)
|
||||
// .enqueueUniqueWork("OKSign", ExistingWorkPolicy.KEEP, okSignWork)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
|||
Loading…
Reference in New Issue