mirror of
https://github.com/MetaCubeX/ClashMetaForAndroid.git
synced 2024-11-16 11:52:18 +08:00
feat: add intent filters for tasker automation (#119)
This commit is contained in:
parent
ccfcb71565
commit
021939264f
13
README.md
13
README.md
|
@ -47,6 +47,19 @@ Feature of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
|
|||
./gradlew app:assembleMeta-AlphaRelease
|
||||
```
|
||||
|
||||
### Automation
|
||||
|
||||
APP package name is `com.github.metacubex.clash.meta`
|
||||
|
||||
- Toggle Clash.Meta service status
|
||||
- Send intent to `com.github.kr328.clash.ExternalControlActivity` with action `com.github.metacubex.clash.meta.action.TOGGLE_CLASH`
|
||||
- Start Clash.Meta service
|
||||
- Send intent to `com.github.kr328.clash.ExternalControlActivity` with action `com.github.metacubex.clash.meta.action.START_CLASH`
|
||||
- Stop Clash.Meta service
|
||||
- Send intent to `com.github.kr328.clash.ExternalControlActivity` with action `com.github.metacubex.clash.meta.action.STOP_CLASH`
|
||||
- Import a profile
|
||||
- URL Scheme `clash://install-config?url=<encoded URI>` or `clashmeta://install-config?url=<encoded URI>`
|
||||
|
||||
### Kernel Contribution
|
||||
|
||||
- CMFA uses the kernel from `android-real` branch under `MetaCubeX/Clash.Meta`, which is a merge of the main `Alpha` branch and `android-open`.
|
||||
|
|
|
@ -55,9 +55,9 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ExternalImportActivity"
|
||||
android:name=".ExternalControlActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/import_from_file"
|
||||
android:label="@string/external_control_activity"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
@ -69,6 +69,18 @@
|
|||
<data android:scheme="clashmeta"/>
|
||||
<data android:host="install-config"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.github.metacubex.clash.meta.action.START_CLASH" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.github.metacubex.clash.meta.action.STOP_CLASH" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.github.metacubex.clash.meta.action.TOGGLE_CLASH" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ApkBrokenActivity"
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package com.github.kr328.clash
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.github.kr328.clash.common.constants.Intents
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.setUUID
|
||||
import com.github.kr328.clash.design.MainDesign
|
||||
import com.github.kr328.clash.design.ui.ToastDuration
|
||||
import com.github.kr328.clash.remote.Remote
|
||||
import com.github.kr328.clash.remote.StatusClient
|
||||
import com.github.kr328.clash.service.model.Profile
|
||||
import com.github.kr328.clash.util.startClashService
|
||||
import com.github.kr328.clash.util.stopClashService
|
||||
import com.github.kr328.clash.util.withProfile
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
class ExternalControlActivity : Activity(), CoroutineScope by MainScope() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
when(intent.action) {
|
||||
Intent.ACTION_VIEW -> {
|
||||
val uri = intent.data ?: return finish()
|
||||
val url = uri.getQueryParameter("url") ?: return finish()
|
||||
|
||||
launch {
|
||||
val uuid = withProfile {
|
||||
val type = when (uri.getQueryParameter("type")?.lowercase(Locale.getDefault())) {
|
||||
"url" -> Profile.Type.Url
|
||||
"file" -> Profile.Type.File
|
||||
else -> Profile.Type.Url
|
||||
}
|
||||
val name = uri.getQueryParameter("name") ?: getString(R.string.new_profile)
|
||||
|
||||
create(type, name).also {
|
||||
patch(it, name, url, 0)
|
||||
}
|
||||
}
|
||||
startActivity(PropertiesActivity::class.intent.setUUID(uuid))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
Intents.ACTION_TOGGLE_CLASH -> if(Remote.broadcasts.clashRunning) {
|
||||
stopClash()
|
||||
}
|
||||
else {
|
||||
startClash()
|
||||
}
|
||||
|
||||
Intents.ACTION_START_CLASH -> if(!Remote.broadcasts.clashRunning) {
|
||||
startClash()
|
||||
}
|
||||
else {
|
||||
Toast.makeText(this, R.string.external_control_started, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
Intents.ACTION_STOP_CLASH -> if(Remote.broadcasts.clashRunning) {
|
||||
stopClash()
|
||||
}
|
||||
else {
|
||||
Toast.makeText(this, R.string.external_control_stopped, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
return finish()
|
||||
}
|
||||
|
||||
private fun startClash() {
|
||||
// if (currentProfile == null) {
|
||||
// Toast.makeText(this, R.string.no_profile_selected, Toast.LENGTH_LONG).show()
|
||||
// return
|
||||
// }
|
||||
val vpnRequest = startClashService()
|
||||
if (vpnRequest != null) {
|
||||
Toast.makeText(this, R.string.unable_to_start_vpn, Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
Toast.makeText(this, R.string.external_control_started, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun stopClash() {
|
||||
stopClashService()
|
||||
Toast.makeText(this, R.string.external_control_stopped, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.github.kr328.clash
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.setUUID
|
||||
import com.github.kr328.clash.service.model.Profile
|
||||
import com.github.kr328.clash.util.withProfile
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
class ExternalImportActivity : Activity(), CoroutineScope by MainScope() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (intent.action != Intent.ACTION_VIEW)
|
||||
return finish()
|
||||
|
||||
val uri = intent.data ?: return finish()
|
||||
val url = uri.getQueryParameter("url") ?: return finish()
|
||||
|
||||
launch {
|
||||
val uuid = withProfile {
|
||||
val type = when (uri.getQueryParameter("type")?.lowercase(Locale.getDefault())) {
|
||||
"url" -> Profile.Type.Url
|
||||
"file" -> Profile.Type.File
|
||||
else -> Profile.Type.Url
|
||||
}
|
||||
val name = uri.getQueryParameter("name") ?: getString(R.string.new_profile)
|
||||
|
||||
create(type, name).also {
|
||||
patch(it, name, url, 0)
|
||||
}
|
||||
}
|
||||
|
||||
startActivity(PropertiesActivity::class.intent.setUUID(uuid))
|
||||
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,9 @@ import com.github.kr328.clash.common.util.packageName
|
|||
object Intents {
|
||||
// Public
|
||||
val ACTION_PROVIDE_URL = "$packageName.action.PROVIDE_URL"
|
||||
val ACTION_START_CLASH = "$packageName.action.START_CLASH"
|
||||
val ACTION_STOP_CLASH = "$packageName.action.STOP_CLASH"
|
||||
val ACTION_TOGGLE_CLASH = "$packageName.action.TOGGLE_CLASH"
|
||||
|
||||
const val EXTRA_NAME = "name"
|
||||
|
||||
|
|
|
@ -245,4 +245,7 @@
|
|||
<string name="geofile_imported">%1$s imported</string>
|
||||
<string name="toast_profile_updated_complete">Update profile %s completed</string>
|
||||
<string name="toast_profile_updated_failed">Update profile %1$s failed: %2$s</string>
|
||||
<string name="external_control_activity">External Control</string>
|
||||
<string name="external_control_started">Clash.Meta service started</string>
|
||||
<string name="external_control_stopped">Clash.Meta service stopped</string>
|
||||
</resources>
|
|
@ -245,4 +245,7 @@
|
|||
<string name="geofile_imported">%1$s imported</string>
|
||||
<string name="toast_profile_updated_complete">Update profile %s completed</string>
|
||||
<string name="toast_profile_updated_failed">Update profile %1$s failed: %2$s</string>
|
||||
<string name="external_control_activity">External Control</string>
|
||||
<string name="external_control_started">Clash.Meta service started</string>
|
||||
<string name="external_control_stopped">Clash.Meta service stopped</string>
|
||||
</resources>
|
|
@ -310,4 +310,7 @@
|
|||
<string name="geofile_imported">%1$s imported</string>
|
||||
<string name="toast_profile_updated_complete">Update profile %s completed</string>
|
||||
<string name="toast_profile_updated_failed">Update profile %1$s failed: %2$s</string>
|
||||
<string name="external_control_activity">External Control</string>
|
||||
<string name="external_control_started">Clash.Meta service started</string>
|
||||
<string name="external_control_stopped">Clash.Meta service stopped</string>
|
||||
</resources>
|
||||
|
|
|
@ -242,4 +242,7 @@
|
|||
<string name="geofile_imported">%1$s imported</string>
|
||||
<string name="toast_profile_updated_complete">Update profile %s completed</string>
|
||||
<string name="toast_profile_updated_failed">Update profile %1$s failed: %2$s</string>
|
||||
<string name="external_control_activity">External Control</string>
|
||||
<string name="external_control_started">Clash.Meta service started</string>
|
||||
<string name="external_control_stopped">Clash.Meta service stopped</string>
|
||||
</resources>
|
|
@ -242,4 +242,7 @@
|
|||
<string name="geofile_imported">%1$s imported</string>
|
||||
<string name="toast_profile_updated_complete">Update profile %s completed</string>
|
||||
<string name="toast_profile_updated_failed">Update profile %1$s failed: %2$s</string>
|
||||
<string name="external_control_activity">External Control</string>
|
||||
<string name="external_control_started">Clash.Meta service started</string>
|
||||
<string name="external_control_stopped">Clash.Meta service stopped</string>
|
||||
</resources>
|
||||
|
|
|
@ -245,4 +245,7 @@
|
|||
<string name="geofile_imported">%1$s 已导入</string>
|
||||
<string name="toast_profile_updated_complete">更新配置 %s 成功</string>
|
||||
<string name="toast_profile_updated_failed">更新配置 %1$s 失败: %2$s</string>
|
||||
<string name="external_control_activity">External Control</string>
|
||||
<string name="external_control_started">Clash.Meta 服务已启动</string>
|
||||
<string name="external_control_stopped">Clash.Meta 服务已停止</string>
|
||||
</resources>
|
|
@ -310,4 +310,7 @@
|
|||
<string name="geofile_imported">%1$s imported</string>
|
||||
<string name="toast_profile_updated_complete">Update profile %s completed</string>
|
||||
<string name="toast_profile_updated_failed">Update profile %1$s failed: %2$s</string>
|
||||
<string name="external_control_activity">External Control</string>
|
||||
<string name="external_control_started">Clash.Meta service started</string>
|
||||
<string name="external_control_stopped">Clash.Meta service stopped</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue
Block a user