diff --git a/mobile/build.gradle b/mobile/build.gradle
index 47c9cf92..c3853295 100644
--- a/mobile/build.gradle
+++ b/mobile/build.gradle
@@ -11,8 +11,8 @@ android {
applicationId "nl.jolanrensen.permanentproxy"
minSdkVersion 23
targetSdkVersion 29
- versionCode 9
- versionName "3.3"
+ versionCode 10
+ versionName "3.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/wear/build.gradle b/wear/build.gradle
index f7af1af9..f71a557d 100644
--- a/wear/build.gradle
+++ b/wear/build.gradle
@@ -11,8 +11,8 @@ android {
applicationId "nl.jolanrensen.permanentproxy"
minSdkVersion 23
targetSdkVersion 29
- versionCode 9
- versionName "3.3"
+ versionCode 12
+ versionName "3.5"
}
buildTypes {
release {
@@ -39,7 +39,9 @@ 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.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.support:wear:28.0.0'
diff --git a/wear/release/mobile-release.apk b/wear/release/mobile-release.apk
index 4f183b7a..0efb9688 100644
Binary files a/wear/release/mobile-release.apk and b/wear/release/mobile-release.apk differ
diff --git a/wear/release/wear-release.aab b/wear/release/wear-release.aab
index d6871a03..c22ec7d4 100644
Binary files a/wear/release/wear-release.aab and b/wear/release/wear-release.aab differ
diff --git a/wear/release/wear-release.apk b/wear/release/wear-release.apk
index d9a8df3d..d8e7db47 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 63407cc9..8ec9602b 100644
--- a/wear/src/main/AndroidManifest.xml
+++ b/wear/src/main/AndroidManifest.xml
@@ -13,7 +13,7 @@
-
+
+
+
@@ -48,7 +52,6 @@
-
\ No newline at end of file
diff --git a/wear/src/main/java/nl/jolanrensen/permanentproxy/DonateActivity.kt b/wear/src/main/java/nl/jolanrensen/permanentproxy/DonateActivity.kt
new file mode 100644
index 00000000..7e0030f1
--- /dev/null
+++ b/wear/src/main/java/nl/jolanrensen/permanentproxy/DonateActivity.kt
@@ -0,0 +1,143 @@
+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
+
+class DonateActivity : WearableActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_donate)
+
+ // 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++
+ }
+ }
+
+ 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
+ }
+ }
+
+ 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()
+ )
+ }
+
+ thank_you_card.setOnClickListener(doPurchase)
+ big_thank_you_card.setOnClickListener(doPurchase)
+ bigger_thank_you_card.setOnClickListener(doPurchase)
+ biggest_thank_you_card.setOnClickListener(doPurchase)
+ }
+ }
+ billingClient.startConnection(billingClientStateListener)
+ }
+}
diff --git a/wear/src/main/java/nl/jolanrensen/permanentproxy/MainActivity.kt b/wear/src/main/java/nl/jolanrensen/permanentproxy/MainActivity.kt
index 58b68c34..0f251515 100644
--- a/wear/src/main/java/nl/jolanrensen/permanentproxy/MainActivity.kt
+++ b/wear/src/main/java/nl/jolanrensen/permanentproxy/MainActivity.kt
@@ -89,7 +89,12 @@ class MainActivity : WearableActivity() {
PERMISSION
)
+ }
+ donate.setOnClickListener {
+ startActivity(
+ Intent(this, DonateActivity::class.java)
+ )
}
}
diff --git a/wear/src/main/java/nl/jolanrensen/permanentproxy/RequestPermissionActivity.kt b/wear/src/main/java/nl/jolanrensen/permanentproxy/RequestPermissionActivity.kt
index 1b673828..98434fb6 100644
--- a/wear/src/main/java/nl/jolanrensen/permanentproxy/RequestPermissionActivity.kt
+++ b/wear/src/main/java/nl/jolanrensen/permanentproxy/RequestPermissionActivity.kt
@@ -13,11 +13,15 @@ class RequestPermissionActivity : WearableActivity() {
@Volatile
var currentADBProcess: SendSingleCommand? = null
+ @Volatile
+ var stop = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_request_permission)
+ setAmbientEnabled()
+
cancel.setOnClickListener {
finish()
}
@@ -31,7 +35,7 @@ class RequestPermissionActivity : WearableActivity() {
ip = "localhost",
port = Constants.PORT,
command = "pm grant \\\nnl.jolanrensen.permanentproxy \\\nandroid.permission.WRITE_SECURE_SETTINGS",
- timeout = 2000,
+ timeout = 2500,
ctrlC = false
) {
currentADBProcess = null
@@ -57,10 +61,21 @@ class RequestPermissionActivity : WearableActivity() {
}
}
}
+
+ // useless loading bar to show google the app is doing something
+ thread(start = true) {
+ var s = 0
+ while (s <= 25 && !stop) {
+ loading_bar.progress = ((s / 25f) * 100f).toInt()
+ s++
+ Thread.sleep(1000)
+ }
+ }
}
override fun onStop() {
currentADBProcess?.cancel()
+ stop = true
logE("requesting permission canceled")
super.onStop()
}
diff --git a/wear/src/main/res/layout/activity_donate.xml b/wear/src/main/res/layout/activity_donate.xml
new file mode 100644
index 00000000..125fff2a
--- /dev/null
+++ b/wear/src/main/res/layout/activity_donate.xml
@@ -0,0 +1,281 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wear/src/main/res/layout/activity_main.xml b/wear/src/main/res/layout/activity_main.xml
index dd3ce6cc..a970f252 100644
--- a/wear/src/main/res/layout/activity_main.xml
+++ b/wear/src/main/res/layout/activity_main.xml
@@ -123,7 +123,6 @@
android:id="@+id/set_proxy_port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="45dp"
android:background="?android:attr/selectableItemBackground"
android:enabled="false"
android:gravity="center_vertical"
@@ -131,6 +130,17 @@
android:text="@string/set_proxy_port"
android:textAppearance="@android:style/TextAppearance.Material.Body1" />
+
+
+
diff --git a/wear/src/main/res/layout/activity_request_permission.xml b/wear/src/main/res/layout/activity_request_permission.xml
index cdb064ba..598e2dba 100644
--- a/wear/src/main/res/layout/activity_request_permission.xml
+++ b/wear/src/main/res/layout/activity_request_permission.xml
@@ -21,21 +21,24 @@
android:orientation="vertical">
+ android:indeterminate="false"
+ android:max="100"
+ android:progress="0" />
How to enable ADB over Bluetooth?
EnableADBBluetoothActivity
System -> About and tap the Build number until you are a \"developer\".\nNext, go to Settings -> Developer options and enable \"ADB debugging\" and \"Debug over Bluetooth\".\nFinally start up Permanent Proxy, request permission and press \"Allow\" or \"Always allow this Computer\" if prompted.\nAfter the app has gotten permission, ADB can be turned off again unless you want to disable the proxy.\n\nNow you can get started! Simply enter a proxy address and port, enable it and you\'re done! If you reboot, the proxy will remain.\n\nProxy services can be found online and can be from any country. However, do make sure your proxy works and 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.]]>
- Requesting permission, this can take up to 20s… \"Allow\" or \"Always allow computer\" if prompted.\n\nNote: the app works best with WiFi turned OFF.
+ Requesting permission, this can take up to 25s… \"Allow\" or \"Always allow computer\" if prompted.\n\nNote: the app works best with WiFi turned OFF.
Write secure settings permission needed. This can be enabled via ADB over Bluetooth.
ADB over Bluetooth is enabled, request permission!
Permission granted,\nADB can be turned off.
@@ -32,4 +32,20 @@
Other apps and external IP might take time to update.
Cancel
Error: did you enter a valid port?
+ Donate
+ DonateActivity
+ It seems I\'m unable to connect to Google Play at the moment. Retry later or, if you don\'t have Google Play, you can always use PayPal to donate:
+ https://www.paypal.me/jolanrensen
+ Thank you!
+ Big thank you!
+ Bigger thank you!
+ Couldn\'t connect to Google Play
+ Biggest thank you!
+ A small token of gratitude, enough for me to buy a coffee at uni
+ A bigger token of gratitude, enough for me to buy two cups of coffee
+ Even greater token of gratitude, enough for me to buy a large special coffee
+ Greatest token of gratitude! If you\'ve got money to spend and don\'t know how
+ Donating won\'t give you extra features, however, it will considerably support me, the developer, to continue
+ making awesome apps like this one!
+ Thank you very much for donating! It is much appreciated :)