#1343 Premium Account

This commit is contained in:
sictiru 2020-08-30 16:57:15 -07:00
parent 9121a8303a
commit c65a276c63
8 changed files with 353 additions and 237 deletions

View file

@ -1,253 +1,288 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:padding="16dp">
android:animateLayoutChanges="true">
<TextView
<LinearLayout
android:id="@+id/container_going_premium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/premium_title"
android:textSize="18sp"
android:textStyle="bold" />
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center_horizontal"
android:lineSpacingExtra="@dimen/extra_line_spacing"
android:text="@string/premium_subtitle"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_policies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center_horizontal"
android:lineSpacingExtra="@dimen/extra_line_spacing"
android:text="@string/premium_policies"
android:textSize="12sp" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_hand_pointing_right" />
<LinearLayout
android:id="@+id/container_sub"
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:orientation="vertical"
android:visibility="gone">
android:gravity="center_horizontal"
android:text="@string/premium_title_going_premium"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center_horizontal"
android:lineSpacingExtra="@dimen/extra_line_spacing"
android:text="@string/premium_subtitle"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_policies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center_horizontal"
android:lineSpacingExtra="@dimen/extra_line_spacing"
android:text="@string/premium_policies"
android:textSize="12sp" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_hand_pointing_right" />
<LinearLayout
android:id="@+id/container_sub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:id="@+id/text_sub_title"
style="?linkText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/premium_subscription_title"
android:textSize="14sp" />
<TextView
android:id="@+id/text_sub_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="4dp"
android:text="@string/premium_subscription_price"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<TextView
android:id="@+id/text_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/loading"
android:textSize="18sp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_sync" />
<TextView
android:id="@+id/text_sub_title"
style="?linkText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/premium_subscription_title"
android:textSize="14sp" />
android:layout_marginStart="40dp"
android:text="@string/premium_sync" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_folder" />
<TextView
android:id="@+id/text_sub_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="4dp"
android:text="@string/premium_subscription_price"
android:textSize="20sp"
android:textStyle="bold" />
android:layout_marginStart="40dp"
android:text="@string/premium_read_by_folder" />
</LinearLayout>
</FrameLayout>
<TextView
android:id="@+id/text_loading"
android:layout_width="wrap_content"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/loading"
android:textSize="18sp" />
android:layout_marginTop="16dp">
</FrameLayout>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_search" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_search" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_bookmark" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_searchable_tags" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_lock" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_privacy_options" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_rss_feed" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_custom_rss" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_text" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_text_view" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_dining" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_shiloh" />
</FrameLayout>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_sync" />
android:id="@+id/img_shiloh"
android:layout_width="104dp"
android:layout_height="104dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:scaleType="centerCrop" />
</LinearLayout>
<FrameLayout
android:id="@+id/container_gone_premium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_sync" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_folder" />
android:layout_marginTop="120dp"
android:gravity="center_horizontal"
android:text="@string/premium_title_gone_premium"
android:textSize="40sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_subscription_renewal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_read_by_folder" />
android:layout_marginTop="320dp"
android:gravity="center_horizontal"
android:lineSpacingExtra="@dimen/extra_line_spacing"
android:textSize="18sp"
android:visibility="gone" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_search" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_search" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_bookmark" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_searchable_tags" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_lock" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_privacy_options" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_rss_feed" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_custom_rss" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_text" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_text_view" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_dining" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="40dp"
android:text="@string/premium_shiloh" />
</FrameLayout>
<ImageView
android:id="@+id/img_shiloh"
android:layout_width="104dp"
android:layout_height="104dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:scaleType="centerCrop" />
</LinearLayout>
</FrameLayout>
</ScrollView>

View file

@ -43,6 +43,10 @@
android:title="@string/menu_loginas"
android:showAsAction="never"
android:visible="false"/>
<item android:id="@+id/menu_premium_account"
android:title="@string/menu_premium_account"
android:showAsAction="never" />
<item android:id="@+id/menu_logout"
android:title="@string/menu_logout"

View file

@ -213,6 +213,7 @@
<string name="menu_feedback_post">Create a feedback post</string>
<string name="menu_feedback_email">Email a bug report</string>
<string name="menu_theme_choose">Theme…</string>
<string name="menu_premium_account">Premium Account</string>
<string name="description_add_new_folder_icon">Add new folder icon</string>
@ -264,7 +265,10 @@
<string name="premium_subscribers_search">Search is only available to</string>
<string name="premium_subscribers">premium subscribers</string>
<string name="premium_toolbar_title">NewsBlur Premium</string>
<string name="premium_title">Thank you so much for going premium!</string>
<string name="premium_title_going_premium">Thank you so much for going premium!</string>
<string name="premium_title_gone_premium">Thank you for going premium!</string>
<string name="premium_subscription_renewal">Your premium subscription is set to\nrenew on %s</string>
<string name="premium_subscription_expiration">Your premium subscription is set\nto expire on %s</string>
<string name="premium_subtitle">Upgrading to a NewsBlur premium subscription gives you all of these features. Payments will be charged to your Play Store account at confirmation of purchase. Subscription renew unless auto-renew is turned off at least 24 hours before the end of the current period. Cancel at any time from Account Settings in Play Store.</string>
<string name="premium_policies"><![CDATA[See NewsBlur\'s <a href="https://newsblur.com/privacy">privacy policy</a> and <a href="https://newsblur.com/tos">terms of use</a> for details.]]></string>
<string name="premium_subscription_title">NewsBlur Premium Subscription</string>

View file

@ -373,6 +373,10 @@ public class Main extends NbActivity implements StateChangedListener, SwipeRefre
} else if (item.getItemId() == R.id.menu_theme_black) {
PrefsUtils.setSelectedTheme(this, ThemeValue.BLACK);
UIUtils.restartActivity(this);
} else if (item.getItemId() == R.id.menu_premium_account) {
Intent intent = new Intent(this, Premium.class);
startActivity(intent);
return true;
}
return false;
}

View file

@ -2,9 +2,10 @@ package com.newsblur.activity;
import android.graphics.Paint;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.text.util.Linkify;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
@ -17,33 +18,40 @@ import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchaseHistoryRecord;
import com.android.billingclient.api.PurchaseHistoryResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.newsblur.R;
import com.newsblur.databinding.ActivityPremiumBinding;
import com.newsblur.network.APIManager;
import com.newsblur.network.domain.NewsBlurResponse;
import com.newsblur.service.NBSyncService;
import com.newsblur.util.AppConstants;
import com.newsblur.util.BetterLinkMovementMethod;
import com.newsblur.util.FeedUtils;
import com.newsblur.util.Log;
import com.newsblur.util.PrefsUtils;
import com.newsblur.util.UIUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
public class Premium extends NbActivity {
private ActivityPremiumBinding binding;
private BillingClient billingClient;
private final String subscriptionSku = "nb.premium.36";
private SkuDetails subscriptionDetails;
private Purchase purchasedSubscription;
private AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = billingResult -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Log.d(Premium.this.getLocalClassName(), "acknowledgePurchaseResponseListener OK");
enablePremiumAccess();
verifyUserSubscriptionStatus();
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.BILLING_UNAVAILABLE) {
// Billing API version is not supported for the type requested.
Log.d(Premium.this.getLocalClassName(), "acknowledgePurchaseResponseListener BILLING_UNAVAILABLE");
@ -83,20 +91,8 @@ public class Premium extends NbActivity {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
Log.d(Premium.this.getLocalClassName(), "onBillingSetupFinished OK");
retrieveSubs();
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
for (Purchase purchase : result.getPurchasesList()) {
Purchase purchase1 = purchase;
}
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS, new PurchaseHistoryResponseListener() {
@Override
public void onPurchaseHistoryResponse(@NonNull BillingResult billingResult, @Nullable List<PurchaseHistoryRecord> list) {
Log.d("fdsfsdfsd", "fdsfdfsdfsd");
for (PurchaseHistoryRecord purchaseHistoryRecord : list) {
purchaseHistoryRecord.getSku();
}
}
});
retrievePlayStoreSubscriptions();
verifyUserSubscriptionStatus();
} else {
showSubscriptionDetailsError();
}
@ -144,10 +140,48 @@ public class Premium extends NbActivity {
billingClient.startConnection(billingClientStateListener);
}
private void retrieveSubs() {
private void verifyUserSubscriptionStatus() {
boolean hasNewsBlurSubscription = PrefsUtils.isPremium(this);
Purchase playStoreSubscription = null;
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
if (result.getPurchasesList() != null) {
for (Purchase purchase : result.getPurchasesList()) {
if (purchase.getSku().equals(AppConstants.PREMIUM_SKU)) {
playStoreSubscription = purchase;
}
}
}
if (hasNewsBlurSubscription || playStoreSubscription != null) {
binding.containerGoingPremium.setVisibility(View.GONE);
binding.containerGonePremium.setVisibility(View.VISIBLE);
if (playStoreSubscription != null) {
long expirationTimeMs = playStoreSubscription.getPurchaseTime() + DateUtils.YEAR_IN_MILLIS;
Date expirationDate = new Date(expirationTimeMs);
DateFormat dateFormat = new SimpleDateFormat("EEE, MMMM d, yyyy", Locale.getDefault());
dateFormat.setTimeZone(TimeZone.getDefault());
String renewalString;
if (playStoreSubscription.isAutoRenewing()) {
renewalString = getString(R.string.premium_subscription_renewal, dateFormat.format(expirationDate));
} else {
renewalString = getString(R.string.premium_subscription_expiration, dateFormat.format(expirationDate));
}
binding.textSubscriptionRenewal.setText(renewalString);
binding.textSubscriptionRenewal.setVisibility(View.VISIBLE);
}
}
if (!hasNewsBlurSubscription && playStoreSubscription != null) {
purchasedSubscription = playStoreSubscription;
notifyNewsBlurOfSubscription();
}
}
private void retrievePlayStoreSubscriptions() {
List<String> skuList = new ArrayList<>(1);
// add sub SKUs from Play Store
skuList.add(subscriptionSku);
skuList.add(AppConstants.PREMIUM_SKU);
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.SUBS);
billingClient.querySkuDetailsAsync(params.build(), (billingResult, skuDetailsList) -> {
@ -159,7 +193,7 @@ public class Premium extends NbActivity {
private void processSkuDetailsList(@Nullable List<SkuDetails> skuDetailsList) {
if (skuDetailsList != null) {
for (SkuDetails skuDetails : skuDetailsList) {
if (skuDetails.getSku().equals(subscriptionSku)) {
if (skuDetails.getSku().equals(AppConstants.PREMIUM_SKU)) {
Log.d(Premium.this.getLocalClassName(), "Sku detail: " + skuDetails.getTitle() + " | " + skuDetails.getDescription() + " | " + skuDetails.getPrice() + " | " + skuDetails.getSku());
subscriptionDetails = skuDetails;
}
@ -206,10 +240,13 @@ public class Premium extends NbActivity {
billingClient.launchBillingFlow(this, billingFlowParams);
}
private void handlePurchase(Purchase purchase) {
Log.d(Premium.this.getLocalClassName(), "handlePurchase: " + purchase.getOrderId());
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged()) {
purchasedSubscription = purchase;
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && purchase.isAcknowledged()) {
verifyUserSubscriptionStatus();
} else if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged()) {
// need to acknowledge first time sub otherwise it will void
Log.d(Premium.this.getLocalClassName(), "acknowledge purchase: " + purchase.getOrderId());
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
@ -219,7 +256,25 @@ public class Premium extends NbActivity {
}
}
private void enablePremiumAccess() {
// what now?
private void notifyNewsBlurOfSubscription() {
if (purchasedSubscription != null) {
APIManager apiManager = new APIManager(this);
new AsyncTask<Void, Void, NewsBlurResponse>() {
@Override
protected NewsBlurResponse doInBackground(Void... voids) {
return apiManager.saveReceipt(purchasedSubscription.getOrderId(), purchasedSubscription.getSku());
}
@Override
protected void onPostExecute(NewsBlurResponse result) {
super.onPostExecute(result);
if (!result.isError()) {
NBSyncService.forceFeedsFolders();
triggerSync();
}
finish();
}
}.execute();
}
}
}

View file

@ -76,6 +76,7 @@ public class APIConstants {
public static final String PATH_ADD_FOLDER = "/reader/add_folder";
public static final String PATH_DELETE_FOLDER = "/reader/delete_folder";
public static final String PATH_RENAME_FOLDER = "/reader/rename_folder";
public static final String PATH_SAVE_RECEIPT = "/profile/save_android_receipt";
public static String buildUrl(String path) {
return CurrentUrlBase + path;
@ -129,6 +130,8 @@ public class APIConstants {
public static final String PARAMETER_FOLDER_TO_DELETE = "folder_to_delete";
public static final String PARAMETER_FOLDER_TO_RENAME = "folder_to_rename";
public static final String PARAMETER_NEW_FOLDER_NAME = "new_folder_name";
public static final String PARAMETER_ORDER_ID = "order_id";
public static final String PARAMETER_PRODUCT_ID = "product_id";
public static final String VALUE_PREFIX_SOCIAL = "social:";
public static final String VALUE_ALLSOCIAL = "river:blurblogs"; // the magic value passed to the mark-read API for all social feeds

View file

@ -661,6 +661,14 @@ public class APIManager {
return response.getResponse(gson, NewsBlurResponse.class);
}
public NewsBlurResponse saveReceipt(String orderId, String productId) {
ContentValues values = new ContentValues();
values.put(APIConstants.PARAMETER_ORDER_ID, orderId);
values.put(APIConstants.PARAMETER_PRODUCT_ID, productId);
APIResponse response = post(buildUrl(APIConstants.PATH_SAVE_RECEIPT), values);
return response.getResponse(gson, NewsBlurResponse.class);
}
/* HTTP METHODS */
private APIResponse get(final String urlString) {

View file

@ -95,4 +95,7 @@ public class AppConstants {
// Shiloh photo
public final static String SHILOH_PHOTO_URL = "https://newsblur.com/media//img/reader/shiloh.jpg";
// Premium subscription SKU
public final static String PREMIUM_SKU = "nb.premium.36";
}