Automation app integration
This commit is contained in:
@@ -39,7 +39,8 @@ libraryDependencies ++= Seq(
|
||||
"com.android.support" % "design" % "23.1.1",
|
||||
"com.github.jorgecastilloprz" % "fabprogresscircle" % "1.01",
|
||||
"com.j256.ormlite" % "ormlite-core" % "4.48",
|
||||
"com.j256.ormlite" % "ormlite-android" % "4.48"
|
||||
"com.j256.ormlite" % "ormlite-android" % "4.48",
|
||||
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2"
|
||||
)
|
||||
|
||||
proguardOptions in Android ++= Seq("-keep class com.github.shadowsocks.** { <init>(...); }",
|
||||
|
||||
@@ -80,6 +80,14 @@
|
||||
android:parentActivityName=".Shadowsocks"
|
||||
android:launchMode="singleTask"/>
|
||||
|
||||
<activity android:name=".TaskerActivity"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="com.twofortyfouram.locale.intent.action.EDIT_SETTING" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".ShadowsocksRunnerService"
|
||||
android:exported="false">
|
||||
@@ -109,6 +117,11 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".TaskerReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<include layout="@layout/toolbar_light_dark" />
|
||||
<RelativeLayout
|
||||
android:padding="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<Switch
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/toggle_service_state"
|
||||
android:id="@+id/service_switch"
|
||||
android:layout_centerHorizontal="true" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save"
|
||||
android:textColor="@android:color/white"
|
||||
android:id="@+id/btn_save"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
@@ -97,5 +97,7 @@
|
||||
|
||||
<string name="removed">已删除</string>
|
||||
<string name="undo">撤销</string>
|
||||
<string name="toggle_service_state">切换服务状态</string>
|
||||
<string name="save">保存</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -102,4 +102,10 @@
|
||||
<string name="removed">Removed</string>
|
||||
<string name="undo">Undo</string>
|
||||
|
||||
<!-- tasker -->
|
||||
<string name="toggle_service_state">Toggle service state</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="turn_service_state">Turn service %s</string>
|
||||
<string name="state_on">On</string>
|
||||
<string name="state_off">Off</string>
|
||||
</resources>
|
||||
|
||||
@@ -47,18 +47,8 @@ class ShadowsocksReceiver extends BroadcastReceiver {
|
||||
val TAG = "Shadowsocks"
|
||||
|
||||
def onReceive(context: Context, intent: Intent) {
|
||||
val isAutoConnect: Boolean = ShadowsocksApplication.settings.getBoolean(Key.isAutoConnect, false)
|
||||
val isInstalled: Boolean = ShadowsocksApplication.settings.getBoolean(ShadowsocksApplication.getVersionName, false)
|
||||
if (isAutoConnect && isInstalled) {
|
||||
if (Utils.isLollipopOrAbove) {
|
||||
val intent = new Intent(context, classOf[ShadowsocksRunnerService])
|
||||
context.startService(intent)
|
||||
} else {
|
||||
val intent = new Intent(context, classOf[ShadowsocksRunnerActivity])
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
if (ShadowsocksApplication.settings.getBoolean(Key.isAutoConnect, false)) {
|
||||
Utils.startSsService(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Shadowsocks - A shadowsocks client for Android
|
||||
* Copyright (C) 2014 <max.c.lv@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
* ___====-_ _-====___
|
||||
* _--^^^#####// \\#####^^^--_
|
||||
* _-^##########// ( ) \\##########^-_
|
||||
* -############// |\^^/| \\############-
|
||||
* _/############// (@::@) \\############\_
|
||||
* /#############(( \\// ))#############\
|
||||
* -###############\\ (oo) //###############-
|
||||
* -#################\\ / VV \ //#################-
|
||||
* -###################\\/ \//###################-
|
||||
* _#/|##########/\######( /\ )######/\##########|\#_
|
||||
* |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \|
|
||||
* ` |/ V V ` V \#\| | | |/#/ V ' V V \| '
|
||||
* ` ` ` ` / | | | | \ ' ' ' '
|
||||
* ( | | | | )
|
||||
* __\ | | | | /__
|
||||
* (vvv(VVV)(VVV)vvv)
|
||||
*
|
||||
* HERE BE DRAGONS
|
||||
*
|
||||
*/
|
||||
package com.github.shadowsocks
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.{Button, Switch}
|
||||
import com.github.shadowsocks.helper.TaskerSettings
|
||||
import com.twofortyfouram.locale.api.{Intent => ApiIntent}
|
||||
|
||||
/**
|
||||
* @author CzBiX
|
||||
*/
|
||||
class TaskerActivity extends AppCompatActivity {
|
||||
var taskerOption: TaskerSettings = _
|
||||
|
||||
var switch: Switch = _
|
||||
var btnSave: Button = _
|
||||
|
||||
override def onCreate(savedInstanceState: Bundle) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.layout_tasker)
|
||||
|
||||
switch = findViewById(R.id.service_switch).asInstanceOf[Switch]
|
||||
btnSave = findViewById(R.id.btn_save).asInstanceOf[Button]
|
||||
|
||||
val toolbar = findViewById(R.id.toolbar).asInstanceOf[Toolbar]
|
||||
toolbar.setTitle(R.string.screen_name)
|
||||
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha)
|
||||
toolbar.setNavigationOnClickListener(_ => finish())
|
||||
|
||||
switch.setOnCheckedChangeListener((_, isChecked) => taskerOption.is_start = isChecked)
|
||||
btnSave.setOnClickListener(_ => saveResult())
|
||||
|
||||
loadSettings()
|
||||
}
|
||||
|
||||
private def loadSettings(): Unit = {
|
||||
val intent: Intent = getIntent
|
||||
if (intent.getAction != ApiIntent.ACTION_EDIT_SETTING) {
|
||||
Log.w(Shadowsocks.TAG, "unknown tasker action")
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
taskerOption = TaskerSettings.fromIntent(intent)
|
||||
|
||||
switch.setChecked(taskerOption.is_start)
|
||||
}
|
||||
|
||||
private def saveResult(): Unit = {
|
||||
setResult(Activity.RESULT_OK, taskerOption.toIntent(this))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Shadowsocks - A shadowsocks client for Android
|
||||
* Copyright (C) 2014 <max.c.lv@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
* ___====-_ _-====___
|
||||
* _--^^^#####// \\#####^^^--_
|
||||
* _-^##########// ( ) \\##########^-_
|
||||
* -############// |\^^/| \\############-
|
||||
* _/############// (@::@) \\############\_
|
||||
* /#############(( \\// ))#############\
|
||||
* -###############\\ (oo) //###############-
|
||||
* -#################\\ / VV \ //#################-
|
||||
* -###################\\/ \//###################-
|
||||
* _#/|##########/\######( /\ )######/\##########|\#_
|
||||
* |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \|
|
||||
* ` |/ V V ` V \#\| | | |/#/ V ' V V \| '
|
||||
* ` ` ` ` / | | | | \ ' ' ' '
|
||||
* ( | | | | )
|
||||
* __\ | | | | /__
|
||||
* (vvv(VVV)(VVV)vvv)
|
||||
*
|
||||
* HERE BE DRAGONS
|
||||
*
|
||||
*/
|
||||
package com.github.shadowsocks
|
||||
|
||||
import android.content.{BroadcastReceiver, Context, Intent}
|
||||
import com.github.shadowsocks.helper.TaskerSettings
|
||||
import com.github.shadowsocks.utils.Utils
|
||||
|
||||
/**
|
||||
* @author CzBiX
|
||||
*/
|
||||
class TaskerReceiver extends BroadcastReceiver {
|
||||
override def onReceive(context: Context, intent: Intent): Unit = {
|
||||
val settings: TaskerSettings = TaskerSettings.fromIntent(intent)
|
||||
|
||||
if (settings.is_start) {
|
||||
Utils.startSsService(context)
|
||||
} else {
|
||||
Utils.stopSsService(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Shadowsocks - A shadowsocks client for Android
|
||||
* Copyright (C) 2014 <max.c.lv@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
* ___====-_ _-====___
|
||||
* _--^^^#####// \\#####^^^--_
|
||||
* _-^##########// ( ) \\##########^-_
|
||||
* -############// |\^^/| \\############-
|
||||
* _/############// (@::@) \\############\_
|
||||
* /#############(( \\// ))#############\
|
||||
* -###############\\ (oo) //###############-
|
||||
* -#################\\ / VV \ //#################-
|
||||
* -###################\\/ \//###################-
|
||||
* _#/|##########/\######( /\ )######/\##########|\#_
|
||||
* |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \|
|
||||
* ` |/ V V ` V \#\| | | |/#/ V ' V V \| '
|
||||
* ` ` ` ` / | | | | \ ' ' ' '
|
||||
* ( | | | | )
|
||||
* __\ | | | | /__
|
||||
* (vvv(VVV)(VVV)vvv)
|
||||
*
|
||||
* HERE BE DRAGONS
|
||||
*
|
||||
*/
|
||||
package com.github.shadowsocks.helper
|
||||
|
||||
import android.content.{Intent, Context}
|
||||
import android.os.Bundle
|
||||
import com.github.shadowsocks.R
|
||||
|
||||
import com.twofortyfouram.locale.api.{Intent => ApiIntent}
|
||||
|
||||
object TaskerSettings {
|
||||
def fromIntent(intent: Intent): TaskerSettings = {
|
||||
val bundle: Bundle = if (intent.hasExtra(ApiIntent.EXTRA_BUNDLE))
|
||||
intent.getBundleExtra(ApiIntent.EXTRA_BUNDLE) else Bundle.EMPTY
|
||||
|
||||
new TaskerSettings(bundle)
|
||||
}
|
||||
|
||||
def fromBundle(bundle: Bundle): TaskerSettings = {
|
||||
new TaskerSettings(bundle)
|
||||
}
|
||||
}
|
||||
|
||||
class TaskerSettings(bundle: Bundle) {
|
||||
val KEY_IS_START = "is_start"
|
||||
|
||||
var is_start: Boolean = bundle.getBoolean(KEY_IS_START)
|
||||
|
||||
def toIntent(context: Context): Intent = {
|
||||
val bundle = new Bundle()
|
||||
bundle.putBoolean(KEY_IS_START, is_start)
|
||||
|
||||
val desc = context.getString(R.string.turn_service_state,
|
||||
context.getString(if (is_start) R.string.state_on else R.string.state_off))
|
||||
|
||||
val intent: Intent = new Intent()
|
||||
intent.putExtra(ApiIntent.EXTRA_STRING_BLURB, desc)
|
||||
.putExtra(ApiIntent.EXTRA_BUNDLE, bundle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ import android.util.{DisplayMetrics, Base64, Log}
|
||||
import android.view.View.MeasureSpec
|
||||
import android.view.{Gravity, View, Window}
|
||||
import android.widget.Toast
|
||||
import com.github.shadowsocks.{ShadowsocksApplication, BuildConfig}
|
||||
import com.github.shadowsocks.{ShadowsocksRunnerActivity, ShadowsocksRunnerService, ShadowsocksApplication, BuildConfig}
|
||||
import org.xbill.DNS._
|
||||
|
||||
|
||||
@@ -416,6 +416,25 @@ object Utils {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
def startSsService(context: Context): Unit = {
|
||||
val isInstalled: Boolean = ShadowsocksApplication.settings.getBoolean(ShadowsocksApplication.getVersionName, false)
|
||||
if (!isInstalled) return
|
||||
|
||||
if (Utils.isLollipopOrAbove) {
|
||||
val intent = new Intent(context, classOf[ShadowsocksRunnerService])
|
||||
context.startService(intent)
|
||||
} else {
|
||||
val intent = new Intent(context, classOf[ShadowsocksRunnerActivity])
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
def stopSsService(context: Context): Unit = {
|
||||
context.sendBroadcast(new Intent(Action.CLOSE))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user