ads + billing + fix for MiOne devices' tabs
This commit is contained in:
parent
d26a084e50
commit
0d6656f52c
@ -144,7 +144,7 @@
|
|||||||
так как приложение стало довольно большим и сложным.\n
|
так как приложение стало довольно большим и сложным.\n
|
||||||
Если вы хотите поддержать проект и избавиться от рекламы, вы можете купить специальную опцию в настройках приложения,\n
|
Если вы хотите поддержать проект и избавиться от рекламы, вы можете купить специальную опцию в настройках приложения,\n
|
||||||
если вы не хотите или не можете этого сделать - вы всё равно можете отблагодарить автора программы по почте: se.solovyev@gmail.com, высоко оценить приложение на андроид.маркете\n
|
если вы не хотите или не можете этого сделать - вы всё равно можете отблагодарить автора программы по почте: se.solovyev@gmail.com, высоко оценить приложение на андроид.маркете\n
|
||||||
или помочь в переводе приложения на свой роной язык.
|
или помочь в переводе приложения на свой родной язык.
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -10,6 +10,8 @@ import android.app.Activity;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -35,6 +37,7 @@ public final class AndroidUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void centerAndWrapTabsFor(@NotNull TabHost tabHost) {
|
public static void centerAndWrapTabsFor(@NotNull TabHost tabHost) {
|
||||||
|
if (allowCenterAndWrappingTabs()) {
|
||||||
int tabCount = tabHost.getTabWidget().getTabCount();
|
int tabCount = tabHost.getTabWidget().getTabCount();
|
||||||
for (int i = 0; i < tabCount; i++) {
|
for (int i = 0; i < tabCount; i++) {
|
||||||
final View view = tabHost.getTabWidget().getChildTabViewAt(i);
|
final View view = tabHost.getTabWidget().getChildTabViewAt(i);
|
||||||
@ -61,6 +64,23 @@ public final class AndroidUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean allowCenterAndWrappingTabs() {
|
||||||
|
boolean result = true;
|
||||||
|
|
||||||
|
String deviceModel = Build.MODEL;
|
||||||
|
if (deviceModel != null) {
|
||||||
|
deviceModel = deviceModel.toUpperCase();
|
||||||
|
if (deviceModel.contains("M1") || deviceModel.contains("MIONE") || deviceModel.contains("MI-ONE")) {
|
||||||
|
// Xiaomi Phone MiOne => do not allow to center and wrap tabs
|
||||||
|
result = false;
|
||||||
|
Log.i(AndroidUtils.class.getName(), "Device model doesn't support center and wrap of tabs: " + Build.MODEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static void addTab(@NotNull Context context,
|
public static void addTab(@NotNull Context context,
|
||||||
@NotNull TabHost tabHost,
|
@NotNull TabHost tabHost,
|
||||||
|
@ -26,6 +26,8 @@ import android.widget.TextView;
|
|||||||
import com.google.ads.AdView;
|
import com.google.ads.AdView;
|
||||||
import jscl.AngleUnit;
|
import jscl.AngleUnit;
|
||||||
import jscl.NumeralBase;
|
import jscl.NumeralBase;
|
||||||
|
import net.robotmedia.billing.BillingController;
|
||||||
|
import net.robotmedia.billing.IBillingObserver;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.AndroidUtils;
|
import org.solovyev.android.AndroidUtils;
|
||||||
@ -53,6 +55,9 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
|||||||
|
|
||||||
private static final int HVGA_WIDTH_PIXELS = 320;
|
private static final int HVGA_WIDTH_PIXELS = 320;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private IBillingObserver billingObserver;
|
||||||
|
|
||||||
public static class Preferences {
|
public static class Preferences {
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final String APP_VERSION_P_KEY = "application.version";
|
private static final String APP_VERSION_P_KEY = "application.version";
|
||||||
@ -377,6 +382,10 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
|||||||
private synchronized void firstTimeInit(@NotNull SharedPreferences preferences) {
|
private synchronized void firstTimeInit(@NotNull SharedPreferences preferences) {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
|
|
||||||
|
billingObserver = new CalculatorBillingObserver(this);
|
||||||
|
BillingController.registerObserver(billingObserver);
|
||||||
|
BillingController.checkBillingSupported(this);
|
||||||
|
|
||||||
final int savedVersion = Preferences.appVersion.getPreference(preferences);
|
final int savedVersion = Preferences.appVersion.getPreference(preferences);
|
||||||
|
|
||||||
final int appVersion = AndroidUtils.getAppVersionCode(this, CalculatorActivity.class.getPackage().getName());
|
final int appVersion = AndroidUtils.getAppVersionCode(this, CalculatorActivity.class.getPackage().getName());
|
||||||
@ -627,6 +636,11 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
|||||||
if ( adView != null ) {
|
if ( adView != null ) {
|
||||||
adView.destroy();
|
adView.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (billingObserver != null) {
|
||||||
|
BillingController.unregisterObserver(billingObserver);
|
||||||
|
}
|
||||||
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,20 +36,24 @@ public class CalculatorApplication extends android.app.Application {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAdFreeApprox(@NotNull Context context) {
|
private static boolean isAdFreePurchased(@NotNull Context context) {
|
||||||
return BillingController.isPurchased(context.getApplicationContext(), AD_FREE_PRODUCT_ID);
|
return BillingController.isPurchased(context.getApplicationContext(), AD_FREE_PRODUCT_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean transactionsRestored = false;
|
||||||
|
|
||||||
public static boolean isAdFree(@NotNull Context context) {
|
public static boolean isAdFree(@NotNull Context context) {
|
||||||
// check if user already bought this product
|
// check if user already bought this product
|
||||||
boolean purchased = isAdFreeApprox(context);
|
boolean purchased = isAdFreePurchased(context);
|
||||||
if (!purchased) {
|
if (!purchased && !transactionsRestored) {
|
||||||
// we must to restore all transactions done by user to guarantee that product was purchased or not
|
// we must to restore all transactions done by user to guarantee that product was purchased or not
|
||||||
BillingController.restoreTransactions(context);
|
BillingController.restoreTransactions(context);
|
||||||
|
|
||||||
|
transactionsRestored = true;
|
||||||
|
|
||||||
// todo serso: may be call net.robotmedia.billing.BillingController.restoreTransactions() always before first check and get rid of second check
|
// todo serso: may be call net.robotmedia.billing.BillingController.restoreTransactions() always before first check and get rid of second check
|
||||||
// check the billing one more time
|
// check the billing one more time
|
||||||
purchased = isAdFreeApprox(context);
|
purchased = isAdFreePurchased(context);
|
||||||
}
|
}
|
||||||
return purchased;
|
return purchased;
|
||||||
}
|
}
|
||||||
@ -62,9 +66,8 @@ public class CalculatorApplication extends android.app.Application {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static AdView inflateAd(@NotNull Activity activity, int parentViewId) {
|
public static AdView inflateAd(@NotNull Activity activity, int parentViewId) {
|
||||||
AdView result = null;
|
AdView result = null;
|
||||||
if ( !isAdFreeApprox(activity) ) {
|
if ( !isAdFree(activity) ) {
|
||||||
Log.d(activity.getClass().getName(), "Application is not ad free - inflating ad!");
|
Log.d(activity.getClass().getName(), "Application is not ad free - inflating ad!");
|
||||||
//final List<String> keywords = Arrays.asList("math", "mathematics", "finance", "physics", "dynamics");
|
|
||||||
final List<String> keywords = Collections.emptyList();
|
final List<String> keywords = Collections.emptyList();
|
||||||
result = AndroidUtils.createAndInflateAdView(activity, ADMOB_USER_ID, parentViewId, keywords);
|
result = AndroidUtils.createAndInflateAdView(activity, ADMOB_USER_ID, parentViewId, keywords);
|
||||||
} else {
|
} else {
|
||||||
@ -78,6 +81,7 @@ public class CalculatorApplication extends android.app.Application {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
|
//BillingController.setDebug(true);
|
||||||
BillingController.setConfiguration(new BillingController.IConfiguration() {
|
BillingController.setConfiguration(new BillingController.IConfiguration() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -90,7 +94,5 @@ public class CalculatorApplication extends android.app.Application {
|
|||||||
return CalculatorSecurity.getPK();
|
return CalculatorSecurity.getPK();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
BillingController.checkBillingSupported(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2012. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
* or visit http://se.solovyev.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import net.robotmedia.billing.BillingRequest;
|
||||||
|
import net.robotmedia.billing.helper.AbstractBillingObserver;
|
||||||
|
import net.robotmedia.billing.model.Transaction;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 1/5/12
|
||||||
|
* Time: 4:51 PM
|
||||||
|
*/
|
||||||
|
public class CalculatorBillingObserver extends AbstractBillingObserver {
|
||||||
|
|
||||||
|
public CalculatorBillingObserver(@NotNull Activity activity) {
|
||||||
|
super(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBillingChecked(boolean supported) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPurchaseStateChanged(String itemId, Transaction.PurchaseState state) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPurchaseResponse(String itemId, BillingRequest.ResponseCode response) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
@ -6,11 +6,16 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
|
import android.util.Log;
|
||||||
import net.robotmedia.billing.BillingController;
|
import net.robotmedia.billing.BillingController;
|
||||||
|
import net.robotmedia.billing.BillingRequest;
|
||||||
|
import net.robotmedia.billing.IBillingObserver;
|
||||||
|
import net.robotmedia.billing.model.Transaction;
|
||||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||||
import org.solovyev.android.view.widgets.VibratorContainer;
|
import org.solovyev.android.view.widgets.VibratorContainer;
|
||||||
|
|
||||||
@ -19,7 +24,7 @@ import org.solovyev.android.view.widgets.VibratorContainer;
|
|||||||
* Date: 7/16/11
|
* Date: 7/16/11
|
||||||
* Time: 6:37 PM
|
* Time: 6:37 PM
|
||||||
*/
|
*/
|
||||||
public class CalculatorPreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class CalculatorPreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener, IBillingObserver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -35,10 +40,13 @@ public class CalculatorPreferencesActivity extends PreferenceActivity implements
|
|||||||
|
|
||||||
// check billing availability
|
// check billing availability
|
||||||
if (BillingController.checkBillingSupported(CalculatorPreferencesActivity.this) != BillingController.BillingStatus.SUPPORTED) {
|
if (BillingController.checkBillingSupported(CalculatorPreferencesActivity.this) != BillingController.BillingStatus.SUPPORTED) {
|
||||||
|
Log.d(CalculatorPreferencesActivity.class.getName(), "Billing is not supported - warn user!");
|
||||||
// warn about not supported billing
|
// warn about not supported billing
|
||||||
new AlertDialog.Builder(CalculatorPreferencesActivity.this).setTitle(R.string.c_error).setMessage(R.string.c_billing_error).create().show();
|
new AlertDialog.Builder(CalculatorPreferencesActivity.this).setTitle(R.string.c_error).setMessage(R.string.c_billing_error).create().show();
|
||||||
} else {
|
} else {
|
||||||
|
Log.d(CalculatorPreferencesActivity.class.getName(), "Billing is supported - continue!");
|
||||||
if (!CalculatorApplication.isAdFree(CalculatorPreferencesActivity.this)) {
|
if (!CalculatorApplication.isAdFree(CalculatorPreferencesActivity.this)) {
|
||||||
|
Log.d(CalculatorPreferencesActivity.class.getName(), "Item not purchased - try to purchase!");
|
||||||
// not purchased => show purchase window for user
|
// not purchased => show purchase window for user
|
||||||
BillingController.requestPurchase(CalculatorPreferencesActivity.this, CalculatorApplication.AD_FREE_PRODUCT_ID, true);
|
BillingController.requestPurchase(CalculatorPreferencesActivity.this, CalculatorApplication.AD_FREE_PRODUCT_ID, true);
|
||||||
}
|
}
|
||||||
@ -51,18 +59,67 @@ public class CalculatorPreferencesActivity extends PreferenceActivity implements
|
|||||||
addFreePreference.setEnabled(false);
|
addFreePreference.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BillingController.registerObserver(this);
|
||||||
|
|
||||||
final SharedPreferences preferences = getPreferenceManager().getSharedPreferences();
|
final SharedPreferences preferences = getPreferenceManager().getSharedPreferences();
|
||||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
onSharedPreferenceChanged(preferences, CalculatorEngine.Preferences.roundResult.getKey());
|
onSharedPreferenceChanged(preferences, CalculatorEngine.Preferences.roundResult.getKey());
|
||||||
onSharedPreferenceChanged(preferences, VibratorContainer.HAPTIC_FEEDBACK_P_KEY);
|
onSharedPreferenceChanged(preferences, VibratorContainer.HAPTIC_FEEDBACK_P_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
BillingController.unregisterObserver(this);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||||
if (CalculatorEngine.Preferences.roundResult.getKey().equals(key)) {
|
if (CalculatorEngine.Preferences.roundResult.getKey().equals(key)) {
|
||||||
findPreference(CalculatorEngine.Preferences.roundResult.getKey()).setEnabled(preferences.getBoolean(key, CalculatorEngine.Preferences.roundResult.getDefaultValue()));
|
findPreference(CalculatorEngine.Preferences.precision.getKey()).setEnabled(preferences.getBoolean(key, CalculatorEngine.Preferences.roundResult.getDefaultValue()));
|
||||||
} else if (VibratorContainer.HAPTIC_FEEDBACK_P_KEY.equals(key)) {
|
} else if (VibratorContainer.HAPTIC_FEEDBACK_P_KEY.equals(key)) {
|
||||||
findPreference(VibratorContainer.HAPTIC_FEEDBACK_DURATION_P_KEY).setEnabled(preferences.getBoolean(key, VibratorContainer.HAPTIC_FEEDBACK_DEFAULT));
|
findPreference(VibratorContainer.HAPTIC_FEEDBACK_DURATION_P_KEY).setEnabled(preferences.getBoolean(key, VibratorContainer.HAPTIC_FEEDBACK_DEFAULT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBillingChecked(boolean supported) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPurchaseIntent(String itemId, PendingIntent purchaseIntent) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPurchaseStateChanged(String itemId, Transaction.PurchaseState state) {
|
||||||
|
if (CalculatorApplication.AD_FREE_PRODUCT_ID.equals(itemId)) {
|
||||||
|
final Preference addFreePreference = findPreference(CalculatorApplication.AD_FREE_P_KEY);
|
||||||
|
if (addFreePreference != null) {
|
||||||
|
switch (state) {
|
||||||
|
case PURCHASED:
|
||||||
|
addFreePreference.setEnabled(false);
|
||||||
|
break;
|
||||||
|
case CANCELLED:
|
||||||
|
addFreePreference.setEnabled(true);
|
||||||
|
break;
|
||||||
|
case REFUNDED:
|
||||||
|
addFreePreference.setEnabled(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPurchaseResponse(String itemId, BillingRequest.ResponseCode response) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransactionsRestored() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
BIN
src/misc/res/logoFULL_banner.png
Normal file
BIN
src/misc/res/logoFULL_banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Loading…
Reference in New Issue
Block a user