Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
29ce4b727c
|
|||
![]() |
f178019ffe | ||
0a1b948042
|
|||
![]() |
74cbfb235e | ||
63c4104a89
|
|||
2597287b1e
|
|||
![]() |
316156f0f0 |
@@ -6,8 +6,8 @@ import android.content.SharedPreferences;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.billingclient.api.Purchase;
|
|
||||||
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple3;
|
||||||
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
|
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
|
||||||
import com.blackforestbytes.simplecloudnotifier.service.IABService;
|
import com.blackforestbytes.simplecloudnotifier.service.IABService;
|
||||||
import com.google.firebase.iid.FirebaseInstanceId;
|
import com.google.firebase.iid.FirebaseInstanceId;
|
||||||
@@ -122,6 +122,9 @@ public class SCNSettings
|
|||||||
e.putString( "user_key", user_key);
|
e.putString( "user_key", user_key);
|
||||||
e.putString( "fcm_token_local", fcm_token_local);
|
e.putString( "fcm_token_local", fcm_token_local);
|
||||||
e.putString( "fcm_token_server", fcm_token_server);
|
e.putString( "fcm_token_server", fcm_token_server);
|
||||||
|
e.putBoolean("promode_local", promode_local);
|
||||||
|
e.putBoolean("promode_server", promode_server);
|
||||||
|
e.putString( "promode_token", promode_token);
|
||||||
|
|
||||||
e.putBoolean("app_enabled", Enabled);
|
e.putBoolean("app_enabled", Enabled);
|
||||||
e.putInt( "local_cache_size", LocalCacheSize);
|
e.putInt( "local_cache_size", LocalCacheSize);
|
||||||
@@ -243,14 +246,17 @@ public class SCNSettings
|
|||||||
|
|
||||||
public void updateProState(View loader)
|
public void updateProState(View loader)
|
||||||
{
|
{
|
||||||
Purchase purch = IABService.inst().getPurchaseCached(IABService.IAB_PRO_MODE);
|
Tuple3<Boolean, Boolean, String> state = IABService.inst().getPurchaseCachedExtended(IABService.IAB_PRO_MODE);
|
||||||
boolean promode_real = (purch != null);
|
if (!state.Item2) return; // not initialized
|
||||||
|
|
||||||
|
boolean promode_real = state.Item1;
|
||||||
|
|
||||||
if (promode_real != promode_local || promode_real != promode_server)
|
if (promode_real != promode_local || promode_real != promode_server)
|
||||||
{
|
{
|
||||||
promode_local = promode_real;
|
promode_local = promode_real;
|
||||||
|
promode_token = promode_real ? state.Item3 : "";
|
||||||
|
save();
|
||||||
|
|
||||||
promode_token = promode_real ? purch.getPurchaseToken() : "";
|
|
||||||
updateProStateOnServer(loader);
|
updateProStateOnServer(loader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,14 +6,22 @@ import android.widget.Toast;
|
|||||||
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
||||||
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple4;
|
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple4;
|
||||||
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple5;
|
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple5;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.CMessage;
|
import com.blackforestbytes.simplecloudnotifier.model.CMessage;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.model.LogLevel;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.PriorityEnum;
|
import com.blackforestbytes.simplecloudnotifier.model.PriorityEnum;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.model.QueryLog;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
|
import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.model.SingleQuery;
|
||||||
|
import com.google.android.gms.common.util.JsonUtils;
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
import com.google.firebase.messaging.RemoteMessage;
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
|
import org.joda.time.Instant;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class FBMService extends FirebaseMessagingService
|
public class FBMService extends FirebaseMessagingService
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@@ -42,6 +50,10 @@ public class FBMService extends FirebaseMessagingService
|
|||||||
long scn_id = Long.parseLong(remoteMessage.getData().get("scn_msg_id"));
|
long scn_id = Long.parseLong(remoteMessage.getData().get("scn_msg_id"));
|
||||||
boolean trimmed = Boolean.parseBoolean(remoteMessage.getData().get("trimmed"));
|
boolean trimmed = Boolean.parseBoolean(remoteMessage.getData().get("trimmed"));
|
||||||
|
|
||||||
|
|
||||||
|
SingleQuery q = new SingleQuery(LogLevel.INFO, Instant.now(), "FBM<recieve>", Str.Empty, new JSONObject(remoteMessage.getData()).toString(), 0, "SUCCESS");
|
||||||
|
QueryLog.instance().add(q);
|
||||||
|
|
||||||
if (trimmed)
|
if (trimmed)
|
||||||
{
|
{
|
||||||
ServerCommunication.expand(SCNSettings.inst().user_id, SCNSettings.inst().user_key, scn_id, null, (i1, i2, i3, i4, i5) -> recieveData(i4, i1, i2, i3, i5, false));
|
ServerCommunication.expand(SCNSettings.inst().user_id, SCNSettings.inst().user_key, scn_id, null, (i1, i2, i3, i4, i5) -> recieveData(i4, i1, i2, i3, i5, false));
|
||||||
|
@@ -2,6 +2,7 @@ package com.blackforestbytes.simplecloudnotifier.service;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -11,13 +12,18 @@ import com.android.billingclient.api.BillingFlowParams;
|
|||||||
import com.android.billingclient.api.Purchase;
|
import com.android.billingclient.api.Purchase;
|
||||||
import com.android.billingclient.api.PurchasesUpdatedListener;
|
import com.android.billingclient.api.PurchasesUpdatedListener;
|
||||||
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple2;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple3;
|
||||||
import com.blackforestbytes.simplecloudnotifier.lib.lambda.Func0to0;
|
import com.blackforestbytes.simplecloudnotifier.lib.lambda.Func0to0;
|
||||||
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
|
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
||||||
import com.blackforestbytes.simplecloudnotifier.view.MainActivity;
|
import com.blackforestbytes.simplecloudnotifier.view.MainActivity;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Dictionary;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
@@ -45,12 +51,21 @@ public class IABService implements PurchasesUpdatedListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SimplePurchaseState { YES, NO, UNINITIALIZED }
|
||||||
|
|
||||||
private BillingClient client;
|
private BillingClient client;
|
||||||
private boolean isServiceConnected;
|
private boolean isServiceConnected;
|
||||||
private final List<Purchase> purchases = new ArrayList<>();
|
private final List<Purchase> purchases = new ArrayList<>();
|
||||||
|
private boolean _isInitialized = false;
|
||||||
|
|
||||||
|
private Map<String, Boolean> _localCache= new HashMap<>();
|
||||||
|
|
||||||
public IABService(Context c)
|
public IABService(Context c)
|
||||||
{
|
{
|
||||||
|
_isInitialized = false;
|
||||||
|
|
||||||
|
loadCache();
|
||||||
|
|
||||||
client = BillingClient
|
client = BillingClient
|
||||||
.newBuilder(c)
|
.newBuilder(c)
|
||||||
.setListener(this)
|
.setListener(this)
|
||||||
@@ -59,6 +74,45 @@ public class IABService implements PurchasesUpdatedListener
|
|||||||
startServiceConnection(this::queryPurchases, false);
|
startServiceConnection(this::queryPurchases, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadCache()
|
||||||
|
{
|
||||||
|
_localCache.clear();
|
||||||
|
SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("IAB", Context.MODE_PRIVATE);
|
||||||
|
int count = sharedPref.getInt("c", 0);
|
||||||
|
for (int i=0; i < count; i++)
|
||||||
|
{
|
||||||
|
String k = sharedPref.getString("["+i+"]->key", null);
|
||||||
|
boolean v = sharedPref.getBoolean("["+i+"]->value", false);
|
||||||
|
if (k==null)continue;
|
||||||
|
_localCache.put(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveCache()
|
||||||
|
{
|
||||||
|
SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("IAB", Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor= sharedPref.edit();
|
||||||
|
|
||||||
|
editor.putInt("c", _localCache.size());
|
||||||
|
int i = 0;
|
||||||
|
for (Map.Entry<String, Boolean> e : _localCache.entrySet())
|
||||||
|
{
|
||||||
|
editor.putString("["+i+"]->key", e.getKey());
|
||||||
|
editor.putBoolean("["+i+"]->value", e.getValue());
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
private synchronized void updateCache(String k, boolean v)
|
||||||
|
{
|
||||||
|
if (_localCache.containsKey(k) && _localCache.get(k)==v) return;
|
||||||
|
|
||||||
|
_localCache.put(k, v);
|
||||||
|
saveCache();
|
||||||
|
}
|
||||||
|
|
||||||
public void queryPurchases()
|
public void queryPurchases()
|
||||||
{
|
{
|
||||||
Func0to0 queryToExecute = () ->
|
Func0to0 queryToExecute = () ->
|
||||||
@@ -71,10 +125,12 @@ public class IABService implements PurchasesUpdatedListener
|
|||||||
{
|
{
|
||||||
for (Purchase p : purchasesResult.getPurchasesList())
|
for (Purchase p : purchasesResult.getPurchasesList())
|
||||||
{
|
{
|
||||||
handlePurchase(p);
|
handlePurchase(p, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean newProMode = getPurchaseCached(IAB_PRO_MODE) != null;
|
_isInitialized = true;
|
||||||
|
|
||||||
|
boolean newProMode = getPurchaseCachedSimple(IAB_PRO_MODE);
|
||||||
if (newProMode != SCNSettings.inst().promode_local)
|
if (newProMode != SCNSettings.inst().promode_local)
|
||||||
{
|
{
|
||||||
refreshProModeListener();
|
refreshProModeListener();
|
||||||
@@ -102,7 +158,8 @@ public class IABService implements PurchasesUpdatedListener
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeServiceRequest(Func0to0 runnable, final boolean userRequest) {
|
private void executeServiceRequest(Func0to0 runnable, final boolean userRequest)
|
||||||
|
{
|
||||||
if (isServiceConnected)
|
if (isServiceConnected)
|
||||||
{
|
{
|
||||||
runnable.invoke();
|
runnable.invoke();
|
||||||
@@ -130,28 +187,31 @@ public class IABService implements PurchasesUpdatedListener
|
|||||||
{
|
{
|
||||||
for (Purchase purchase : purchases)
|
for (Purchase purchase : purchases)
|
||||||
{
|
{
|
||||||
handlePurchase(purchase);
|
handlePurchase(purchase, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (responseCode == BillingClient.BillingResponse.ITEM_ALREADY_OWNED && purchases != null)
|
else if (responseCode == BillingClient.BillingResponse.ITEM_ALREADY_OWNED && purchases != null)
|
||||||
{
|
{
|
||||||
for (Purchase purchase : purchases)
|
for (Purchase purchase : purchases)
|
||||||
{
|
{
|
||||||
handlePurchase(purchase);
|
handlePurchase(purchase, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePurchase(Purchase purchase)
|
private void handlePurchase(Purchase purchase, boolean triggerUpdate)
|
||||||
{
|
{
|
||||||
Log.d(TAG, "Got a verified purchase: " + purchase);
|
Log.d(TAG, "Got a verified purchase: " + purchase);
|
||||||
|
|
||||||
purchases.add(purchase);
|
purchases.add(purchase);
|
||||||
|
|
||||||
refreshProModeListener();
|
if (triggerUpdate) refreshProModeListener();
|
||||||
|
|
||||||
|
updateCache(purchase.getSku(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshProModeListener() {
|
private void refreshProModeListener()
|
||||||
|
{
|
||||||
MainActivity ma = SCNApp.getMainActivity();
|
MainActivity ma = SCNApp.getMainActivity();
|
||||||
if (ma != null) ma.adpTabs.tab3.updateProState();
|
if (ma != null) ma.adpTabs.tab3.updateProState();
|
||||||
if (ma != null) ma.adpTabs.tab1.updateProState();
|
if (ma != null) ma.adpTabs.tab1.updateProState();
|
||||||
@@ -183,13 +243,31 @@ public class IABService implements PurchasesUpdatedListener
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Purchase getPurchaseCached(String id)
|
public boolean getPurchaseCachedSimple(String id)
|
||||||
{
|
{
|
||||||
for (Purchase p : purchases)
|
return getPurchaseCachedExtended(id).Item1;
|
||||||
{
|
|
||||||
if (Str.equals(p.getSku(), id)) return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public Tuple3<Boolean, Boolean, String> getPurchaseCachedExtended(String id)
|
||||||
|
{
|
||||||
|
// <state, initialized, token>
|
||||||
|
|
||||||
|
if (!_isInitialized)
|
||||||
|
{
|
||||||
|
if (_localCache.containsKey(id) && _localCache.get(id)) return new Tuple3<>(true, false, Str.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Purchase p : purchases)
|
||||||
|
{
|
||||||
|
if (Str.equals(p.getSku(), id))
|
||||||
|
{
|
||||||
|
updateCache(id, true);
|
||||||
|
return new Tuple3<>(true, true, p.getPurchaseToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCache(id, false);
|
||||||
|
return new Tuple3<>(false, true, Str.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -58,7 +58,7 @@ public class NotificationsFragment extends Fragment implements MessageAdapterTou
|
|||||||
|
|
||||||
public void updateProState()
|
public void updateProState()
|
||||||
{
|
{
|
||||||
if (adView != null) adView.setVisibility(IABService.inst().getPurchaseCached(IABService.IAB_PRO_MODE) != null ? View.GONE : View.VISIBLE);
|
if (adView != null) adView.setVisibility(IABService.inst().getPurchaseCachedSimple(IABService.IAB_PRO_MODE) ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -366,11 +366,11 @@ public class SettingsFragment extends Fragment implements MusicPickerListener
|
|||||||
|
|
||||||
public void updateProState()
|
public void updateProState()
|
||||||
{
|
{
|
||||||
Purchase p = IABService.inst().getPurchaseCached(IABService.IAB_PRO_MODE);
|
boolean pmode = IABService.inst().getPurchaseCachedSimple(IABService.IAB_PRO_MODE);
|
||||||
|
|
||||||
if (prefUpgradeAccount != null) prefUpgradeAccount.setVisibility( p != null ? View.GONE : View.VISIBLE);
|
if (prefUpgradeAccount != null) prefUpgradeAccount.setVisibility( pmode ? View.GONE : View.VISIBLE);
|
||||||
if (prefUpgradeAccount_info != null) prefUpgradeAccount_info.setVisibility(p != null ? View.GONE : View.VISIBLE);
|
if (prefUpgradeAccount_info != null) prefUpgradeAccount_info.setVisibility(pmode ? View.GONE : View.VISIBLE);
|
||||||
if (prefUpgradeAccount_msg != null) prefUpgradeAccount_msg.setVisibility( p != null ? View.VISIBLE : View.GONE );
|
if (prefUpgradeAccount_msg != null) prefUpgradeAccount_msg.setVisibility( pmode ? View.VISIBLE : View.GONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCacheSizeIndex(int value)
|
private int getCacheSizeIndex(int value)
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
#Fri Nov 23 19:40:03 CET 2018
|
#Fri Dec 14 19:31:54 CET 2018
|
||||||
VERSION_NAME=1.2.0
|
VERSION_NAME=1.5.0
|
||||||
VERSION_CODE=16
|
VERSION_CODE=19
|
||||||
|
Reference in New Issue
Block a user