Refactoring

pull/161/head
M66B 6 years ago
parent 17b11065d8
commit ca480d054d

@ -207,6 +207,12 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".ActivityBilling"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:launchMode="singleInstance" />
<service <service
android:name=".ServiceSynchronize" android:name=".ServiceSynchronize"
android:foregroundServiceType="dataSync" /> android:foregroundServiceType="dataSync" />

@ -19,6 +19,7 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B) Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/ */
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -33,6 +34,8 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
@ -67,21 +70,35 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedListener { public class ActivityBilling extends ActivityBase implements PurchasesUpdatedListener, FragmentManager.OnBackStackChangedListener {
private BillingClient billingClient = null; private BillingClient billingClient = null;
private Map<String, SkuDetails> skuDetails = new HashMap<>(); private Map<String, SkuDetails> skuDetails = new HashMap<>();
private List<IBillingListener> listeners = new ArrayList<>(); private List<IBillingListener> listeners = new ArrayList<>();
static final String ACTION_PURCHASE = BuildConfig.APPLICATION_ID + ".ACTION_PURCHASE"; static final String ACTION_PURCHASE = BuildConfig.APPLICATION_ID + ".ACTION_PURCHASE";
static final String ACTION_PURCHASE_CHECK = BuildConfig.APPLICATION_ID + ".ACTION_PURCHASE_CHECK"; static final String ACTION_PURCHASE_CHECK = BuildConfig.APPLICATION_ID + ".ACTION_PURCHASE_CHECK";
static final String ACTION_ACTIVATE_PRO = BuildConfig.APPLICATION_ID + ".ACTIVATE_PRO";
final static long MAX_SKU_CACHE_DURATION = 24 * 3600 * 1000L; // milliseconds final static long MAX_SKU_CACHE_DURATION = 24 * 3600 * 1000L; // milliseconds
@Override @Override
@SuppressLint("MissingSuperCall")
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState, true);
}
protected void onCreate(Bundle savedInstanceState, boolean standalone) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (standalone) {
setContentView(R.layout.activity_billing);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
getSupportFragmentManager().addOnBackStackChangedListener(this);
}
if (Helper.isPlayStoreInstall(this)) { if (Helper.isPlayStoreInstall(this)) {
Log.i("IAB start"); Log.i("IAB start");
billingClient = BillingClient.newBuilder(this) billingClient = BillingClient.newBuilder(this)
@ -92,6 +109,13 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
} }
} }
@Override
public void onBackStackChanged() {
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count == 0)
finish();
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
@ -100,7 +124,6 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
IntentFilter iff = new IntentFilter(); IntentFilter iff = new IntentFilter();
iff.addAction(ACTION_PURCHASE); iff.addAction(ACTION_PURCHASE);
iff.addAction(ACTION_PURCHASE_CHECK); iff.addAction(ACTION_PURCHASE_CHECK);
iff.addAction(ACTION_ACTIVATE_PRO);
lbm.registerReceiver(receiver, iff); lbm.registerReceiver(receiver, iff);
if (billingClient != null && billingClient.isReady()) if (billingClient != null && billingClient.isReady())
@ -110,6 +133,7 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.unregisterReceiver(receiver); lbm.unregisterReceiver(receiver);
} }
@ -118,6 +142,7 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
protected void onDestroy() { protected void onDestroy() {
if (billingClient != null) if (billingClient != null)
billingClient.endConnection(); billingClient.endConnection();
super.onDestroy(); super.onDestroy();
} }
@ -129,27 +154,42 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
return BuildConfig.APPLICATION_ID + ".pro"; return BuildConfig.APPLICATION_ID + ".pro";
} }
protected Intent getIntentPro() { private static String getChallenge(Context context) throws NoSuchAlgorithmException {
if (Helper.isPlayStoreInstall(this)) String android_id = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
return null; return Helper.sha256(android_id);
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(BuildConfig.PRO_FEATURES_URI + "?challenge=" + getChallenge()));
return intent;
} catch (NoSuchAlgorithmException ex) {
Log.e(ex);
return null;
} }
private static String getResponse(Context context) throws NoSuchAlgorithmException {
return Helper.sha256(BuildConfig.APPLICATION_ID + getChallenge(context));
} }
private String getChallenge() throws NoSuchAlgorithmException { static boolean activatePro(Context context, Uri data) throws NoSuchAlgorithmException {
String android_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); String challenge = getChallenge(context);
return Helper.sha256(android_id); String response = data.getQueryParameter("response");
Log.i("IAB challenge=" + challenge);
Log.i("IAB response=" + response);
String expected = getResponse(context);
if (expected.equals(response)) {
Log.i("IAB response valid");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit()
.putBoolean("pro", true)
.putBoolean("play_store", false)
.apply();
WidgetUnified.update(context);
return true;
} else {
Log.i("IAB response invalid");
return false;
}
} }
private String getResponse() throws NoSuchAlgorithmException { static boolean isPro(Context context) {
return Helper.sha256(BuildConfig.APPLICATION_ID + getChallenge()); if (false && BuildConfig.DEBUG)
return true;
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pro", false);
} }
private BroadcastReceiver receiver = new BroadcastReceiver() { private BroadcastReceiver receiver = new BroadcastReceiver() {
@ -160,8 +200,6 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
onPurchase(intent); onPurchase(intent);
else if (ACTION_PURCHASE_CHECK.equals(intent.getAction())) else if (ACTION_PURCHASE_CHECK.equals(intent.getAction()))
onPurchaseCheck(intent); onPurchaseCheck(intent);
else if (ACTION_ACTIVATE_PRO.equals(intent.getAction()))
onActivatePro(intent);
} }
} }
}; };
@ -179,7 +217,14 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
if (result.getResponseCode() != BillingClient.BillingResponseCode.OK) if (result.getResponseCode() != BillingClient.BillingResponseCode.OK)
notifyError(text); notifyError(text);
} else } else
Helper.view(this, getIntentPro()); try {
Intent view = new Intent(Intent.ACTION_VIEW);
view.setData(Uri.parse(BuildConfig.PRO_FEATURES_URI + "?challenge=" + getChallenge(this)));
Helper.view(this, view);
} catch (NoSuchAlgorithmException ex) {
Log.e(ex);
Helper.unexpectedError(getSupportFragmentManager(), ex);
}
} }
private void onPurchaseCheck(Intent intent) { private void onPurchaseCheck(Intent intent) {
@ -200,35 +245,6 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
}); });
} }
private void onActivatePro(Intent intent) {
try {
Uri data = intent.getParcelableExtra("uri");
String challenge = getChallenge();
String response = data.getQueryParameter("response");
Log.i("IAB challenge=" + challenge);
Log.i("IAB response=" + response);
String expected = getResponse();
if (expected.equals(response)) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit()
.putBoolean("pro", true)
.putBoolean("play_store", false)
.apply();
Log.i("IAB response valid");
ToastEx.makeText(this, R.string.title_pro_valid, Toast.LENGTH_LONG).show();
WidgetUnified.update(this);
} else {
Log.i("IAB response invalid");
ToastEx.makeText(this, R.string.title_pro_invalid, Toast.LENGTH_LONG).show();
}
} catch (NoSuchAlgorithmException ex) {
Log.e(ex);
Helper.unexpectedError(getSupportFragmentManager(), ex);
}
}
private BillingClientStateListener billingClientStateListener = new BillingClientStateListener() { private BillingClientStateListener billingClientStateListener = new BillingClientStateListener() {
private int backoff = 4; // seconds private int backoff = 4; // seconds
@ -303,10 +319,8 @@ abstract class ActivityBilling extends ActivityBase implements PurchasesUpdatedL
if (billingClient.isReady()) { if (billingClient.isReady()) {
listener.onConnected(); listener.onConnected();
queryPurchases(); queryPurchases();
} else { } else
listener.onDisconnected(); listener.onDisconnected();
billingClient.startConnection(billingClientStateListener);
}
owner.getLifecycle().addObserver(new LifecycleObserver() { owner.getLifecycle().addObserver(new LifecycleObserver() {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)

@ -19,10 +19,7 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B) Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/ */
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.net.MailTo; import android.net.MailTo;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -34,7 +31,6 @@ import androidx.core.app.TaskStackBuilder;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist; import org.jsoup.safety.Whitelist;
@ -44,11 +40,9 @@ import java.util.ArrayList;
import javax.mail.internet.AddressException; import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
public class ActivityCompose extends ActivityBilling implements FragmentManager.OnBackStackChangedListener { public class ActivityCompose extends ActivityBase implements FragmentManager.OnBackStackChangedListener {
static final int PI_REPLY = 1; static final int PI_REPLY = 1;
static final String ACTION_SHOW_PRO = BuildConfig.APPLICATION_ID + ".SHOW_PRO";
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -214,39 +208,4 @@ public class ActivityCompose extends ActivityBilling implements FragmentManager.
return false; return false;
} }
} }
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
IntentFilter iff = new IntentFilter();
iff.addAction(ACTION_SHOW_PRO);
lbm.registerReceiver(receiver, iff);
}
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.unregisterReceiver(receiver);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
if (ACTION_SHOW_PRO.equals(intent.getAction()))
onShowPro(intent);
}
}
};
private void onShowPro(Intent intent) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
getSupportFragmentManager().popBackStack("pro", FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
} }

@ -409,7 +409,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
} }
private void onMenuExport() { private void onMenuExport() {
if (Helper.isPro(this)) { if (ActivityBilling.isPro(this)) {
try { try {
askPassword(true); askPassword(true);
} catch (Throwable ex) { } catch (Throwable ex) {
@ -417,7 +417,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
Helper.unexpectedError(getSupportFragmentManager(), ex); Helper.unexpectedError(getSupportFragmentManager(), ex);
} }
} else } else
ToastEx.makeText(this, R.string.title_pro_feature, Toast.LENGTH_LONG).show(); startActivity(new Intent(this, ActivityBilling.class));
} }
private void onMenuImport() { private void onMenuImport() {
@ -457,21 +457,20 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
private void onMenuBiometrics() { private void onMenuBiometrics() {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivitySetup.this); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivitySetup.this);
final boolean biometrics = prefs.getBoolean("biometrics", false); final boolean biometrics = prefs.getBoolean("biometrics", false);
final boolean pro = Helper.isPro(this); final boolean pro = ActivityBilling.isPro(this);
Helper.authenticate(this, biometrics, new Runnable() { Helper.authenticate(this, biometrics, new Runnable() {
@Override @Override
public void run() { public void run() {
if (pro) if (pro) {
prefs.edit().putBoolean("biometrics", !biometrics).apply(); prefs.edit().putBoolean("biometrics", !biometrics).apply();
ToastEx.makeText(ActivitySetup.this, ToastEx.makeText(ActivitySetup.this,
pro biometrics
? biometrics
? R.string.title_setup_biometrics_disable ? R.string.title_setup_biometrics_disable
: R.string.title_setup_biometrics_enable : R.string.title_setup_biometrics_enable,
: R.string.title_pro_feature,
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
} else
startActivity(new Intent(ActivitySetup.this, ActivityBilling.class));
} }
}, new Runnable() { }, new Runnable() {
@Override @Override

@ -19,6 +19,7 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B) Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/ */
import android.annotation.SuppressLint;
import android.app.Dialog; import android.app.Dialog;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
@ -114,14 +115,14 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
static final String ACTION_EDIT_ANSWER = BuildConfig.APPLICATION_ID + ".EDIT_ANSWER"; static final String ACTION_EDIT_ANSWER = BuildConfig.APPLICATION_ID + ".EDIT_ANSWER";
static final String ACTION_EDIT_RULES = BuildConfig.APPLICATION_ID + ".EDIT_RULES"; static final String ACTION_EDIT_RULES = BuildConfig.APPLICATION_ID + ".EDIT_RULES";
static final String ACTION_EDIT_RULE = BuildConfig.APPLICATION_ID + ".EDIT_RULE"; static final String ACTION_EDIT_RULE = BuildConfig.APPLICATION_ID + ".EDIT_RULE";
static final String ACTION_SHOW_PRO = BuildConfig.APPLICATION_ID + ".SHOW_PRO";
private static final long EXIT_DELAY = 2500L; // milliseconds private static final long EXIT_DELAY = 2500L; // milliseconds
static final long UPDATE_INTERVAL = (BuildConfig.BETA_RELEASE ? 4 : 12) * 3600 * 1000L; // milliseconds static final long UPDATE_INTERVAL = (BuildConfig.BETA_RELEASE ? 4 : 12) * 3600 * 1000L; // milliseconds
@Override @Override
@SuppressLint("MissingSuperCall")
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState, false);
if (savedInstanceState != null) if (savedInstanceState != null)
searching = savedInstanceState.getBoolean("fair:searching"); searching = savedInstanceState.getBoolean("fair:searching");
@ -341,12 +342,11 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
} }
}).setSeparated()); }).setSeparated());
if (getIntentPro() == null || getIntentPro().resolveActivity(pm) != null)
extra.add(new NavMenuItem(R.drawable.baseline_monetization_on_24, R.string.menu_pro, new Runnable() { extra.add(new NavMenuItem(R.drawable.baseline_monetization_on_24, R.string.menu_pro, new Runnable() {
@Override @Override
public void run() { public void run() {
drawerLayout.closeDrawer(drawerContainer); drawerLayout.closeDrawer(drawerContainer);
onShowPro(null); startActivity(new Intent(ActivityView.this, ActivityBilling.class));
} }
})); }));
@ -560,7 +560,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
iff.addAction(ACTION_EDIT_ANSWER); iff.addAction(ACTION_EDIT_ANSWER);
iff.addAction(ACTION_EDIT_RULES); iff.addAction(ACTION_EDIT_RULES);
iff.addAction(ACTION_EDIT_RULE); iff.addAction(ACTION_EDIT_RULE);
iff.addAction(ACTION_SHOW_PRO);
lbm.registerReceiver(receiver, iff); lbm.registerReceiver(receiver, iff);
checkUpdate(false); checkUpdate(false);
@ -990,8 +989,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
onEditRules(intent); onEditRules(intent);
else if (ACTION_EDIT_RULE.equals(action)) else if (ACTION_EDIT_RULE.equals(action))
onEditRule(intent); onEditRule(intent);
else if (ACTION_SHOW_PRO.equals(action))
onShowPro(intent);
} }
} }
}; };
@ -1093,15 +1090,6 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
fragmentTransaction.commit(); fragmentTransaction.commit();
} }
private void onShowPro(Intent intent) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
getSupportFragmentManager().popBackStack("pro", FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro");
fragmentTransaction.commit();
}
private class UpdateInfo { private class UpdateInfo {
String tag_name; // version String tag_name; // version
String html_url; String html_url;

@ -125,7 +125,7 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
private void bindTo(TupleAccountEx account) { private void bindTo(TupleAccountEx account) {
view.setActivated(account.tbd != null); view.setActivated(account.tbd != null);
vwColor.setBackgroundColor(account.color == null ? Color.TRANSPARENT : account.color); vwColor.setBackgroundColor(account.color == null ? Color.TRANSPARENT : account.color);
vwColor.setVisibility(Helper.isPro(context) ? View.VISIBLE : View.INVISIBLE); vwColor.setVisibility(ActivityBilling.isPro(context) ? View.VISIBLE : View.INVISIBLE);
ivSync.setImageResource(account.synchronize ? R.drawable.baseline_sync_24 : R.drawable.baseline_sync_disabled_24); ivSync.setImageResource(account.synchronize ? R.drawable.baseline_sync_24 : R.drawable.baseline_sync_disabled_24);

@ -167,7 +167,7 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
if (listener == null) { if (listener == null) {
vwColor.setBackgroundColor(folder.accountColor == null ? Color.TRANSPARENT : folder.accountColor); vwColor.setBackgroundColor(folder.accountColor == null ? Color.TRANSPARENT : folder.accountColor);
vwColor.setVisibility(account < 0 && Helper.isPro(context) ? View.VISIBLE : View.GONE); vwColor.setVisibility(account < 0 && ActivityBilling.isPro(context) ? View.VISIBLE : View.GONE);
if (folder.sync_state == null || "requested".equals(folder.sync_state)) { if (folder.sync_state == null || "requested".equals(folder.sync_state)) {
if (folder.executing > 0) if (folder.executing > 0)
@ -600,9 +600,8 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
private void onActionCreateChannel() { private void onActionCreateChannel() {
if (!Helper.isPro(context)) { if (!ActivityBilling.isPro(context)) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); context.startActivity(new Intent(context, ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }

@ -107,7 +107,7 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
private void bindTo(TupleIdentityEx identity) { private void bindTo(TupleIdentityEx identity) {
view.setActivated(identity.tbd != null); view.setActivated(identity.tbd != null);
vwColor.setBackgroundColor(identity.color == null ? Color.TRANSPARENT : identity.color); vwColor.setBackgroundColor(identity.color == null ? Color.TRANSPARENT : identity.color);
vwColor.setVisibility(Helper.isPro(context) ? View.VISIBLE : View.INVISIBLE); vwColor.setVisibility(ActivityBilling.isPro(context) ? View.VISIBLE : View.INVISIBLE);
ivSync.setImageResource(identity.synchronize ? R.drawable.baseline_sync_24 : R.drawable.baseline_sync_disabled_24); ivSync.setImageResource(identity.synchronize ? R.drawable.baseline_sync_24 : R.drawable.baseline_sync_disabled_24);

@ -82,6 +82,7 @@ import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -122,6 +123,7 @@ import org.jsoup.nodes.Element;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -646,7 +648,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
// Account color // Account color
vwColor.setCardBackgroundColor(message.accountColor == null ? Color.TRANSPARENT : message.accountColor); vwColor.setCardBackgroundColor(message.accountColor == null ? Color.TRANSPARENT : message.accountColor);
vwColor.setVisibility(Helper.isPro(context) ? View.VISIBLE : View.INVISIBLE); vwColor.setVisibility(ActivityBilling.isPro(context) ? View.VISIBLE : View.INVISIBLE);
// Expander // Expander
boolean expanded = (viewType == ViewType.THREAD && properties.getValue("expanded", message.id)); boolean expanded = (viewType == ViewType.THREAD && properties.getValue("expanded", message.id));
@ -881,7 +883,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
int flagged = (message.count - message.unflagged); int flagged = (message.count - message.unflagged);
ivFlagged.setImageResource(flagged > 0 ? R.drawable.baseline_star_24 : R.drawable.baseline_star_border_24); ivFlagged.setImageResource(flagged > 0 ? R.drawable.baseline_star_24 : R.drawable.baseline_star_border_24);
ivFlagged.setImageTintList(ColorStateList.valueOf(flagged > 0 ivFlagged.setImageTintList(ColorStateList.valueOf(flagged > 0
? message.color == null || !Helper.isPro(context) ? message.color == null || !ActivityBilling.isPro(context)
? colorAccent : message.color : textColorSecondary)); ? colorAccent : message.color : textColorSecondary));
ivFlagged.setVisibility(flags && !message.folderReadOnly ivFlagged.setVisibility(flags && !message.folderReadOnly
? (message.uid == null ? View.INVISIBLE : View.VISIBLE) ? (message.uid == null ? View.INVISIBLE : View.VISIBLE)
@ -1319,9 +1321,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
private void onActionCalendar(TupleMessageEx message, int action) { private void onActionCalendar(TupleMessageEx message, int action) {
if (!Helper.isPro(context)) { if (!ActivityBilling.isPro(context)) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); context.startActivity(new Intent(context, ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -1709,9 +1710,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
@TargetApi(Build.VERSION_CODES.O) @TargetApi(Build.VERSION_CODES.O)
private void onActionCreateChannel() { private void onActionCreateChannel() {
if (!Helper.isPro(context)) { if (!ActivityBilling.isPro(context)) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); context.startActivity(new Intent(context, ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -2172,10 +2172,15 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
Log.i("Opening uri=" + uri); Log.i("Opening uri=" + uri);
if (BuildConfig.APPLICATION_ID.equals(uri.getHost()) && "/activate/".equals(uri.getPath())) { if (BuildConfig.APPLICATION_ID.equals(uri.getHost()) && "/activate/".equals(uri.getPath())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); try {
lbm.sendBroadcast( if (ActivityBilling.activatePro(context, uri))
new Intent(ActivityView.ACTION_ACTIVATE_PRO) ToastEx.makeText(context, R.string.title_pro_valid, Toast.LENGTH_LONG).show();
.putExtra("uri", uri)); else
ToastEx.makeText(context, R.string.title_pro_invalid, Toast.LENGTH_LONG).show();
} catch (NoSuchAlgorithmException ex) {
Log.e(ex);
Helper.unexpectedError(parentFragment.getFragmentManager(), ex);
}
} else { } else {
if ("cid".equals(uri.getScheme())) if ("cid".equals(uri.getScheme()))
return; return;
@ -2821,7 +2826,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
if (recipients.length == 0 && if (recipients.length == 0 &&
data.message.list_post == null && data.message.list_post == null &&
data.message.receipt_to == null && data.message.receipt_to == null &&
(answers == 0 && Helper.isPro(context))) { (answers == 0 && ActivityBilling.isPro(context))) {
onMenuReply(data, "reply"); onMenuReply(data, "reply");
return; return;
} }
@ -2832,7 +2837,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setVisible(recipients.length > 0); popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setVisible(recipients.length > 0);
popupMenu.getMenu().findItem(R.id.menu_reply_list).setVisible(data.message.list_post != null); popupMenu.getMenu().findItem(R.id.menu_reply_list).setVisible(data.message.list_post != null);
popupMenu.getMenu().findItem(R.id.menu_reply_receipt).setVisible(data.message.receipt_to != null); popupMenu.getMenu().findItem(R.id.menu_reply_receipt).setVisible(data.message.receipt_to != null);
popupMenu.getMenu().findItem(R.id.menu_reply_answer).setVisible(answers != 0 || !Helper.isPro(context)); popupMenu.getMenu().findItem(R.id.menu_reply_answer).setVisible(answers != 0 || !ActivityBilling.isPro(context));
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
@ -2908,9 +2913,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem target) { public boolean onMenuItemClick(MenuItem target) {
if (!Helper.isPro(context)) { if (!ActivityBilling.isPro(context)) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); context.startActivity(new Intent(context, ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return true; return true;
} }
@ -3901,9 +3905,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -3978,9 +3981,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }

@ -101,7 +101,7 @@ public class AdapterNavFolder extends RecyclerView.Adapter<AdapterNavFolder.View
? R.drawable.baseline_folder_24 ? R.drawable.baseline_folder_24
: R.drawable.baseline_folder_open_24); : R.drawable.baseline_folder_open_24);
if (folder.accountColor == null || !Helper.isPro(context)) if (folder.accountColor == null || !ActivityBilling.isPro(context))
ivItem.clearColorFilter(); ivItem.clearColorFilter();
else else
ivItem.setColorFilter(folder.accountColor); ivItem.setColorFilter(folder.accountColor);

@ -184,7 +184,7 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
popupMenu.getMenu().add(Menu.NONE, R.string.title_rule_enabled, 1, R.string.title_rule_enabled) popupMenu.getMenu().add(Menu.NONE, R.string.title_rule_enabled, 1, R.string.title_rule_enabled)
.setCheckable(true).setChecked(rule.enabled); .setCheckable(true).setChecked(rule.enabled);
popupMenu.getMenu().add(Menu.NONE, R.string.title_rule_execute, 2, R.string.title_rule_execute) popupMenu.getMenu().add(Menu.NONE, R.string.title_rule_execute, 2, R.string.title_rule_execute)
.setEnabled(Helper.isPro(context)); .setEnabled(ActivityBilling.isPro(context));
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override

@ -1737,7 +1737,7 @@ class Core {
} }
private static void runRules(Context context, Message imessage, EntityMessage message, List<EntityRule> rules) { private static void runRules(Context context, Message imessage, EntityMessage message, List<EntityRule> rules) {
if (!Helper.isPro(context)) if (!ActivityBilling.isPro(context))
return; return;
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
@ -1938,7 +1938,7 @@ class Core {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean badge = prefs.getBoolean("badge", true); boolean badge = prefs.getBoolean("badge", true);
boolean pro = Helper.isPro(context); boolean pro = ActivityBilling.isPro(context);
// Current // Current
int unseen = 0; int unseen = 0;
@ -2057,7 +2057,7 @@ class Core {
if (messages == null || messages.size() == 0 || nm == null) if (messages == null || messages.size() == 0 || nm == null)
return notifications; return notifications;
boolean pro = Helper.isPro(context); boolean pro = ActivityBilling.isPro(context);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean biometrics = prefs.getBoolean("biometrics", false); boolean biometrics = prefs.getBoolean("biometrics", false);

@ -49,7 +49,6 @@ import android.widget.RadioGroup;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -762,7 +761,7 @@ public class FragmentAccount extends FragmentBase {
EntityFolder left = (EntityFolder) args.getSerializable("left"); EntityFolder left = (EntityFolder) args.getSerializable("left");
EntityFolder right = (EntityFolder) args.getSerializable("right"); EntityFolder right = (EntityFolder) args.getSerializable("right");
boolean pro = Helper.isPro(context); boolean pro = ActivityBilling.isPro(context);
boolean should = args.getBoolean("should"); boolean should = args.getBoolean("should");
if (host.contains(":")) { if (host.contains(":")) {
@ -1167,7 +1166,7 @@ public class FragmentAccount extends FragmentBase {
etName.setText(account == null ? null : account.name); etName.setText(account == null ? null : account.name);
boolean pro = Helper.isPro(getContext()); boolean pro = ActivityBilling.isPro(getContext());
cbNotify.setChecked(account != null && account.notify && pro); cbNotify.setChecked(account != null && account.notify && pro);
cbNotify.setEnabled(pro); cbNotify.setEnabled(pro);
@ -1292,11 +1291,11 @@ public class FragmentAccount extends FragmentBase {
switch (requestCode) { switch (requestCode) {
case REQUEST_COLOR: case REQUEST_COLOR:
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
if (Helper.isPro(getContext())) { if (ActivityBilling.isPro(getContext())) {
Bundle args = data.getBundleExtra("args"); Bundle args = data.getBundleExtra("args");
setColor(args.getInt("color")); setColor(args.getInt("color"));
} else } else
ToastEx.makeText(getContext(), R.string.title_pro_feature, Toast.LENGTH_LONG).show(); startActivity(new Intent(getContext(), ActivityBilling.class));
} }
break; break;
case REQUEST_SAVE: case REQUEST_SAVE:

@ -99,7 +99,6 @@ import androidx.core.content.FileProvider;
import androidx.cursoradapter.widget.SimpleCursorAdapter; import androidx.cursoradapter.widget.SimpleCursorAdapter;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -903,9 +902,8 @@ public class FragmentCompose extends FragmentBase {
} }
private void onMenuAnswer() { private void onMenuAnswer() {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityCompose.ACTION_SHOW_PRO));
return; return;
} }
@ -1542,9 +1540,8 @@ public class FragmentCompose extends FragmentBase {
} }
private void onSendAfter(long time) { private void onSendAfter(long time) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityCompose.ACTION_SHOW_PRO));
return; return;
} }
@ -2499,7 +2496,7 @@ public class FragmentCompose extends FragmentBase {
} }
}); });
} }
}else { } else {
// Move draft to new account // Move draft to new account
if (draft.account != aid && aid >= 0) { if (draft.account != aid && aid >= 0) {
Log.i("Account changed"); Log.i("Account changed");

@ -31,7 +31,6 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.Editable; import android.text.Editable;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
@ -53,7 +52,6 @@ import android.widget.RadioGroup;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -594,7 +592,7 @@ public class FragmentIdentity extends FragmentBase {
if (TextUtils.isEmpty(bcc)) if (TextUtils.isEmpty(bcc))
bcc = null; bcc = null;
if (color == Color.TRANSPARENT || !Helper.isPro(context)) if (color == Color.TRANSPARENT || !ActivityBilling.isPro(context))
color = null; color = null;
if (TextUtils.isEmpty(signature)) if (TextUtils.isEmpty(signature))
signature = null; signature = null;
@ -1005,11 +1003,11 @@ public class FragmentIdentity extends FragmentBase {
switch (requestCode) { switch (requestCode) {
case REQUEST_COLOR: case REQUEST_COLOR:
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
if (Helper.isPro(getContext())) { if (ActivityBilling.isPro(getContext())) {
Bundle args = data.getBundleExtra("args"); Bundle args = data.getBundleExtra("args");
setColor(args.getInt("color")); setColor(args.getInt("color"));
} else } else
ToastEx.makeText(getContext(), R.string.title_pro_feature, Toast.LENGTH_LONG).show(); startActivity(new Intent(getContext(), ActivityBilling.class));
} }
break; break;
case REQUEST_SAVE: case REQUEST_SAVE:

@ -372,8 +372,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
tvSupport.setOnClickListener(new View.OnClickListener() { tvSupport.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
} }
}); });
@ -3408,9 +3407,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
break; break;
case REQUEST_MESSAGES_COLOR: case REQUEST_MESSAGES_COLOR:
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -4007,9 +4005,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
} }
private void onColor(long id, int color) { private void onColor(long id, int color) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -4045,9 +4042,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
} }
private void onSnooze(Bundle args) { private void onSnooze(Bundle args) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -4099,9 +4095,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
} }
private void onSnoozeSelection(Bundle args) { private void onSnoozeSelection(Bundle args) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -4322,9 +4317,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
static void search( static void search(
final Context context, final LifecycleOwner owner, final FragmentManager manager, final Context context, final LifecycleOwner owner, final FragmentManager manager,
long folder, boolean server, String query) { long folder, boolean server, String query) {
if (!Helper.isPro(context)) { if (!ActivityBilling.isPro(context)) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); context.startActivity(new Intent(context, ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }

@ -289,7 +289,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
swBadge.setChecked(prefs.getBoolean("badge", true)); swBadge.setChecked(prefs.getBoolean("badge", true));
boolean pro = Helper.isPro(getContext()); boolean pro = ActivityBilling.isPro(getContext());
swSubscriptions.setChecked(prefs.getBoolean("subscriptions", false) && pro); swSubscriptions.setChecked(prefs.getBoolean("subscriptions", false) && pro);
swSubscriptions.setEnabled(pro); swSubscriptions.setEnabled(pro);
swSubscribedOnly.setChecked(prefs.getBoolean("subscribed_only", false)); swSubscribedOnly.setChecked(prefs.getBoolean("subscribed_only", false));

@ -232,7 +232,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
} }
private void setOptions() { private void setOptions() {
boolean pro = Helper.isPro(getContext()); boolean pro = ActivityBilling.isPro(getContext());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
swNotifyPreview.setChecked(prefs.getBoolean("notify_preview", true)); swNotifyPreview.setChecked(prefs.getBoolean("notify_preview", true));

@ -264,7 +264,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr
break; break;
} }
boolean pro = Helper.isPro(getContext()); boolean pro = ActivityBilling.isPro(getContext());
swSchedule.setChecked(prefs.getBoolean("schedule", false) && pro); swSchedule.setChecked(prefs.getBoolean("schedule", false) && pro);
swSchedule.setEnabled(pro); swSchedule.setEnabled(pro);
tvScheduleStart.setText(formatHour(getContext(), prefs.getInt("schedule_start", 0))); tvScheduleStart.setText(formatHour(getContext(), prefs.getInt("schedule_start", 0)));

@ -57,7 +57,6 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Group; import androidx.constraintlayout.widget.Group;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -494,9 +493,8 @@ public class FragmentRule extends FragmentBase {
break; break;
case REQUEST_COLOR: case REQUEST_COLOR:
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }
@ -770,9 +768,8 @@ public class FragmentRule extends FragmentBase {
} }
private void onActionSave() { private void onActionSave() {
if (!Helper.isPro(getContext())) { if (!ActivityBilling.isPro(getContext())) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext()); getContext().startActivity(new Intent(getContext(), ActivityBilling.class));
lbm.sendBroadcast(new Intent(ActivityView.ACTION_SHOW_PRO));
return; return;
} }

@ -230,7 +230,7 @@ public class Helper {
(Helper.hasValidFingerprint(context) ? "1" : "3") + (Helper.hasValidFingerprint(context) ? "1" : "3") +
(BuildConfig.PLAY_STORE_RELEASE ? "p" : "") + (BuildConfig.PLAY_STORE_RELEASE ? "p" : "") +
(BuildConfig.DEBUG ? "d" : "") + (BuildConfig.DEBUG ? "d" : "") +
(Helper.isPro(context) ? "+" : ""); (ActivityBilling.isPro(context) ? "+" : "");
Intent intent = new Intent(Intent.ACTION_SEND); Intent intent = new Intent(Intent.ACTION_SEND);
intent.setPackage(BuildConfig.APPLICATION_ID); intent.setPackage(BuildConfig.APPLICATION_ID);
intent.setType("text/plain"); intent.setType("text/plain");
@ -812,29 +812,19 @@ public class Helper {
return BuildConfig.PLAY_STORE_RELEASE; return BuildConfig.PLAY_STORE_RELEASE;
} }
static boolean isPro(Context context) {
if (false && BuildConfig.DEBUG)
return true;
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pro", false);
}
static void linkPro(final TextView tv) { static void linkPro(final TextView tv) {
if (isPro(tv.getContext()) && !BuildConfig.DEBUG) if (ActivityBilling.isPro(tv.getContext()) && !BuildConfig.DEBUG)
hide(tv); hide(tv);
else { else {
final Intent pro = new Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.PRO_FEATURES_URI));
PackageManager pm = tv.getContext().getPackageManager();
if (pro.resolveActivity(pm) != null) {
tv.getPaint().setUnderlineText(true); tv.getPaint().setUnderlineText(true);
tv.setOnClickListener(new View.OnClickListener() { tv.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
tv.getContext().startActivity(pro); tv.getContext().startActivity(new Intent(tv.getContext(), ActivityBilling.class));
} }
}); });
} }
} }
}
static <T> List<List<T>> chunkList(List<T> list, int size) { static <T> List<List<T>> chunkList(List<T> list, int size) {
List<List<T>> result = new ArrayList<>(list.size() / size); List<List<T>> result = new ArrayList<>(list.size() / size);

@ -459,7 +459,7 @@ public class Log {
Helper.hasValidFingerprint(context) ? "1" : "3", Helper.hasValidFingerprint(context) ? "1" : "3",
BuildConfig.PLAY_STORE_RELEASE ? "p" : "", BuildConfig.PLAY_STORE_RELEASE ? "p" : "",
BuildConfig.DEBUG ? "d" : "", BuildConfig.DEBUG ? "d" : "",
Helper.isPro(context) ? "+" : "")); ActivityBilling.isPro(context) ? "+" : ""));
sb.append(String.format("Android: %s (SDK %d)\r\n", Build.VERSION.RELEASE, Build.VERSION.SDK_INT)); sb.append(String.format("Android: %s (SDK %d)\r\n", Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
sb.append("\r\n"); sb.append("\r\n");

@ -60,7 +60,7 @@ public class ServiceExternal extends Service {
if (intent == null) if (intent == null)
return START_NOT_STICKY; return START_NOT_STICKY;
if (!Helper.isPro(this)) if (!ActivityBilling.isPro(this))
return START_NOT_STICKY; return START_NOT_STICKY;
final Boolean enabled; final Boolean enabled;

@ -1488,7 +1488,7 @@ public class ServiceSynchronize extends ServiceBase {
am.cancel(piAlarm); am.cancel(piAlarm);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (!prefs.getBoolean("schedule", false) || !Helper.isPro(context)) if (!prefs.getBoolean("schedule", false) || !ActivityBilling.isPro(context))
return; return;
int minuteStart = prefs.getInt("schedule_start", 0); int minuteStart = prefs.getInt("schedule_start", 0);

@ -43,7 +43,7 @@ public class WidgetUnified extends AppWidgetProvider {
static void update(Context context) { static void update(Context context) {
Log.i("Widget unified update"); Log.i("Widget unified update");
if (Helper.isPro(context)) { if (ActivityBilling.isPro(context)) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetUnified.class)); int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetUnified.class));
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.lv); appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.lv);
@ -56,7 +56,7 @@ public class WidgetUnified extends AppWidgetProvider {
view.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); view.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(context, ActivityView.REQUEST_UNIFIED, view, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent pi = PendingIntent.getActivity(context, ActivityView.REQUEST_UNIFIED, view, PendingIntent.FLAG_UPDATE_CURRENT);
boolean pro = Helper.isPro(context); boolean pro = ActivityBilling.isPro(context);
for (int id : appWidgetIds) { for (int id : appWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_unified); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_unified);

@ -0,0 +1,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ActivityBilling" />
Loading…
Cancel
Save