ads + billing + fix for MiOne devices' tabs
This commit is contained in:
parent
d26a084e50
commit
0d6656f52c
@ -144,7 +144,7 @@
|
||||
так как приложение стало довольно большим и сложным.\n
|
||||
Если вы хотите поддержать проект и избавиться от рекламы, вы можете купить специальную опцию в настройках приложения,\n
|
||||
если вы не хотите или не можете этого сделать - вы всё равно можете отблагодарить автора программы по почте: se.solovyev@gmail.com, высоко оценить приложение на андроид.маркете\n
|
||||
или помочь в переводе приложения на свой роной язык.
|
||||
или помочь в переводе приложения на свой родной язык.
|
||||
</string>
|
||||
|
||||
</resources>
|
@ -10,6 +10,8 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -35,33 +37,51 @@ public final class AndroidUtils {
|
||||
}
|
||||
|
||||
public static void centerAndWrapTabsFor(@NotNull TabHost tabHost) {
|
||||
int tabCount = tabHost.getTabWidget().getTabCount();
|
||||
for (int i = 0; i < tabCount; i++) {
|
||||
final View view = tabHost.getTabWidget().getChildTabViewAt(i);
|
||||
if (view != null) {
|
||||
if (view.getLayoutParams().height > 0) {
|
||||
// reduce height of the tab
|
||||
view.getLayoutParams().height *= 0.8;
|
||||
}
|
||||
if (allowCenterAndWrappingTabs()) {
|
||||
int tabCount = tabHost.getTabWidget().getTabCount();
|
||||
for (int i = 0; i < tabCount; i++) {
|
||||
final View view = tabHost.getTabWidget().getChildTabViewAt(i);
|
||||
if (view != null) {
|
||||
if (view.getLayoutParams().height > 0) {
|
||||
// reduce height of the tab
|
||||
view.getLayoutParams().height *= 0.8;
|
||||
}
|
||||
|
||||
// get title text view
|
||||
final View textView = view.findViewById(android.R.id.title);
|
||||
if (textView instanceof TextView) {
|
||||
// just in case check the type
|
||||
// get title text view
|
||||
final View textView = view.findViewById(android.R.id.title);
|
||||
if (textView instanceof TextView) {
|
||||
// just in case check the type
|
||||
|
||||
// center text
|
||||
((TextView) textView).setGravity(Gravity.CENTER);
|
||||
// wrap text
|
||||
((TextView) textView).setSingleLine(false);
|
||||
// center text
|
||||
((TextView) textView).setGravity(Gravity.CENTER);
|
||||
// wrap text
|
||||
((TextView) textView).setSingleLine(false);
|
||||
|
||||
// explicitly set layout parameters
|
||||
textView.getLayoutParams().height = ViewGroup.LayoutParams.FILL_PARENT;
|
||||
textView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
// explicitly set layout parameters
|
||||
textView.getLayoutParams().height = ViewGroup.LayoutParams.FILL_PARENT;
|
||||
textView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@NotNull TabHost tabHost,
|
||||
@NotNull String tabId,
|
||||
|
@ -26,6 +26,8 @@ import android.widget.TextView;
|
||||
import com.google.ads.AdView;
|
||||
import jscl.AngleUnit;
|
||||
import jscl.NumeralBase;
|
||||
import net.robotmedia.billing.BillingController;
|
||||
import net.robotmedia.billing.IBillingObserver;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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;
|
||||
|
||||
@Nullable
|
||||
private IBillingObserver billingObserver;
|
||||
|
||||
public static class Preferences {
|
||||
@NotNull
|
||||
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) {
|
||||
if (!initialized) {
|
||||
|
||||
billingObserver = new CalculatorBillingObserver(this);
|
||||
BillingController.registerObserver(billingObserver);
|
||||
BillingController.checkBillingSupported(this);
|
||||
|
||||
final int savedVersion = Preferences.appVersion.getPreference(preferences);
|
||||
|
||||
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 ) {
|
||||
adView.destroy();
|
||||
}
|
||||
|
||||
if (billingObserver != null) {
|
||||
BillingController.unregisterObserver(billingObserver);
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
@ -36,20 +36,24 @@ public class CalculatorApplication extends android.app.Application {
|
||||
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);
|
||||
}
|
||||
|
||||
private static boolean transactionsRestored = false;
|
||||
|
||||
public static boolean isAdFree(@NotNull Context context) {
|
||||
// check if user already bought this product
|
||||
boolean purchased = isAdFreeApprox(context);
|
||||
if (!purchased) {
|
||||
boolean purchased = isAdFreePurchased(context);
|
||||
if (!purchased && !transactionsRestored) {
|
||||
// we must to restore all transactions done by user to guarantee that product was purchased or not
|
||||
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
|
||||
// check the billing one more time
|
||||
purchased = isAdFreeApprox(context);
|
||||
purchased = isAdFreePurchased(context);
|
||||
}
|
||||
return purchased;
|
||||
}
|
||||
@ -62,9 +66,8 @@ public class CalculatorApplication extends android.app.Application {
|
||||
@Nullable
|
||||
public static AdView inflateAd(@NotNull Activity activity, int parentViewId) {
|
||||
AdView result = null;
|
||||
if ( !isAdFreeApprox(activity) ) {
|
||||
if ( !isAdFree(activity) ) {
|
||||
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();
|
||||
result = AndroidUtils.createAndInflateAdView(activity, ADMOB_USER_ID, parentViewId, keywords);
|
||||
} else {
|
||||
@ -78,6 +81,7 @@ public class CalculatorApplication extends android.app.Application {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
//BillingController.setDebug(true);
|
||||
BillingController.setConfiguration(new BillingController.IConfiguration() {
|
||||
|
||||
@Override
|
||||
@ -90,7 +94,5 @@ public class CalculatorApplication extends android.app.Application {
|
||||
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;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.util.Log;
|
||||
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.view.widgets.VibratorContainer;
|
||||
|
||||
@ -19,7 +24,7 @@ import org.solovyev.android.view.widgets.VibratorContainer;
|
||||
* Date: 7/16/11
|
||||
* Time: 6:37 PM
|
||||
*/
|
||||
public class CalculatorPreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
public class CalculatorPreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener, IBillingObserver {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -35,10 +40,13 @@ public class CalculatorPreferencesActivity extends PreferenceActivity implements
|
||||
|
||||
// check billing availability
|
||||
if (BillingController.checkBillingSupported(CalculatorPreferencesActivity.this) != BillingController.BillingStatus.SUPPORTED) {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Billing is not supported - warn user!");
|
||||
// warn about not supported billing
|
||||
new AlertDialog.Builder(CalculatorPreferencesActivity.this).setTitle(R.string.c_error).setMessage(R.string.c_billing_error).create().show();
|
||||
} else {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Billing is supported - continue!");
|
||||
if (!CalculatorApplication.isAdFree(CalculatorPreferencesActivity.this)) {
|
||||
Log.d(CalculatorPreferencesActivity.class.getName(), "Item not purchased - try to purchase!");
|
||||
// not purchased => show purchase window for user
|
||||
BillingController.requestPurchase(CalculatorPreferencesActivity.this, CalculatorApplication.AD_FREE_PRODUCT_ID, true);
|
||||
}
|
||||
@ -51,18 +59,67 @@ public class CalculatorPreferencesActivity extends PreferenceActivity implements
|
||||
addFreePreference.setEnabled(false);
|
||||
}
|
||||
|
||||
BillingController.registerObserver(this);
|
||||
|
||||
final SharedPreferences preferences = getPreferenceManager().getSharedPreferences();
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
onSharedPreferenceChanged(preferences, CalculatorEngine.Preferences.roundResult.getKey());
|
||||
onSharedPreferenceChanged(preferences, VibratorContainer.HAPTIC_FEEDBACK_P_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
BillingController.unregisterObserver(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String 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)) {
|
||||
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