Admob version update + checkout library instead of old billing
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import com.google.android.gms.ads.AdListener;
|
||||
import com.google.android.gms.ads.AdRequest;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class AdView extends FrameLayout {
|
||||
|
||||
@Nullable
|
||||
private com.google.android.gms.ads.AdView admobView;
|
||||
|
||||
public AdView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public AdView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public AdView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (admobView != null) {
|
||||
admobView.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (admobView != null) {
|
||||
admobView.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (admobView != null) {
|
||||
admobView.resume();
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (admobView != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setVisibility(VISIBLE);
|
||||
|
||||
LayoutInflater.from(getContext()).inflate(R.layout.admob, this);
|
||||
admobView = (com.google.android.gms.ads.AdView) findViewById(R.id.admob);
|
||||
admobView.setVisibility(View.VISIBLE);
|
||||
admobView.setAdListener(new AdListener() {
|
||||
@Override
|
||||
public void onAdFailedToLoad(int errorCode) {
|
||||
hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdLoaded() {
|
||||
}
|
||||
});
|
||||
|
||||
final AdRequest.Builder b = new AdRequest.Builder();
|
||||
b.addTestDevice(AdRequest.DEVICE_ID_EMULATOR);
|
||||
if (BuildConfig.DEBUG) {
|
||||
// LG Nexus 5
|
||||
b.addTestDevice("B80E676D60CE6FDBE1B84A55464E3FE1");
|
||||
}
|
||||
admobView.loadAd(b.build());
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if(admobView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setVisibility(GONE);
|
||||
|
||||
admobView.setVisibility(View.GONE);
|
||||
admobView.pause();
|
||||
admobView.destroy();
|
||||
admobView = null;
|
||||
}
|
||||
}
|
@@ -32,13 +32,9 @@ import android.preference.PreferenceManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
|
||||
import jscl.math.Generic;
|
||||
|
||||
import org.solovyev.android.Android;
|
||||
import org.solovyev.android.App;
|
||||
import org.solovyev.android.calculator.about.CalculatorAboutActivity;
|
||||
import org.solovyev.android.calculator.function.FunctionEditDialogFragment;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
|
||||
@@ -46,14 +42,13 @@ import org.solovyev.android.calculator.math.edit.*;
|
||||
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
||||
import org.solovyev.android.calculator.preferences.CalculatorPreferencesActivity;
|
||||
import org.solovyev.android.calculator.preferences.PreferencesActivity;
|
||||
import org.solovyev.common.msg.Message;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
import org.solovyev.common.text.Strings;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -81,7 +76,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
|
||||
}
|
||||
|
||||
public static void showSettings(@Nonnull final Context context, boolean detached) {
|
||||
final Intent intent = new Intent(context, CalculatorPreferencesActivity.class);
|
||||
final Intent intent = new Intent(context, PreferencesActivity.class);
|
||||
Android.addIntentFlags(intent, detached, context);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
@@ -29,16 +29,10 @@ import android.graphics.Typeface;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import net.robotmedia.billing.BillingController;
|
||||
import net.robotmedia.billing.helper.DefaultBillingObserver;
|
||||
import net.robotmedia.billing.model.BillingDB;
|
||||
import org.acra.ACRA;
|
||||
import org.acra.ReportingInteractionMode;
|
||||
import org.acra.annotation.ReportsCrashes;
|
||||
import org.solovyev.android.Android;
|
||||
import org.solovyev.android.App;
|
||||
import org.solovyev.android.ServiceLocator;
|
||||
import org.solovyev.android.ads.AdsController;
|
||||
import org.solovyev.android.calculator.history.AndroidCalculatorHistory;
|
||||
import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
|
||||
import org.solovyev.android.calculator.onscreen.CalculatorOnscreenStartActivity;
|
||||
@@ -46,12 +40,15 @@ import org.solovyev.android.calculator.plot.AndroidCalculatorPlotter;
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotterImpl;
|
||||
import org.solovyev.android.calculator.view.EditorTextProcessor;
|
||||
import org.solovyev.android.calculator.wizard.CalculatorWizards;
|
||||
import org.solovyev.android.checkout.*;
|
||||
import org.solovyev.android.wizard.Wizards;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@@ -74,12 +71,14 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
@Nonnull
|
||||
static final String MAIL = "se.solovyev@gmail.com";
|
||||
|
||||
private static final String TAG = "Calculator++ Application";
|
||||
|
||||
public static final String AD_FREE_PRODUCT_ID = "ad_free";
|
||||
public static final String AD_FREE_P_KEY = "org.solovyev.android.calculator_ad_free";
|
||||
|
||||
public static final String ADMOB_USER_ID = "a14f02cf9c80cbc";
|
||||
public static final String ADMOB = "ca-app-pub-2228934497384784/2916398892";
|
||||
|
||||
@Nonnull
|
||||
private static CalculatorApplication instance;
|
||||
@@ -109,6 +108,25 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
@Nonnull
|
||||
private Typeface typeFace;
|
||||
|
||||
@Nonnull
|
||||
private final Billing billing = new Billing(this, new Billing.DefaultConfiguration() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getPublicKey() {
|
||||
return CalculatorSecurity.getPK();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Inventory getFallbackInventory(@Nonnull Checkout checkout, @Nonnull Executor onLoadExecutor) {
|
||||
if (RobotmediaDatabase.exists(billing.getContext())) {
|
||||
return new RobotmediaInventory(checkout, onLoadExecutor);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
@@ -137,7 +155,9 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
ACRA.init(this);
|
||||
if (!BuildConfig.DEBUG) {
|
||||
ACRA.init(this);
|
||||
}
|
||||
|
||||
if (!App.isInitialized()) {
|
||||
App.init(this);
|
||||
@@ -178,32 +198,11 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
|
||||
Locator.getInstance().getCalculator().init();
|
||||
|
||||
BillingDB.init(CalculatorApplication.this);
|
||||
billing.connect();
|
||||
|
||||
if (withAds) {
|
||||
AdsController.getInstance().init(this, ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() {
|
||||
|
||||
@Override
|
||||
public byte[] getObfuscationSalt() {
|
||||
return new byte[]{81, -114, 32, -127, -32, -104, -40, -15, -47, 57, -13, -41, -33, 67, -114, 7, -11, 53, 126, 82};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKey() {
|
||||
return CalculatorSecurity.getPK();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BillingController.registerObserver(new DefaultBillingObserver(this, null));
|
||||
|
||||
// init billing controller
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
BillingController.checkBillingSupported(CalculatorApplication.this);
|
||||
AdsController.getInstance().isAdFree(CalculatorApplication.this);
|
||||
|
||||
try {
|
||||
// prepare engine
|
||||
Locator.getInstance().getEngine().getMathEngine0().evaluate("1+1");
|
||||
@@ -261,6 +260,11 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
return typeFace;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Billing getBilling() {
|
||||
return billing;
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
|
@@ -23,17 +23,17 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.ads.AdView;
|
||||
import org.solovyev.android.checkout.*;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.solovyev.android.ads.AdsController;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@@ -42,6 +42,8 @@ import org.solovyev.android.ads.AdsController;
|
||||
*/
|
||||
public class CalculatorFragmentHelperImpl extends AbstractCalculatorHelper implements CalculatorFragmentHelper {
|
||||
|
||||
private ActivityCheckout checkout;
|
||||
|
||||
@Nullable
|
||||
private AdView adView;
|
||||
|
||||
@@ -51,6 +53,9 @@ public class CalculatorFragmentHelperImpl extends AbstractCalculatorHelper imple
|
||||
|
||||
private boolean listenersOnCreate = true;
|
||||
|
||||
@Nullable
|
||||
private Boolean adFree = null;
|
||||
|
||||
public CalculatorFragmentHelperImpl(int layoutId) {
|
||||
this.layoutId = layoutId;
|
||||
}
|
||||
@@ -84,26 +89,57 @@ public class CalculatorFragmentHelperImpl extends AbstractCalculatorHelper imple
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nonnull Fragment fragment) {
|
||||
super.onCreate(fragment.getActivity());
|
||||
final FragmentActivity activity = fragment.getActivity();
|
||||
super.onCreate(activity);
|
||||
checkout = Checkout.forActivity(activity, CalculatorApplication.getInstance().getBilling(), Products.create().add(ProductTypes.IN_APP, asList("ad_free")));
|
||||
|
||||
if (listenersOnCreate) {
|
||||
if (fragment instanceof CalculatorEventListener) {
|
||||
Locator.getInstance().getCalculator().addCalculatorEventListener((CalculatorEventListener) fragment);
|
||||
}
|
||||
}
|
||||
|
||||
checkout.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(@Nonnull Fragment fragment) {
|
||||
if (adView != null) {
|
||||
adView.resume();
|
||||
}
|
||||
if (!listenersOnCreate) {
|
||||
if (fragment instanceof CalculatorEventListener) {
|
||||
Locator.getInstance().getCalculator().addCalculatorEventListener((CalculatorEventListener) fragment);
|
||||
}
|
||||
}
|
||||
|
||||
checkout.loadInventory().whenLoaded(new Inventory.Listener() {
|
||||
@Override
|
||||
public void onLoaded(@Nonnull Inventory.Products products) {
|
||||
adFree = products.get(ProductTypes.IN_APP).isPurchased("ad_free");
|
||||
updateAdViewState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateAdViewState() {
|
||||
if(adFree == null || adView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (adFree) {
|
||||
adView.hide();
|
||||
} else {
|
||||
adView.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(@Nonnull Fragment fragment) {
|
||||
adFree = null;
|
||||
if (adView != null) {
|
||||
adView.pause();
|
||||
}
|
||||
if (!listenersOnCreate) {
|
||||
if (fragment instanceof CalculatorEventListener) {
|
||||
Locator.getInstance().getCalculator().removeCalculatorEventListener((CalculatorEventListener) fragment);
|
||||
@@ -113,16 +149,15 @@ public class CalculatorFragmentHelperImpl extends AbstractCalculatorHelper imple
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@Nonnull Fragment fragment, @Nonnull View root) {
|
||||
final ViewGroup adParentView = (ViewGroup) root.findViewById(R.id.ad_parent_view);
|
||||
adView = (AdView) root.findViewById(R.id.ad);
|
||||
final ViewGroup mainFragmentLayout = (ViewGroup) root.findViewById(R.id.main_fragment_layout);
|
||||
|
||||
if (fragment instanceof CalculatorDisplayFragment || fragment instanceof CalculatorEditorFragment || fragment instanceof CalculatorKeyboardFragment) {
|
||||
// no ads in those fragments
|
||||
} else {
|
||||
if (adParentView != null) {
|
||||
adView = AdsController.getInstance().inflateAd(fragment.getActivity(), adParentView, R.id.ad_parent_view);
|
||||
if (adView != null) {
|
||||
updateAdViewState();
|
||||
} else if (mainFragmentLayout != null) {
|
||||
adView = AdsController.getInstance().inflateAd(fragment.getActivity(), mainFragmentLayout, R.id.main_fragment_layout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +170,10 @@ public class CalculatorFragmentHelperImpl extends AbstractCalculatorHelper imple
|
||||
|
||||
@Override
|
||||
public void onDestroy(@Nonnull Fragment fragment) {
|
||||
super.onDestroy(fragment.getActivity());
|
||||
if (adView != null) {
|
||||
adView.destroy();
|
||||
adView = null;
|
||||
}
|
||||
|
||||
if (listenersOnCreate) {
|
||||
if (fragment instanceof CalculatorEventListener) {
|
||||
@@ -143,9 +181,9 @@ public class CalculatorFragmentHelperImpl extends AbstractCalculatorHelper imple
|
||||
}
|
||||
}
|
||||
|
||||
if (this.adView != null) {
|
||||
this.adView.destroy();
|
||||
}
|
||||
checkout.stop();
|
||||
|
||||
super.onDestroy(fragment.getActivity());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@@ -417,7 +417,7 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
preferences(R.id.menu_plot_settings) {
|
||||
@Override
|
||||
public void onClick(@Nonnull MenuItem data, @Nonnull Context context) {
|
||||
context.startActivity(new Intent(context, CalculatorPlotPreferenceActivity.class));
|
||||
context.startActivity(new Intent(context, PlotPreferenceActivity.class));
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -23,17 +23,10 @@
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockPreferenceActivity;
|
||||
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.preferences.BasePreferencesActivity;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/4/12
|
||||
* Time: 9:01 PM
|
||||
*/
|
||||
public class CalculatorPlotPreferenceActivity extends SherlockPreferenceActivity {
|
||||
public class PlotPreferenceActivity extends BasePreferencesActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
@@ -0,0 +1,92 @@
|
||||
package org.solovyev.android.calculator.preferences;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import com.actionbarsherlock.app.SherlockPreferenceActivity;
|
||||
import org.solovyev.android.calculator.AdView;
|
||||
import org.solovyev.android.calculator.CalculatorApplication;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.checkout.*;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public abstract class BasePreferencesActivity extends SherlockPreferenceActivity {
|
||||
|
||||
private final ActivityCheckout checkout = Checkout.forActivity(this, CalculatorApplication.getInstance().getBilling(), Products.create().add(ProductTypes.IN_APP, asList("ad_free")));
|
||||
private Inventory inventory;
|
||||
private AdView adView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
checkout.start();
|
||||
inventory = checkout.loadInventory();
|
||||
}
|
||||
|
||||
|
||||
private class InventoryListener implements Inventory.Listener {
|
||||
@Override
|
||||
public void onLoaded(@Nonnull Inventory.Products products) {
|
||||
final Inventory.Product product = products.get(ProductTypes.IN_APP);
|
||||
final boolean adFree = product.isPurchased("ad_free");
|
||||
onShowAd(!adFree);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onShowAd(boolean show) {
|
||||
if (show) {
|
||||
if (adView != null) {
|
||||
return;
|
||||
}
|
||||
adView = (AdView) LayoutInflater.from(this).inflate(R.layout.ad, null);
|
||||
adView.show();
|
||||
getListView().addHeaderView(adView);
|
||||
} else {
|
||||
if (adView == null) {
|
||||
return;
|
||||
}
|
||||
getListView().removeHeaderView(adView);
|
||||
adView.hide();
|
||||
adView = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (checkout.onActivityResult(requestCode, resultCode, data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (adView != null) {
|
||||
adView.resume();
|
||||
}
|
||||
inventory.whenLoaded(new InventoryListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
if (adView != null) {
|
||||
adView.pause();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (adView != null) {
|
||||
adView.destroy();
|
||||
}
|
||||
checkout.stop();
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 serso aka se.solovyev
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Contact details
|
||||
*
|
||||
* Email: se.solovyev@gmail.com
|
||||
* Site: http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.preferences;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
import com.actionbarsherlock.app.SherlockPreferenceActivity;
|
||||
import net.robotmedia.billing.BillingController;
|
||||
import net.robotmedia.billing.IBillingObserver;
|
||||
import net.robotmedia.billing.ResponseCode;
|
||||
import net.robotmedia.billing.helper.AbstractBillingObserver;
|
||||
import net.robotmedia.billing.model.Transaction;
|
||||
import org.solovyev.android.Activities;
|
||||
import org.solovyev.android.App;
|
||||
import org.solovyev.android.ads.AdsController;
|
||||
import org.solovyev.android.calculator.*;
|
||||
import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
|
||||
import org.solovyev.android.calculator.wizard.CalculatorWizards;
|
||||
import org.solovyev.android.msg.AndroidMessage;
|
||||
import org.solovyev.android.view.VibratorContainer;
|
||||
import org.solovyev.android.wizard.WizardUi;
|
||||
import org.solovyev.common.msg.Message;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static org.solovyev.android.calculator.wizard.CalculatorWizards.DEFAULT_WIZARD_FLOW;
|
||||
import static org.solovyev.android.wizard.WizardUi.startWizard;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 7/16/11
|
||||
* Time: 6:37 PM
|
||||
*/
|
||||
public class CalculatorPreferencesActivity extends SherlockPreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener, IBillingObserver {
|
||||
|
||||
public static final String PREFERENCE_CLEAR_BILLING_INFO = "clear_billing_info";
|
||||
public static final String PREFERENCE_RESTART_WIZARD = "restart_wizard";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//noinspection deprecation
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
//noinspection deprecation
|
||||
addPreferencesFromResource(R.xml.preferences_calculations);
|
||||
addPreferencesFromResource(R.xml.preferences_appearance);
|
||||
addPreferencesFromResource(R.xml.preferences_plot);
|
||||
addPreferencesFromResource(R.xml.preferences_other);
|
||||
addPreferencesFromResource(R.xml.preferences_onscreen);
|
||||
|
||||
final Preference restartWizardPreference = findPreference(PREFERENCE_RESTART_WIZARD);
|
||||
restartWizardPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
startWizard(CalculatorApplication.getInstance().getWizards(), DEFAULT_WIZARD_FLOW, CalculatorPreferencesActivity.this);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
final Preference adFreePreference = findPreference(CalculatorApplication.AD_FREE_P_KEY);
|
||||
adFreePreference.setEnabled(false);
|
||||
|
||||
// observer must be set before net.robotmedia.billing.BillingController.checkBillingSupported()
|
||||
BillingController.registerObserver(this);
|
||||
|
||||
BillingController.checkBillingSupported(CalculatorPreferencesActivity.this);
|
||||
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
onSharedPreferenceChanged(preferences, AndroidCalculatorEngine.Preferences.roundResult.getKey());
|
||||
onSharedPreferenceChanged(preferences, VibratorContainer.Preferences.hapticFeedbackEnabled.getKey());
|
||||
|
||||
final Preference clearBillingInfoPreference = findPreference(PREFERENCE_CLEAR_BILLING_INFO);
|
||||
if (clearBillingInfoPreference != null) {
|
||||
clearBillingInfoPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
|
||||
Toast.makeText(CalculatorPreferencesActivity.this, R.string.c_calc_clearing, Toast.LENGTH_SHORT).show();
|
||||
|
||||
removeBillingInformation(CalculatorPreferencesActivity.this, PreferenceManager.getDefaultSharedPreferences(CalculatorPreferencesActivity.this));
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeBillingInformation(@Nonnull Context context, @Nonnull SharedPreferences preferences) {
|
||||
final SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putBoolean(AbstractBillingObserver.KEY_TRANSACTIONS_RESTORED, false);
|
||||
editor.commit();
|
||||
|
||||
BillingController.dropBillingData(context);
|
||||
}
|
||||
|
||||
private void setAdFreeAction() {
|
||||
final Preference adFreePreference = findPreference(CalculatorApplication.AD_FREE_P_KEY);
|
||||
|
||||
if (!AdsController.getInstance().isAdFree(this)) {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Ad free is not purchased - enable preference!");
|
||||
|
||||
adFreePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
final Context context = CalculatorPreferencesActivity.this;
|
||||
context.startActivity(new Intent(context, CalculatorPurchaseDialogActivity.class));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
adFreePreference.setEnabled(true);
|
||||
} else {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Ad free is not purchased - disable preference!");
|
||||
adFreePreference.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
BillingController.unregisterObserver(this);
|
||||
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (AndroidCalculatorEngine.Preferences.roundResult.getKey().equals(key)) {
|
||||
findPreference(AndroidCalculatorEngine.Preferences.precision.getKey()).setEnabled(preferences.getBoolean(key, AndroidCalculatorEngine.Preferences.roundResult.getDefaultValue()));
|
||||
} else if (VibratorContainer.Preferences.hapticFeedbackEnabled.getKey().equals(key)) {
|
||||
findPreference(VibratorContainer.Preferences.hapticFeedbackDuration.getKey()).setEnabled(VibratorContainer.Preferences.hapticFeedbackEnabled.getPreference(preferences));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckBillingSupportedResponse(boolean supported) {
|
||||
if (supported) {
|
||||
setAdFreeAction();
|
||||
} else {
|
||||
final Preference adFreePreference = findPreference(CalculatorApplication.AD_FREE_P_KEY);
|
||||
adFreePreference.setEnabled(false);
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Billing is not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPurchaseIntentOK(@Nonnull String productId, @Nonnull PendingIntent purchaseIntent) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPurchaseIntentFailure(@Nonnull String productId, @Nonnull ResponseCode responseCode) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPurchaseStateChanged(@Nonnull String itemId, @Nonnull Transaction.PurchaseState state) {
|
||||
if (CalculatorApplication.AD_FREE_PRODUCT_ID.equals(itemId)) {
|
||||
final Preference adFreePreference = findPreference(CalculatorApplication.AD_FREE_P_KEY);
|
||||
if (adFreePreference != null) {
|
||||
switch (state) {
|
||||
case PURCHASED:
|
||||
adFreePreference.setEnabled(false);
|
||||
// restart activity to disable ads
|
||||
Activities.restartActivity(this);
|
||||
break;
|
||||
case CANCELLED:
|
||||
adFreePreference.setEnabled(true);
|
||||
break;
|
||||
case REFUNDED:
|
||||
adFreePreference.setEnabled(true);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPurchaseResponse(@Nonnull String itemId, @Nonnull ResponseCode response) {
|
||||
final Preference adFreePreference = findPreference(CalculatorApplication.AD_FREE_P_KEY);
|
||||
if (adFreePreference != null) {
|
||||
if (response == ResponseCode.RESULT_OK) {
|
||||
adFreePreference.setEnabled(false);
|
||||
|
||||
final Message message = new AndroidMessage(R.string.cpp_purchase_thank_you_text, MessageType.info, App.getApplication());
|
||||
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_message_dialog, MessageDialogData.newInstance(message, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionsRestored() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onErrorRestoreTransactions(@Nonnull ResponseCode responseCode) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
@@ -23,28 +23,22 @@
|
||||
package org.solovyev.android.calculator.preferences;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
|
||||
import net.robotmedia.billing.BillingController;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.solovyev.android.ads.AdsController;
|
||||
import org.solovyev.android.calculator.CalculatorApplication;
|
||||
import org.solovyev.android.calculator.CalculatorFragment;
|
||||
import org.solovyev.android.calculator.CalculatorFragmentType;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.checkout.*;
|
||||
import org.solovyev.android.fragments.FragmentUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 1/20/13
|
||||
@@ -52,6 +46,22 @@ import org.solovyev.android.fragments.FragmentUtils;
|
||||
*/
|
||||
public class CalculatorPurchaseDialogActivity extends SherlockFragmentActivity {
|
||||
|
||||
@Nonnull
|
||||
private final ActivityCheckout checkout = Checkout.forActivity(this, CalculatorApplication.getInstance().getBilling(), Products.create().add("ad_free"));
|
||||
|
||||
@Nonnull
|
||||
private final RequestListener<Purchase> purchaseListener = new RequestListener<Purchase>() {
|
||||
@Override
|
||||
public void onSuccess(@Nonnull Purchase purchase) {
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int i, @Nonnull Exception e) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -59,6 +69,9 @@ public class CalculatorPurchaseDialogActivity extends SherlockFragmentActivity {
|
||||
setContentView(R.layout.cpp_dialog);
|
||||
|
||||
FragmentUtils.createFragment(this, PurchaseDialogFragment.class, R.id.dialog_layout, "purchase-dialog");
|
||||
|
||||
checkout.start();
|
||||
checkout.createPurchaseFlow(purchaseListener);
|
||||
}
|
||||
|
||||
public static class PurchaseDialogFragment extends CalculatorFragment {
|
||||
@@ -75,36 +88,35 @@ public class CalculatorPurchaseDialogActivity extends SherlockFragmentActivity {
|
||||
root.findViewById(R.id.cpp_continue_button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
final Activity activity = getActivity();
|
||||
|
||||
if (activity != null) {
|
||||
// check billing availability
|
||||
if (BillingController.checkBillingSupported(activity) != BillingController.BillingStatus.SUPPORTED) {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Billing is not supported - warn user!");
|
||||
// warn about not supported billing
|
||||
new AlertDialog.Builder(activity).setTitle(R.string.c_error).setMessage(R.string.c_billing_error).create().show();
|
||||
} else {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Billing is supported - continue!");
|
||||
if (!AdsController.getInstance().isAdFree(activity)) {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Item not purchased - try to purchase!");
|
||||
|
||||
// not purchased => purchasing
|
||||
Toast.makeText(activity, R.string.c_calc_purchasing, Toast.LENGTH_SHORT).show();
|
||||
|
||||
// show purchase window for user
|
||||
BillingController.requestPurchase(activity, CalculatorApplication.AD_FREE_PRODUCT_ID, true);
|
||||
} else {
|
||||
// and show message to user
|
||||
Toast.makeText(activity, R.string.c_calc_already_purchased, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
activity.finish();
|
||||
((CalculatorPurchaseDialogActivity) activity).purchase();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void purchase() {
|
||||
checkout.whenReady(new Checkout.ListenerAdapter() {
|
||||
@Override
|
||||
public void onReady(@Nonnull BillingRequests requests) {
|
||||
requests.purchase(ProductTypes.IN_APP, "ad_free", null, checkout.getPurchaseFlow());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
checkout.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
checkout.destroyPurchaseFlow();
|
||||
checkout.stop();
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2013 serso aka se.solovyev
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Contact details
|
||||
*
|
||||
* Email: se.solovyev@gmail.com
|
||||
* Site: http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.preferences;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.SparseArray;
|
||||
import org.solovyev.android.calculator.CalculatorApplication;
|
||||
import org.solovyev.android.calculator.R;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static org.solovyev.android.calculator.CalculatorApplication.AD_FREE_P_KEY;
|
||||
import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.precision;
|
||||
import static org.solovyev.android.calculator.model.AndroidCalculatorEngine.Preferences.roundResult;
|
||||
import static org.solovyev.android.calculator.wizard.CalculatorWizards.DEFAULT_WIZARD_FLOW;
|
||||
import static org.solovyev.android.view.VibratorContainer.Preferences.hapticFeedbackDuration;
|
||||
import static org.solovyev.android.view.VibratorContainer.Preferences.hapticFeedbackEnabled;
|
||||
import static org.solovyev.android.wizard.WizardUi.startWizard;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PreferencesActivity extends BasePreferencesActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@Nonnull
|
||||
private static final SparseArray<String> preferences = new SparseArray<String>();
|
||||
|
||||
static {
|
||||
preferences.append(R.xml.preferences, "screen-main");
|
||||
preferences.append(R.xml.preferences_calculations, "screen-calculations");
|
||||
preferences.append(R.xml.preferences_appearance, "screen-appearance");
|
||||
preferences.append(R.xml.preferences_plot, "screen-plot");
|
||||
preferences.append(R.xml.preferences_other, "screen-other");
|
||||
preferences.append(R.xml.preferences_onscreen, "screen-onscreen");
|
||||
}
|
||||
|
||||
private Preference adFreePreference;
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
final int preference = intent.getIntExtra("preference", R.xml.preferences);
|
||||
final String title = intent.getStringExtra("preference-title");
|
||||
setPreference(preference, preferences.get(preference));
|
||||
if (preference == R.xml.preferences) {
|
||||
for (int i = 0; i < preferences.size(); i++) {
|
||||
final int xml = preferences.keyAt(i);
|
||||
final String name = preferences.valueAt(i);
|
||||
setPreferenceIntent(xml, name);
|
||||
}
|
||||
final Preference restartWizardPreference = findPreference("restart_wizard");
|
||||
restartWizardPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
startWizard(CalculatorApplication.getInstance().getWizards(), DEFAULT_WIZARD_FLOW, PreferencesActivity.this);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
adFreePreference = findPreference(AD_FREE_P_KEY);
|
||||
adFreePreference.setEnabled(false);
|
||||
adFreePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
startActivity(new Intent(getApplicationContext(), CalculatorPurchaseDialogActivity.class));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (title != null) {
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
onSharedPreferenceChanged(preferences, roundResult.getKey());
|
||||
onSharedPreferenceChanged(preferences, hapticFeedbackEnabled.getKey());
|
||||
}
|
||||
|
||||
private void setPreference(int xml, @Nonnull String name) {
|
||||
addPreferencesFromResource(xml);
|
||||
}
|
||||
|
||||
private void setPreferenceIntent(int xml, @Nonnull String name) {
|
||||
final Preference preference = findPreference(name);
|
||||
if (preference != null) {
|
||||
final Intent intent = new Intent(getApplicationContext(), PreferencesActivity.class);
|
||||
intent.putExtra("preference", xml);
|
||||
intent.putExtra("preference-title", preference.getTitle());
|
||||
preference.setIntent(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (roundResult.getKey().equals(key)) {
|
||||
final Preference preference = findPreference(precision.getKey());
|
||||
if (preference != null) {
|
||||
preference.setEnabled(preferences.getBoolean(key, roundResult.getDefaultValue()));
|
||||
}
|
||||
} else if (hapticFeedbackEnabled.getKey().equals(key)) {
|
||||
final Preference preference = findPreference(hapticFeedbackDuration.getKey());
|
||||
if (preference != null) {
|
||||
preference.setEnabled(hapticFeedbackEnabled.getPreference(preferences));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShowAd(boolean show) {
|
||||
super.onShowAd(show);
|
||||
if (adFreePreference != null) {
|
||||
adFreePreference.setEnabled(show);
|
||||
}
|
||||
}
|
||||
}
|
@@ -25,7 +25,7 @@ package org.solovyev.android.calculator.wizard;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import org.solovyev.android.App;
|
||||
import org.solovyev.android.calculator.App;
|
||||
import org.solovyev.android.Views;
|
||||
import org.solovyev.android.calculator.CalculatorPreferences;
|
||||
import org.solovyev.android.calculator.R;
|
||||
|
Reference in New Issue
Block a user