From 1cc45d6b447fb7a9d8012cc188144175c3f9b616 Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 25 Aug 2018 13:32:52 +0000 Subject: [PATCH] Added IAB --- FAQ.md | 3 +- app/build.gradle | 5 + app/proguard-rules.pro | 3 + app/src/main/AndroidManifest.xml | 1 + .../java/eu/faircode/email/ActivityView.java | 96 ++++++++++++++++++- .../main/java/eu/faircode/email/Helper.java | 52 ++++++++++ app/src/main/res/values/strings.xml | 1 + 7 files changed, 158 insertions(+), 3 deletions(-) diff --git a/FAQ.md b/FAQ.md index bc2ddee89d..be7896205b 100644 --- a/FAQ.md +++ b/FAQ.md @@ -11,7 +11,8 @@ Frequently Asked Questions * View network connections (ACCESS_NETWORK_STATE): to monitor internet connectivity changes * Run at startup (RECEIVE_BOOT_COMPLETED): to start monitoring on device start * Optional: read your contacts (READ_CONTACTS): to autocomplete addresses -* ... (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question. +* ... (BILLING): to offer in-app purchases +* ... (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question **(2) Why is there a permanent notification shown?** diff --git a/app/build.gradle b/app/build.gradle index 79deb3ba76..2551904e65 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,6 +55,8 @@ dependencies { // https://mvnrepository.com/artifact/androidx.room/room-runtime // https://mvnrepository.com/artifact/androidx.paging/paging-runtime + // https://developer.android.com/google/play/billing/billing_library_releases_notes + // https://javaee.github.io/javamail/ // https://jsoup.org/ // http://www.freeutils.net/source/jcharset/ @@ -70,6 +72,7 @@ dependencies { def lifecycle_version = "2.0.0-rc01" def room_version = "2.0.0-rc01" def paging_version = "2.0.0-rc01" + def billingclient_version = "1.1" def javamail_version = "1.6.0" def jsoup_version = "1.11.3" def jcharset_version = "2.0" @@ -88,6 +91,8 @@ dependencies { implementation "androidx.paging:paging-runtime:$paging_version" + implementation "com.android.billingclient:billing:$billingclient_version" + implementation "com.sun.mail:android-mail:$javamail_version" implementation "com.sun.mail:android-activation:$javamail_version" diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 251617c02d..0752a1ecf3 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -27,6 +27,9 @@ #AndroidX -keep class androidx.appcompat.app.AppCompatViewInflater { (...); } +#IAB +-keep class com.android.vending.billing.** + #JavaMail -dontshrink -keep class javax.** {*;} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fdac5dbf1e..028edcc5ce 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ + purchases) { + String text = Helper.getBillingResponseText(responseCode); + Log.i(Helper.TAG, "IAB purchases updated response=" + text); + if (responseCode == BillingClient.BillingResponse.OK) + checkPurchases(purchases); + else + Snackbar.make(view, text, Snackbar.LENGTH_LONG).show(); + } + + private void queryPurchases() { + Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP); + String text = Helper.getBillingResponseText(result.getResponseCode()); + Log.i(Helper.TAG, "IAB query purchases response=" + text); + if (result.getResponseCode() == BillingClient.BillingResponse.OK) + checkPurchases(result.getPurchasesList()); + else + Snackbar.make(view, text, Snackbar.LENGTH_LONG).show(); + } + + private void checkPurchases(List purchases) { + if (purchases != null) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences.Editor editor = prefs.edit(); + editor.remove("pro"); + for (Purchase purchase : purchases) { + Log.i(Helper.TAG, "IAB SKU=" + purchase.getSku()); + if ((BuildConfig.APPLICATION_ID + ".pro").equals(purchase.getSku())) { + editor.putBoolean("pro", true); + Log.i(Helper.TAG, "IAB pro features activated"); + } + } + editor.apply(); + } + } } diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index eb12f8d16d..0e106335f7 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -31,6 +31,7 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.Spinner; +import com.android.billingclient.api.BillingClient; import com.google.android.material.bottomnavigation.BottomNavigationView; import java.io.BufferedReader; @@ -188,4 +189,55 @@ public class Helper { sb.append(String.format("%02x", b)); return sb.toString(); } + + static String getBillingResponseText(@BillingClient.BillingResponse int responseCode) { + switch (responseCode) { + case BillingClient.BillingResponse.BILLING_UNAVAILABLE: + // Billing API version is not supported for the type requested + return "BILLING_UNAVAILABLE"; + + case BillingClient.BillingResponse.DEVELOPER_ERROR: + // Invalid arguments provided to the API. + return "DEVELOPER_ERROR"; + + case BillingClient.BillingResponse.ERROR: + // Fatal error during the API action + return "ERROR"; + + case BillingClient.BillingResponse.FEATURE_NOT_SUPPORTED: + // Requested feature is not supported by Play Store on the current device. + return "FEATURE_NOT_SUPPORTED"; + + case BillingClient.BillingResponse.ITEM_ALREADY_OWNED: + // Failure to purchase since item is already owned + return "ITEM_ALREADY_OWNED"; + + case BillingClient.BillingResponse.ITEM_NOT_OWNED: + // Failure to consume since item is not owned + return "ITEM_NOT_OWNED"; + + case BillingClient.BillingResponse.ITEM_UNAVAILABLE: + // Requested product is not available for purchase + return "ITEM_UNAVAILABLE"; + + case BillingClient.BillingResponse.OK: + // Success + return "OK"; + + case BillingClient.BillingResponse.SERVICE_DISCONNECTED: + // Play Store service is not connected now - potentially transient state. + return "SERVICE_DISCONNECTED"; + + case BillingClient.BillingResponse.SERVICE_UNAVAILABLE: + // Network connection is down + return "SERVICE_UNAVAILABLE"; + + case BillingClient.BillingResponse.USER_CANCELED: + // User pressed back or canceled a dialog + return "USER_CANCELED"; + + default: + return Integer.toString(responseCode); + } + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4ea3d588e0..780adf4b89 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -176,6 +176,7 @@ Connected Closing + All pro features are activated All pro features activated Invalid response