diff --git a/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt b/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt index d551435..18d66eb 100644 --- a/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt @@ -51,7 +51,13 @@ class CreateProfileActivity : BaseActivity() { } startActivityForResult( - ProfileEditActivity::class.intent.putExtra("id", id), + ProfileEditActivity::class.intent.setData( + Uri.fromParts( + "id", + id.toString(), + null + ) + ), REQUEST_CODE ) } diff --git a/app/src/main/java/com/github/kr328/clash/MainApplication.kt b/app/src/main/java/com/github/kr328/clash/MainApplication.kt index b459ae9..3adaff1 100644 --- a/app/src/main/java/com/github/kr328/clash/MainApplication.kt +++ b/app/src/main/java/com/github/kr328/clash/MainApplication.kt @@ -2,7 +2,10 @@ package com.github.kr328.clash import android.app.Application import android.content.Context +import android.content.Intent +import android.net.Uri import com.github.kr328.clash.common.Global +import com.github.kr328.clash.common.util.componentName import com.github.kr328.clash.dump.LogcatDumper import com.github.kr328.clash.remote.Broadcasts import com.github.kr328.clash.remote.Remote @@ -48,6 +51,20 @@ class MainApplication : Application() { }) } + Global.openMainIntent = { + Intent(Intent.ACTION_MAIN).apply { + component = MainActivity::class.componentName + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + } + } + Global.openProfileIntent = { + Intent(Intent.ACTION_MAIN).apply { + component = ProfileEditActivity::class.componentName + data = Uri.fromParts("id", it.toString(), null) + flags = Intent.FLAG_ACTIVITY_NEW_TASK + } + } + Remote.init(this) Broadcasts.init(this) } diff --git a/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt b/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt index 250e588..1fdf50a 100644 --- a/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking class ProfileEditActivity : BaseActivity() { + private var editor: ProfileEditFragment? = null private var processing = false set(value) { field = value @@ -34,7 +35,7 @@ class ProfileEditActivity : BaseActivity() { toolbar.setTitle(R.string.loading) launch { - val id = intent.getLongExtra("id", -1) + val id = intent.data?.schemeSpecificPart?.toLongOrNull() ?: return@launch finish() val metadata = withProfile { queryById(id) @@ -50,10 +51,13 @@ class ProfileEditActivity : BaseActivity() { } val fragment = ProfileEditFragment( + metadata.id, metadata.name, metadata.uri, metadata.interval, metadata.type, metadata.source ) + editor = fragment + supportFragmentManager.beginTransaction() .replace(R.id.fragment, fragment) .commit() @@ -87,6 +91,9 @@ class ProfileEditActivity : BaseActivity() { return } + if ( editor?.isModified != true) + return finish() + AlertDialog.Builder(this) .setTitle(R.string.exit_without_save) .setMessage(R.string.exit_without_save_warning) @@ -98,7 +105,9 @@ class ProfileEditActivity : BaseActivity() { override fun onDestroy() { runBlocking { withProfile { - release(intent.getLongExtra("id", -1)) + val id = editor?.id ?: return@withProfile + + release(id) } } diff --git a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt index 98fdab1..d0bd2d3 100644 --- a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt @@ -112,13 +112,10 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C } private fun openProperties(id: Long) { - if (id < 0) { - Snackbar.make(rootView, getText(R.string.profile_not_found), Snackbar.LENGTH_LONG) - .show() - return - } - - startActivity(ProfileEditActivity::class.intent.putExtra("id", id)) + startActivity( + ProfileEditActivity::class.intent + .setData(Uri.fromParts("id", id.toString(), null)) + ) } private fun openEditor(profile: Profile) = launch { diff --git a/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt b/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt index 54b808f..b8409ec 100644 --- a/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt +++ b/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt @@ -20,12 +20,15 @@ import com.github.kr328.clash.service.model.Profile.Type import com.google.android.material.snackbar.Snackbar class ProfileEditFragment( + val id: Long, var name: String, var uri: Uri, var interval: Long, private val type: Type, private val source: Uri? ) : Fragment() { + var isModified = false + companion object { private const val REQUEST_CODE = 10000 @@ -60,6 +63,7 @@ class ProfileEditFragment( ) { onTextChanged { name = content.toString() + isModified = true } } textInput( @@ -84,6 +88,7 @@ class ProfileEditFragment( } uri = Uri.parse(content.toString()) + isModified = true } } textInput( @@ -118,6 +123,7 @@ class ProfileEditFragment( } interval = content.toString().toLong() * 1000 * 60 + isModified = true } if ( type == Type.FILE ) diff --git a/common/src/main/java/com/github/kr328/clash/common/Global.kt b/common/src/main/java/com/github/kr328/clash/common/Global.kt index eda1c2f..3de7c5b 100644 --- a/common/src/main/java/com/github/kr328/clash/common/Global.kt +++ b/common/src/main/java/com/github/kr328/clash/common/Global.kt @@ -1,8 +1,12 @@ package com.github.kr328.clash.common import android.app.Application +import android.content.Intent object Global { + var openMainIntent: () -> Intent = { Intent() } + var openProfileIntent: (Long) -> Intent = { Intent() } + lateinit var application: Application private set diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt index 2ed3dd2..00faf7b 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt @@ -2,6 +2,7 @@ package com.github.kr328.clash.service import android.app.NotificationChannel import android.app.NotificationManager +import android.app.PendingIntent import android.content.ComponentName import android.content.Context import android.content.Intent @@ -12,9 +13,11 @@ import android.os.IBinder import android.os.RemoteException import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat +import com.github.kr328.clash.common.Global import com.github.kr328.clash.common.ids.Intents import com.github.kr328.clash.common.ids.NotificationChannels import com.github.kr328.clash.common.ids.NotificationIds +import com.github.kr328.clash.common.ids.PendingIds import com.github.kr328.clash.common.util.intent import com.github.kr328.clash.service.data.ProfileDao import com.github.kr328.clash.service.transact.IStreamCallback @@ -157,6 +160,7 @@ class ProfileBackgroundService : BaseService() { .setContentText(content) .setColor(getColor(R.color.colorAccentService)) .setSmallIcon(R.drawable.ic_notification) + .setOngoing(true) .setOnlyAlertOnce(true) .setGroup(NotificationChannels.PROFILE_STATUS) .build() @@ -167,6 +171,13 @@ class ProfileBackgroundService : BaseService() { private suspend fun sendUpdateCompleted(id: Long) { val entity = ProfileDao.queryById(id) ?: return + val intent = PendingIntent.getActivity( + this, + PendingIds.generateProfileResultId(id), + Global.openProfileIntent(id), + PendingIntent.FLAG_UPDATE_CURRENT + ) + val notification = NotificationCompat.Builder(this, NotificationChannels.PROFILE_RESULT) .setContentTitle(getText(R.string.process_result)) .setContentText(getString(R.string.format_update_complete, entity.name)) @@ -174,6 +185,8 @@ class ProfileBackgroundService : BaseService() { .setSmallIcon(R.drawable.ic_notification) .setOnlyAlertOnce(true) .setGroup(NotificationChannels.PROFILE_RESULT) + .setAutoCancel(true) + .setContentIntent(intent) .build() NotificationManagerCompat.from(this) @@ -183,6 +196,13 @@ class ProfileBackgroundService : BaseService() { private suspend fun sendUpdateFailed(id: Long, reason: String) { val entity = ProfileDao.queryById(id) ?: return + val intent = PendingIntent.getActivity( + this, + PendingIds.generateProfileResultId(id), + Global.openProfileIntent(id), + PendingIntent.FLAG_UPDATE_CURRENT + ) + val notification = NotificationCompat.Builder(this, NotificationChannels.PROFILE_RESULT) .setContentTitle(getString(R.string.format_update_failure, entity.name)) .setColor(getColor(R.color.colorAccentService)) @@ -190,6 +210,8 @@ class ProfileBackgroundService : BaseService() { .setStyle(NotificationCompat.BigTextStyle().bigText(reason)) .setOnlyAlertOnce(true) .setGroup(NotificationChannels.PROFILE_RESULT) + .setAutoCancel(true) + .setContentIntent(intent) .build() NotificationManagerCompat.from(this) diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/module/DynamicNotificationModule.kt b/service/src/main/java/com/github/kr328/clash/service/clash/module/DynamicNotificationModule.kt index 67ce1db..17e9c9c 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/module/DynamicNotificationModule.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/module/DynamicNotificationModule.kt @@ -5,6 +5,7 @@ import android.app.Service import android.content.Intent import android.os.PowerManager import androidx.core.app.NotificationCompat +import com.github.kr328.clash.common.Global import com.github.kr328.clash.common.ids.Intents import com.github.kr328.clash.common.ids.NotificationChannels import com.github.kr328.clash.common.ids.NotificationIds @@ -23,11 +24,6 @@ class DynamicNotificationModule(private val service: Service) : Module() { Intent.ACTION_SCREEN_OFF, Intents.INTENT_ACTION_PROFILE_LOADED ) - private val contentIntent = Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_DEFAULT) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setPackage(service.packageName) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) private val builder = NotificationCompat.Builder(service, NotificationChannels.CLASH_STATUS) .setSmallIcon(R.drawable.ic_notification) .setOngoing(true) @@ -39,7 +35,7 @@ class DynamicNotificationModule(private val service: Service) : Module() { PendingIntent.getActivity( service, NotificationIds.CLASH_STATUS, - contentIntent, + Global.openMainIntent(), PendingIntent.FLAG_UPDATE_CURRENT ) ) diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt b/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt index 864df25..66086e1 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt @@ -8,6 +8,7 @@ import android.content.Intent import android.os.Build import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat +import com.github.kr328.clash.common.Global import com.github.kr328.clash.common.ids.Intents import com.github.kr328.clash.common.ids.NotificationChannels import com.github.kr328.clash.common.ids.NotificationIds @@ -17,11 +18,6 @@ import com.github.kr328.clash.service.ServiceStatusProvider class StaticNotificationModule(private val service: Service) : Module() { override val receiveBroadcasts: Set get() = setOf(Intents.INTENT_ACTION_PROFILE_LOADED) - private val contentIntent = Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_DEFAULT) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setPackage(service.packageName) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) private val builder = NotificationCompat.Builder(service, NotificationChannels.CLASH_STATUS) .setSmallIcon(R.drawable.ic_notification) .setOngoing(true) @@ -33,7 +29,7 @@ class StaticNotificationModule(private val service: Service) : Module() { PendingIntent.getActivity( service, NotificationIds.CLASH_STATUS, - contentIntent, + Global.openMainIntent(), PendingIntent.FLAG_UPDATE_CURRENT ) ) diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/module/TunModule.kt b/service/src/main/java/com/github/kr328/clash/service/clash/module/TunModule.kt index 23eb405..17efce7 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/module/TunModule.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/module/TunModule.kt @@ -4,6 +4,7 @@ import android.app.PendingIntent import android.content.Intent import android.net.VpnService import android.os.Build +import com.github.kr328.clash.common.Global import com.github.kr328.clash.common.ids.PendingIds import com.github.kr328.clash.core.Clash import com.github.kr328.clash.service.util.parseCIDR @@ -23,12 +24,6 @@ class TunModule(private val service: VpnService) : Module() { val disallowApplication: List } - private val contentIntent = Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_DEFAULT) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setPackage(service.packageName) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) - var configure: Configure? = null override suspend fun onStart() { @@ -58,7 +53,7 @@ class TunModule(private val service: VpnService) : Module() { PendingIntent.getActivity( service, PendingIds.CLASH_VPN, - contentIntent, + Global.openMainIntent(), PendingIntent.FLAG_UPDATE_CURRENT ) )