Purchase dialog

This commit is contained in:
Sergey Solovyev 2013-01-20 16:54:10 +04:00
parent b6778f7615
commit 974fbc4ec7
12 changed files with 173 additions and 44 deletions

View File

@ -320,5 +320,16 @@
<string name="cpp_invalid_number">Неправильное число!</string> <string name="cpp_invalid_number">Неправильное число!</string>
<string name="cpp_plot_boundaries_should_differ">Границы графика не могут быть равны!</string> <string name="cpp_plot_boundaries_should_differ">Границы графика не могут быть равны!</string>
<string name="cpp_apply">Применить</string> <string name="cpp_apply">Применить</string>
<string name="cpp_message">Сообщение</string>
<string name="cpp_continue">Продолжить</string>
<string name="cpp_purchase_text">Поддержать проект очень легко и безопасно: процесс покупки проводится Google и всё что вам нужно - это настроенный Google аккаунт.\n\n
Информация о покупке хранится на серверах Google с вашим Google аккаунтом и вы можете легко использовать приложение на нескольких устройствах.\n\n
По нажатию кнопки \'Продолжить\' вы будете перенаправлены в приложение Google Play для совершения покупки.
</string>
<string name="cpp_purchase_title">Покупка</string>
<string name="cpp_purchase_thank_you_text">Спасибо за помощь в развитии проекта!\n\n Приложение получит уведомление о покупке в течение нескольких минут. Вы всегда можете посмотреть состояние покупки в вашем Google аккаунте.\n
Если у вас есть вопросы или проблемы вы всегда можете обратиться ко мне напрямую (конакты доступны в Меню->О приложении)
</string>
</resources> </resources>

View File

@ -175,8 +175,8 @@
<string name="c_calc_use_back_button_as_prev_summary">Defines the behaviour of the Back button</string> <string name="c_calc_use_back_button_as_prev_summary">Defines the behaviour of the Back button</string>
<string name="c_calc_use_back_button_as_prev_title">Use Back button as history prev</string> <string name="c_calc_use_back_button_as_prev_title">Use Back button as history prev</string>
<string name="c_clear_billing_info_summary">Billing information will be reloaded from the server</string> <string name="c_clear_billing_info_summary">Purchase information will be reloaded from the server</string>
<string name="c_clear_billing_info_title">Update billing information</string> <string name="c_clear_billing_info_title">Update purchase information</string>
<string name="c_warning">Warning</string> <string name="c_warning">Warning</string>
<string name="c_error">Error</string> <string name="c_error">Error</string>
@ -321,6 +321,16 @@
<string name="cpp_plot_boundaries_should_differ">Graph boundaries should not be the same!</string> <string name="cpp_plot_boundaries_should_differ">Graph boundaries should not be the same!</string>
<string name="cpp_apply">Apply</string> <string name="cpp_apply">Apply</string>
<string name="cpp_message">Message</string> <string name="cpp_message">Message</string>
<string name="cpp_continue">Continue</string>
<string name="cpp_purchase_text">Supporting the project is easy and secure: purchase process is provided by Google and all you need is a properly configured Google account.\n\n
Payment information is stored in Google servers with your Google account and you can easily use application on several devices.\n\n
By clicking \'Continue\' button you will be redirected to the Google Play app to make the payment.
</string>
<string name="cpp_purchase_title">Purchase</string>
<string name="cpp_purchase_thank_you_text">Thank you for supporting the application!\n\n It might take several minutes until app will be informed about the purchase. You always can check information about the purchase in your Google Account.\n
If you have any problems or questions feel free to contact me directly (contacts are available in Main->Menu->About)
</string>
</resources> </resources>

View File

@ -36,7 +36,7 @@
<activity android:clearTaskOnLaunch="true" android:label="@string/c_app_name" android:name=".CalculatorActivityMobile" android:windowSoftInputMode="adjustPan"/> <activity android:clearTaskOnLaunch="true" android:label="@string/c_app_name" android:name=".CalculatorActivityMobile" android:windowSoftInputMode="adjustPan"/>
<!-- settings must use action bar icon--> <!-- settings must use action bar icon-->
<activity android:icon="@drawable/ab_icon" android:label="@string/c_app_settings" android:name=".CalculatorPreferencesActivity"/> <activity android:icon="@drawable/ab_icon" android:label="@string/c_app_settings" android:name=".preferences.CalculatorPreferencesActivity"/>
<activity android:label="@string/c_history" android:name=".history.CalculatorHistoryActivity"/> <activity android:label="@string/c_history" android:name=".history.CalculatorHistoryActivity"/>
@ -57,6 +57,8 @@
<activity android:launchMode="singleTop" android:label="@string/cpp_plot_function_settings" android:name=".plot.CalculatorPlotFunctionSettingsActivity" android:theme="@style/cpp_gray_dialog_theme"/> <activity android:launchMode="singleTop" android:label="@string/cpp_plot_function_settings" android:name=".plot.CalculatorPlotFunctionSettingsActivity" android:theme="@style/cpp_gray_dialog_theme"/>
<activity android:launchMode="singleTop" android:label="@string/cpp_plot_range" android:name=".plot.CalculatorPlotRangeActivity" android:theme="@style/cpp_gray_dialog_theme"/> <activity android:launchMode="singleTop" android:label="@string/cpp_plot_range" android:name=".plot.CalculatorPlotRangeActivity" android:theme="@style/cpp_gray_dialog_theme"/>
<activity android:launchMode="singleTop" android:label="@string/cpp_purchase_title" android:name=".preferences.CalculatorPurchaseDialogActivity" android:theme="@style/cpp_gray_dialog_theme"/>
<activity android:launchMode="singleTop" android:name=".CalculatorDialogActivity" android:theme="@style/cpp_gray_dialog_theme"/> <activity android:launchMode="singleTop" android:name=".CalculatorDialogActivity" android:theme="@style/cpp_gray_dialog_theme"/>
<!-- todo serso: strings--> <!-- todo serso: strings-->

View File

@ -11,7 +11,9 @@
<TextView <TextView
a:id="@+id/cpp_dialog_message_textview" a:id="@+id/cpp_dialog_message_textview"
a:layout_width="match_parent" a:layout_width="match_parent"
a:layout_height="wrap_content" /> a:layout_height="wrap_content"
a:maxLines="10"
a:scrollbars="vertical"/>
<LinearLayout <LinearLayout
a:layout_width="match_parent" a:layout_width="match_parent"

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/main_fragment_layout"
style="?cpp_fragment_layout_style"
a:layout_width="match_parent"
a:layout_gravity="center_horizontal"
a:layout_height="match_parent"
a:orientation="vertical">
<TextView
a:id="@+id/cpp_purchase_text"
a:text="@string/cpp_purchase_text"
a:layout_width="match_parent"
a:layout_height="wrap_content"
a:maxLines="10"
a:scrollbars="vertical"/>
<Button
a:id="@+id/cpp_continue_button"
a:text="@string/cpp_continue"
a:layout_width="match_parent"
a:layout_height="wrap_content" />
</LinearLayout>

View File

@ -24,6 +24,7 @@ import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity; import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotter; import org.solovyev.android.calculator.plot.CalculatorPlotter;
import org.solovyev.android.calculator.preferences.CalculatorPreferencesActivity;
import org.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType; import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.StringUtils; import org.solovyev.common.text.StringUtils;

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.method.ScrollingMovementMethod;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
@ -97,6 +98,7 @@ public class CalculatorDialogActivity extends SherlockFragmentActivity {
if (dialogData != null) { if (dialogData != null) {
final TextView messageTextView = (TextView) root.findViewById(R.id.cpp_dialog_message_textview); final TextView messageTextView = (TextView) root.findViewById(R.id.cpp_dialog_message_textview);
messageTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
messageTextView.setText(dialogData.getMessage()); messageTextView.setText(dialogData.getMessage());
if ( dialogData.getMessageType() == MessageType.error || dialogData.getMessageType() == MessageType.warning ) { if ( dialogData.getMessageType() == MessageType.error || dialogData.getMessageType() == MessageType.warning ) {

View File

@ -35,6 +35,8 @@ public enum CalculatorFragmentType {
plotter_function_settings(CalculatorPlotFunctionSettingsActivity.CalculatorPlotFunctionSettingsFragment.class, R.layout.cpp_plot_function_settings_fragment, R.string.cpp_plot_function_settings), plotter_function_settings(CalculatorPlotFunctionSettingsActivity.CalculatorPlotFunctionSettingsFragment.class, R.layout.cpp_plot_function_settings_fragment, R.string.cpp_plot_function_settings),
plotter_range(CalculatorPlotRangeActivity.CalculatorPlotRangeFragment.class, R.layout.cpp_plot_range_fragment, R.string.cpp_plot_range), plotter_range(CalculatorPlotRangeActivity.CalculatorPlotRangeFragment.class, R.layout.cpp_plot_range_fragment, R.string.cpp_plot_range),
purchase_dialog(CalculatorPlotRangeActivity.CalculatorPlotRangeFragment.class, R.layout.cpp_purchase_dialog_fragment, R.string.cpp_purchase_title),
dialog(CalculatorDialogActivity.CalculatorDialogFragment.class, R.layout.cpp_dialog_fragment, R.string.cpp_message), dialog(CalculatorDialogActivity.CalculatorDialogFragment.class, R.layout.cpp_dialog_fragment, R.string.cpp_message),
about(CalculatorAboutFragment.class, R.layout.about_fragment, R.string.c_about), about(CalculatorAboutFragment.class, R.layout.about_fragment, R.string.c_about),

View File

@ -43,6 +43,17 @@ enum CalculatorMenu implements LabeledMenuItem<MenuItem> {
} }
}, },
exit(R.string.c_exit) {
@Override
public void onClick(@NotNull MenuItem data, @NotNull Context context) {
if (context instanceof Activity) {
((Activity) context).finish();
} else {
Log.e(CalculatorActivity.TAG, "Activity menu used with context");
}
}
},
help(R.string.c_help) { help(R.string.c_help) {
@Override @Override
public void onClick(@NotNull MenuItem data, @NotNull Context context) { public void onClick(@NotNull MenuItem data, @NotNull Context context) {
@ -55,17 +66,6 @@ enum CalculatorMenu implements LabeledMenuItem<MenuItem> {
public void onClick(@NotNull MenuItem data, @NotNull Context context) { public void onClick(@NotNull MenuItem data, @NotNull Context context) {
CalculatorActivityLauncher.showAbout(context); CalculatorActivityLauncher.showAbout(context);
} }
},
exit(R.string.c_exit) {
@Override
public void onClick(@NotNull MenuItem data, @NotNull Context context) {
if (context instanceof Activity) {
((Activity) context).finish();
} else {
Log.e(CalculatorActivity.TAG, "Activity menu used with context");
}
}
}; };
private final int captionResId; private final int captionResId;

View File

@ -3,11 +3,11 @@
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
*/ */
package org.solovyev.android.calculator; package org.solovyev.android.calculator.preferences;
import android.app.AlertDialog;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.Preference; import android.preference.Preference;
@ -22,9 +22,14 @@ import net.robotmedia.billing.helper.AbstractBillingObserver;
import net.robotmedia.billing.model.Transaction; import net.robotmedia.billing.model.Transaction;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.AndroidUtils; import org.solovyev.android.AndroidUtils;
import org.solovyev.android.App;
import org.solovyev.android.ads.AdsController; import org.solovyev.android.ads.AdsController;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.android.view.VibratorContainer; import org.solovyev.android.view.VibratorContainer;
import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
/** /**
* User: serso * User: serso
@ -93,30 +98,8 @@ public class CalculatorPreferencesActivity extends SherlockPreferenceActivity im
adFreePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { adFreePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
final Context context = CalculatorPreferencesActivity.this;
// check billing availability context.startActivity(new Intent(context, CalculatorPurchaseDialogActivity.class));
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 (!AdsController.getInstance().isAdFree(CalculatorPreferencesActivity.this)) {
Log.d(CalculatorPreferencesActivity.class.getName(), "Item not purchased - try to purchase!");
// not purchased => purchasing
Toast.makeText(CalculatorPreferencesActivity.this, R.string.c_calc_purchasing, Toast.LENGTH_SHORT).show();
// show purchase window for user
BillingController.requestPurchase(CalculatorPreferencesActivity.this, CalculatorApplication.AD_FREE_PRODUCT_ID, true);
} else {
// disable preference
adFreePreference.setEnabled(false);
// and show message to user
Toast.makeText(CalculatorPreferencesActivity.this, R.string.c_calc_already_purchased, Toast.LENGTH_SHORT).show();
}
}
return true; return true;
} }
}); });
@ -189,7 +172,15 @@ public class CalculatorPreferencesActivity extends SherlockPreferenceActivity im
@Override @Override
public void onRequestPurchaseResponse(@NotNull String itemId, @NotNull ResponseCode response) { public void onRequestPurchaseResponse(@NotNull String itemId, @NotNull ResponseCode response) {
// do nothing 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.getInstance().getApplication());
Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_message_dialog, MessageDialogData.newInstance(message, null));
}
}
} }
@Override @Override

View File

@ -0,0 +1,84 @@
package org.solovyev.android.calculator.preferences;
import android.app.Activity;
import android.app.AlertDialog;
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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.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.fragments.FragmentUtils;
/**
* User: serso
* Date: 1/20/13
* Time: 2:36 PM
*/
public class CalculatorPurchaseDialogActivity extends SherlockFragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cpp_dialog);
FragmentUtils.createFragment(this, PurchaseDialogFragment.class, R.id.dialog_layout, "purchase-dialog");
}
public static class PurchaseDialogFragment extends CalculatorFragment {
public PurchaseDialogFragment() {
super(CalculatorFragmentType.purchase_dialog);
}
@Override
public void onViewCreated(@NotNull View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
((TextView) root.findViewById(R.id.cpp_purchase_text)).setMovementMethod(ScrollingMovementMethod.getInstance());
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();
}
}
});
}
}
}

View File

@ -6,7 +6,6 @@ msg_5=Для функции {0} не определены параметры
msg_6=В выражении найден Бесконечный цикл - проверьте выражение msg_6=В выражении найден Бесконечный цикл - проверьте выражение
msg_7=Некоторые пользовательские данные не могут быть загружены. Пожалуйста, свяжитесь с авторами приложения с информацией ниже.\n\nНевозможно загрузить:\n{0} msg_7=Некоторые пользовательские данные не могут быть загружены. Пожалуйста, свяжитесь с авторами приложения с информацией ниже.\n\nНевозможно загрузить:\n{0}
syntax_error=Ошибка syntax_error=Ошибка
result_copied=Результат скопирован в буфер! result_copied=Результат скопирован в буфер!
text_copied=Текст скопирован в буфер! text_copied=Текст скопирован в буфер!