diff --git a/README.md b/README.md
index df9f07e2..76616a14 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# PermanentProxy-for-WearOS
-App that will enable (on boot) a defined proxy on Wear OS watches. Could be used to enable Google Pay in "unsupported countries"
+Simple app to run a proxy (on boot) on a Wear OS device and enable geo-restricted apps like Google Pay in unsupported regions!
+
+(The apk provided is an empty PHONE companion app. Simply install Permanent Proxy on your Wear OS watch from the Play Store after installing this apk on your phone)
Sometimes big companies decide that Geoblocking is a good idea. I don't agree.
So that's why I created this Wear OS app to allow users to use their watch as if they were in another country. This means you can use certain payment apps or otherwise geospecific apps wherever you are in the world!
@@ -8,8 +10,29 @@ The app uses Android's built-in http_proxy command that turns on a proxy for the
To get started, first enable the Developer Options of your watch, which can be achieved by going to Settings -> System -> About and tap the Build number until you are a "developer".
Next, go to Settings -> Developer options and enable "ADB debugging" and "Debug over Bluetooth".
-Finally start up Permanent Proxy and press "Always allow this Computer" if prompted.
+Finally start up Permanent Proxy, request permission and press "Allow" or "Always allow this Computer" if prompted.
+After requesting permission, ADB can be turned off again to save battery, unless you want to turn off the proxy completely.
+
Now you can get started!
Simply enter a proxy address and port, enable it (and on boot if you like) and you're done!
Proxy services can be found online and can be from any country. However, do make sure you completely trust the proxy you chose before you enter it! All the data of your watch might be sent through that proxy, even sensitive data, so act at your own risk.
+
+
+Having trouble getting permission?
+
+Some older watches are not powerful enough to get Secure Settings permission by itself using my method. If this is the case for your watch, you will need a PC to grant Permanent Proxy permission. The instructions are also available in the app description.
+
+First make sure to connect your watch to your PC via ADB. You can Google how to do this, there are lots of tutorials. When your watch is connected, use the command
+
+ adb shell pm grant nl.jolanrensen.permanentproxy android.permission.WRITE_SECURE_SETTINGS
+
+to give Permanent Proxy the permissions needed to turn on/edit the proxy.
+
+To turn off the proxy, connect to your PC in the same manner as before, but now you will need the following command:
+
+ adb shell settings delete global http_proxy; adb shell settings delete global global_http_proxy_host; adb shell settings delete global global_http_proxy_port; adb shell settings delete global global_http_proxy_exclusion_list; adb shell settings delete global global_proxy_pac_url; adb shell reboot
+
+
+
+Thanks to reddit user /u/shadowban!
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index e3245e7f..819d034a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,14 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.3.50'
+ ext.kotlin_version = '1.3.61'
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.1'
+ classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/mobile/build.gradle b/mobile/build.gradle
index ab59aba5..e24ed062 100644
--- a/mobile/build.gradle
+++ b/mobile/build.gradle
@@ -11,8 +11,8 @@ android {
applicationId "nl.jolanrensen.permanentproxy"
minSdkVersion 23
targetSdkVersion 29
- versionCode 14
- versionName "3.7"
+ versionCode 15
+ versionName "3.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/wear/build.gradle b/wear/build.gradle
index 44f54387..00324e36 100644
--- a/wear/build.gradle
+++ b/wear/build.gradle
@@ -11,8 +11,8 @@ android {
applicationId "nl.jolanrensen.permanentproxy"
minSdkVersion 23
targetSdkVersion 29
- versionCode 14
- versionName "3.7"
+ versionCode 15
+ versionName "3.8"
}
buildTypes {
release {
@@ -39,11 +39,11 @@ dependencies {
implementation 'com.tananaev:adblib:1.2'
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
implementation 'androidx.percentlayout:percentlayout:1.0.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'com.android.billingclient:billing:1.1'
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
- implementation "androidx.core:core-ktx:1.2.0-beta01"
+// implementation 'com.android.billingclient:billing:1.1'
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
+ implementation "androidx.core:core-ktx:1.2.0-rc01"
implementation 'com.android.support:wear:28.0.0'
compileOnly 'com.google.android.wearable:wearable:2.5.0'
}
diff --git a/wear/release/mobile-release.apk b/wear/release/mobile-release.apk
index 65465e07..f05cb369 100644
Binary files a/wear/release/mobile-release.apk and b/wear/release/mobile-release.apk differ
diff --git a/wear/release/wear-release.apk b/wear/release/wear-release.apk
index 0db9d02f..546b7c48 100644
Binary files a/wear/release/wear-release.apk and b/wear/release/wear-release.apk differ
diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml
index 5f10f9fd..67844029 100644
--- a/wear/src/main/AndroidManifest.xml
+++ b/wear/src/main/AndroidManifest.xml
@@ -13,7 +13,7 @@
-
+
+
\ No newline at end of file
diff --git a/wear/src/main/java/nl/jolanrensen/permanentproxy/Constants.kt b/wear/src/main/java/nl/jolanrensen/permanentproxy/Constants.kt
index b565cf3d..ca60cbfc 100644
--- a/wear/src/main/java/nl/jolanrensen/permanentproxy/Constants.kt
+++ b/wear/src/main/java/nl/jolanrensen/permanentproxy/Constants.kt
@@ -2,11 +2,18 @@ package nl.jolanrensen.permanentproxy
import android.content.Context
import android.content.Intent
+import android.content.Intent.ACTION_VIEW
+import android.content.Intent.CATEGORY_BROWSABLE
import android.content.SharedPreferences
+import android.net.Uri
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.core.content.edit
+import androidx.wear.activity.ConfirmationActivity
+import androidx.wear.activity.ConfirmationActivity.EXTRA_ANIMATION_TYPE
+import androidx.wear.activity.ConfirmationActivity.OPEN_ON_PHONE_ANIMATION
+import com.google.android.wearable.intent.RemoteIntent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
@@ -122,6 +129,20 @@ object Constants {
}
}
}
+
+ fun Context.launchUrlOnPhone(url: String) {
+ RemoteIntent.startRemoteActivity(
+ this,
+ Intent(ACTION_VIEW)
+ .addCategory(CATEGORY_BROWSABLE)
+ .setData(Uri.parse(url)),
+ null
+ )
+ startActivity(
+ Intent(this, ConfirmationActivity::class.java)
+ .putExtra(EXTRA_ANIMATION_TYPE, OPEN_ON_PHONE_ANIMATION)
+ )
+ }
}
diff --git a/wear/src/main/java/nl/jolanrensen/permanentproxy/DonateActivity.kt b/wear/src/main/java/nl/jolanrensen/permanentproxy/DonateActivity.kt
index 7e0030f1..0e05a988 100644
--- a/wear/src/main/java/nl/jolanrensen/permanentproxy/DonateActivity.kt
+++ b/wear/src/main/java/nl/jolanrensen/permanentproxy/DonateActivity.kt
@@ -2,25 +2,18 @@ package nl.jolanrensen.permanentproxy
import android.os.Bundle
import android.support.wearable.activity.WearableActivity
-import android.view.View
-import androidx.core.view.isVisible
-import com.android.billingclient.api.BillingClient
-import com.android.billingclient.api.BillingClient.BillingResponse.*
-import com.android.billingclient.api.BillingClientStateListener
-import com.android.billingclient.api.BillingFlowParams
-import com.android.billingclient.api.SkuDetailsParams
import kotlinx.android.synthetic.main.activity_donate.*
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import nl.jolanrensen.permanentproxy.Constants.logD
-import nl.jolanrensen.permanentproxy.Constants.logE
-import nl.jolanrensen.permanentproxy.Constants.toast
-import nl.jolanrensen.permanentproxy.Constants.toastLong
+import nl.jolanrensen.permanentproxy.Constants.launchUrlOnPhone
class DonateActivity : WearableActivity() {
+ private fun getPaypalLink(amount: Double) = "https://paypal.me/jolanrensen/$amount"
+
+ val thankYou = 0.99
+ val bigThankYou = 1.99
+ val biggerThankYou = 4.99
+ val biggestThankYou = 9.99
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_donate)
@@ -28,116 +21,33 @@ class DonateActivity : WearableActivity() {
// Enables Always-on
setAmbientEnabled()
- var billingClient: BillingClient? = null
- billingClient = BillingClient.newBuilder(this)
- .setListener { responseCode, purchases ->
- logD("on purchases updated response: $responseCode, purchases: $purchases")
- when (responseCode) {
- FEATURE_NOT_SUPPORTED -> Unit
- SERVICE_DISCONNECTED -> Unit
- OK -> {
- if (purchases != null) {
- finish()
- toastLong(
- getString(R.string.donation_successful)
- )
- for (purchase in purchases) { // should only be 1
- billingClient!!.consumeAsync(purchase.purchaseToken) { responseCode, _ ->
- if (responseCode == OK)
- logD("purchase consumed")
- }
- }
- }
- }
- USER_CANCELED -> Unit
- SERVICE_UNAVAILABLE -> Unit
- BILLING_UNAVAILABLE -> Unit
- ITEM_UNAVAILABLE -> Unit
- DEVELOPER_ERROR -> Unit
- ERROR -> Unit
- ITEM_ALREADY_OWNED -> Unit
- ITEM_NOT_OWNED -> Unit
- }
- }
- .build()
- var tries = 0
- val billingClientStateListener = object : BillingClientStateListener {
- override fun onBillingServiceDisconnected() {
- logE("Billing service disconnected")
- if (tries == 10) {
- runOnUiThread {
- toast(getString(R.string.couldnt_connect_to_play))
- }
- }
- val listener = this
- GlobalScope.launch(Dispatchers.Default) {
- delay(100)
- billingClient.startConnection(listener)
- tries++
- }
- }
+ thank_you_price.text = getString(R.string._dollar, thankYou.toString())
+ thank_you_card.setOnClickListener {
+ launchUrlOnPhone(
+ getPaypalLink(thankYou)
+ )
+ }
- override fun onBillingSetupFinished(@BillingClient.BillingResponse responseCode: Int) {
- logD("Billing setup finished")
- // get purchases
- val skuList = arrayListOf(
- "thank_you",
- "big_thank_you",
- "bigger_thank_you",
- "biggest_thank_you"
- )
- billingClient.querySkuDetailsAsync(
- SkuDetailsParams.newBuilder()
- .setSkusList(skuList)
- .setType(BillingClient.SkuType.INAPP)
- .build()
- ) { responseCode, skuDetailsList ->
- logD("Billing sku details received, $responseCode, $skuDetailsList")
- if (responseCode == OK && skuDetailsList != null) {
- for (skuDetails in skuDetailsList) {
- val sku = skuDetails.sku
- val price = skuDetails.price
- runOnUiThread {
- when (sku) {
- "thank_you" -> thank_you_price.text = price
- "big_thank_you" -> big_thank_you_price.text = price
- "bigger_thank_you" -> bigger_thank_you_price.text = price
- "biggest_thank_you" -> biggest_thank_you_price.text = price
- }
- }
- }
- } else {
- billing_not_working.isVisible = true
- billing_not_working2.isVisible = true
- }
- }
+ big_thank_you_price.text = getString(R.string._dollar, bigThankYou.toString())
+ big_thank_you_card.setOnClickListener {
+ launchUrlOnPhone(
+ getPaypalLink(bigThankYou)
+ )
+ }
- val doPurchase = View.OnClickListener {
- logD("Billing onclick $it")
- billingClient!!.launchBillingFlow(
- this@DonateActivity,
- BillingFlowParams.newBuilder()
- .setSku(
- when (it.id) {
- thank_you_card.id -> "thank_you"
- big_thank_you_card.id -> "big_thank_you"
- bigger_thank_you_card.id -> "bigger_thank_you"
- biggest_thank_you_card.id -> "biggest_thank_you"
- else -> null
- }
- )
- .setType(BillingClient.SkuType.INAPP)
- .build()
- )
- }
+ bigger_thank_you_price.text = getString(R.string._dollar, biggerThankYou.toString())
+ bigger_thank_you_card.setOnClickListener {
+ launchUrlOnPhone(
+ getPaypalLink(biggerThankYou)
+ )
+ }
- thank_you_card.setOnClickListener(doPurchase)
- big_thank_you_card.setOnClickListener(doPurchase)
- bigger_thank_you_card.setOnClickListener(doPurchase)
- biggest_thank_you_card.setOnClickListener(doPurchase)
- }
+ biggest_thank_you_price.text = getString(R.string._dollar, biggestThankYou.toString())
+ biggest_thank_you_card.setOnClickListener {
+ launchUrlOnPhone(
+ getPaypalLink(biggestThankYou)
+ )
}
- billingClient.startConnection(billingClientStateListener)
}
}
diff --git a/wear/src/main/res/values/strings.xml b/wear/src/main/res/values/strings.xml
index f60f0821..92e0210b 100644
--- a/wear/src/main/res/values/strings.xml
+++ b/wear/src/main/res/values/strings.xml
@@ -50,6 +50,7 @@
Thank you very much for donating! It is much appreciated :)
Nothing happens?
OldWatchActivity
+ \$%1$s
Some older watches are not powerful enough to get Secure Settings permission by itself using my method. If this is the case for your watch, you will need a PC to grant Permanent Proxy permission. The instructions are also available in the mobile app or in the app description.\n\nFirst make sure to connect your watch to your PC via ADB. You can Google how to do this, there are lots of tutorials. When your watch is connected, use the command\n\nadb shell pm grant nl.jolanrensen.permanentproxy android.permission.WRITE_SECURE_SETTINGS\n\nto give Permanent Proxy the permissions needed to turn on/edit the proxy.\n\nTo turn off the proxy, connect to your PC in the same manner as before, but now you will need the following command:\n\nadb shell settings delete global http_proxy; adb shell settings delete global global_http_proxy_host; adb shell settings delete global global_http_proxy_port; adb shell settings delete global global_http_proxy_exclusion_list; adb shell settings delete global global_proxy_pac_url; adb shell reboot
Requesting permission or turning off proxy not working?