Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
a7fa8b4315
11 changed files with 432 additions and 470 deletions
|
@ -30,6 +30,14 @@
|
|||
<string name="osm_live_subscription">OSM Live subscription</string>
|
||||
<string name="osm_live_subscribe_btn">Subscribe</string>
|
||||
<string name="osm_live_default_price">€1,49</string>
|
||||
<string name="osm_live_email_desc">We need it to provide you information about contributions</string>
|
||||
<string name="osm_live_user_public_name">Public Name</string>
|
||||
<string name="osm_live_hide_user_name">Don\'t show my name in reports</string>
|
||||
<string name="osm_live_support_region">Support region</string>
|
||||
<string name="osm_live_month_cost">Month cost</string>
|
||||
<string name="osm_live_month_cost_desc">Monthly payment</string>
|
||||
<string name="osm_live_active">Active</string>
|
||||
<string name="osm_live_not_active">Inactive</string>
|
||||
|
||||
<string name="osm_live_header">This subscription enables hourly updates for all maps around the world.
|
||||
Major part of the income goes back to OSM community and is paid out per each OSM contribution.
|
||||
|
|
|
@ -99,13 +99,15 @@
|
|||
app:typeface="@string/font_roboto_regular"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/statusTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="Active"
|
||||
android:gravity="right"
|
||||
android:text="@string/osm_live_active"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:textAllCapsCompat="true"
|
||||
|
@ -129,18 +131,20 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="Support country"
|
||||
android:text="@string/osm_live_support_region"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:typeface="@string/font_roboto_regular"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/regionTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:gravity="right"
|
||||
android:text="World"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
|
@ -165,18 +169,20 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="Email"
|
||||
android:text="@string/shared_string_email_address"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:typeface="@string/font_roboto_regular"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/emailTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:gravity="right"
|
||||
android:text="my@email.com"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
|
@ -201,18 +207,20 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="Visible Name"
|
||||
android:text="@string/osm_live_user_public_name"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:typeface="@string/font_roboto_regular"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/userNameTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:gravity="right"
|
||||
android:text="None"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
|
@ -220,44 +228,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dashboard_divider"/>
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minHeight="44dp">
|
||||
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="Last pay"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:typeface="@string/font_roboto_regular"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="25 Nov 2015"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:typeface="@string/font_roboto_medium"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -24,7 +24,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:text="Subscription form"
|
||||
android:text="@string/osm_live_subscription"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/default_list_text_size_large"
|
||||
android:textStyle="bold"
|
||||
|
@ -63,7 +63,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:hint="E-mail address"
|
||||
android:hint="@string/shared_string_email_address"
|
||||
android:inputType="textEmailAddress"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -74,7 +74,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="72dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="We need it to provide you information about contributions"
|
||||
android:text="@string/osm_live_email_desc"
|
||||
android:textColor="?android:attr/textColorSecondary"/>
|
||||
|
||||
|
||||
|
@ -103,20 +103,21 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:hint="Public Name"
|
||||
android:hint="@string/osm_live_user_public_name"
|
||||
android:inputType="text"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/hideUserNameCheckbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:layout_marginLeft="72dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Don't show my name in reports"
|
||||
android:text="@string/osm_live_hide_user_name"
|
||||
android:textColor="?android:attr/textColorPrimary"/>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -149,7 +150,7 @@
|
|||
android:layout_marginTop="4dp"
|
||||
android:drawableRight="@drawable/ic_action_arrow_drop_down"
|
||||
android:editable="false"
|
||||
android:hint="Support region"/>
|
||||
android:hint="@string/osm_live_support_region"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -174,22 +175,21 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Month cost"
|
||||
android:text="@string/osm_live_month_cost"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size_large"
|
||||
android:textStyle="bold"
|
||||
app:typeface="@string/font_roboto_regular"/>
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/priceTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:gravity="right"
|
||||
android:text="@string/osm_live_default_price"
|
||||
android:textColor="?attr/color_dialog_buttons"
|
||||
android:textSize="@dimen/default_list_text_size_large"
|
||||
android:textStyle="bold"
|
||||
app:typeface="@string/font_roboto_regular"/>
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -198,10 +198,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="Monthly payment"
|
||||
android:text="@string/osm_live_month_cost_desc"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:typeface="@string/font_roboto_regular"/>
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
|
@ -223,7 +222,7 @@
|
|||
android:background="?attr/selectableItemBackground"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="Subscribe"
|
||||
android:text="@string/osm_live_subscribe_btn"
|
||||
android:textColor="?attr/color_dialog_buttons"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
||||
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||
-->
|
||||
<string name="shared_string_email_address">E-mail address</string>
|
||||
<string name="rendering_attr_hideUnderground_name">Hide underground objects</string>
|
||||
<string name="data_is_not_available">Data is not available</string>
|
||||
<string name="shared_string_remove">Remove</string>
|
||||
|
|
|
@ -815,6 +815,8 @@ public class OsmandSettings {
|
|||
public final OsmandPreference<String> BILLING_USER_NAME = new StringPreference("billing_user_name", "").makeGlobal();
|
||||
public final OsmandPreference<String> BILLING_USER_EMAIL = new StringPreference("billing_user_email", "").makeGlobal();
|
||||
public final OsmandPreference<String> BILLING_USER_COUNTRY = new StringPreference("billing_user_country", "").makeGlobal();
|
||||
public final OsmandPreference<String> BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference("billing_user_country_download_name", "").makeGlobal();
|
||||
public final OsmandPreference<Boolean> BILLING_HIDE_USER_NAME = new BooleanPreference("billing_hide_user_name", false).makeGlobal();
|
||||
public final OsmandPreference<Boolean> BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference("billing_purchase_token_sent", false).makeGlobal();
|
||||
|
||||
// this value string is synchronized with settings_pref.xml preference name
|
||||
|
|
|
@ -19,16 +19,20 @@ import net.osmand.util.Algorithms;
|
|||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InAppHelper {
|
||||
// Debug tag, for logging
|
||||
|
@ -58,10 +62,13 @@ public class InAppHelper {
|
|||
|
||||
public interface InAppCallbacks {
|
||||
void onError(String error);
|
||||
|
||||
void onGetItems();
|
||||
|
||||
void onItemPurchased(String sku);
|
||||
|
||||
void showProgress();
|
||||
|
||||
void dismissProgress();
|
||||
}
|
||||
|
||||
|
@ -166,8 +173,7 @@ public class InAppHelper {
|
|||
|
||||
// Do we have the live updates?
|
||||
Purchase liveUpdatesPurchase = inventory.getPurchase(SKU_LIVE_UPDATES);
|
||||
mSubscribedToLiveUpdates = (liveUpdatesPurchase != null &&
|
||||
verifyDeveloperPayload(liveUpdatesPurchase));
|
||||
mSubscribedToLiveUpdates = (liveUpdatesPurchase != null);
|
||||
Log.d(TAG, "User " + (mSubscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE")
|
||||
+ " live updates purchased.");
|
||||
|
||||
|
@ -193,7 +199,7 @@ public class InAppHelper {
|
|||
};
|
||||
|
||||
public void purchaseLiveUpdates(final Activity activity, final String email, final String userName,
|
||||
final String country) {
|
||||
final String countryDownloadName) {
|
||||
if (!mHelper.subscriptionsSupported()) {
|
||||
complain("Subscriptions not supported on your device yet. Sorry!");
|
||||
if (callbacks != null) {
|
||||
|
@ -218,12 +224,17 @@ public class InAppHelper {
|
|||
userId = ctx.getSettings().BILLING_USER_ID.get();
|
||||
if (Algorithms.isEmpty(userId)) {
|
||||
try {
|
||||
return sendRequest("http://download.osmand.net/subscription/register?email=" + URLEncoder.encode(email, "UTF-8")
|
||||
+ "&visibleName=" + URLEncoder.encode(userName, "UTF-8")
|
||||
+ "&preferredCountry=" + URLEncoder.encode(country, "UTF-8")
|
||||
+ (Algorithms.isEmpty(userId) ? "&status=new" : ""),
|
||||
"POST", "Requesting userId...");
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put("visibleName", userName);
|
||||
parameters.put("preferredCountry", countryDownloadName);
|
||||
parameters.put("email", email);
|
||||
parameters.put("status", "new");
|
||||
|
||||
return sendRequest("http://download.osmand.net/subscription/register.php",
|
||||
parameters, "Requesting userId...");
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "sendRequest Error", e);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
|
@ -236,6 +247,7 @@ public class InAppHelper {
|
|||
if (Algorithms.isEmpty(userId)) {
|
||||
Log.d(TAG, "Response=" + response);
|
||||
if (response == null) {
|
||||
complain("Cannot retrieve userId from server.");
|
||||
if (callbacks != null) {
|
||||
callbacks.dismissProgress();
|
||||
callbacks.onError("Cannot retrieve userId from server.");
|
||||
|
@ -252,10 +264,12 @@ public class InAppHelper {
|
|||
ctx.getSettings().BILLING_USER_ID.set(userId);
|
||||
Log.d(TAG, "UserId=" + userId);
|
||||
} catch (JSONException e) {
|
||||
String message = "JSON parsing error: "
|
||||
+ (e.getMessage() == null ? "unknown" : e.getMessage());
|
||||
complain(message);
|
||||
if (callbacks != null) {
|
||||
callbacks.dismissProgress();
|
||||
callbacks.onError("JSON parsing error: "
|
||||
+ (e.getMessage() == null ? "unknown" : e.getMessage()));
|
||||
callbacks.onError(message);
|
||||
}
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
|
@ -304,36 +318,6 @@ public class InAppHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/** Verifies the developer payload of a purchase. */
|
||||
private boolean verifyDeveloperPayload(Purchase p) {
|
||||
String payload = p.getDeveloperPayload();
|
||||
|
||||
/*
|
||||
* TODO: verify that the developer payload of the purchase is correct. It will be
|
||||
* the same one that you sent when initiating the purchase.
|
||||
*
|
||||
* WARNING: Locally generating a random string when starting a purchase and
|
||||
* verifying it here might seem like a good approach, but this will fail in the
|
||||
* case where the user purchases an item on one device and then uses your app on
|
||||
* a different device, because on the other device you will not have access to the
|
||||
* random string you originally generated.
|
||||
*
|
||||
* So a good developer payload has these characteristics:
|
||||
*
|
||||
* 1. If two different users purchase an item, the payload is different between them,
|
||||
* so that one user's purchase can't be replayed to another user.
|
||||
*
|
||||
* 2. The payload must be such that you can verify it even when the app wasn't the
|
||||
* one who initiated the purchase flow (so that items purchased by the user on
|
||||
* one device work on other devices owned by the user).
|
||||
*
|
||||
* Using your own server to store and verify developer payloads across app
|
||||
* installations is recommended.
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Callback for when a purchase is finished
|
||||
private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
|
||||
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
|
||||
|
@ -353,17 +337,6 @@ public class InAppHelper {
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (!verifyDeveloperPayload(purchase)) {
|
||||
complain("Error purchasing. Authenticity verification failed.");
|
||||
if (callbacks != null) {
|
||||
callbacks.dismissProgress();
|
||||
callbacks.onError("Error purchasing. Authenticity verification failed.");
|
||||
}
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Purchase successful.");
|
||||
|
||||
|
@ -398,11 +371,14 @@ public class InAppHelper {
|
|||
String userId = ctx.getSettings().BILLING_USER_ID.get();
|
||||
String email = ctx.getSettings().BILLING_USER_EMAIL.get();
|
||||
try {
|
||||
sendRequestAsync("http://download.osmand.net/subscription/purchased?userid=" + URLEncoder.encode(userId, "UTF-8")
|
||||
+ "&sku=" + URLEncoder.encode(SKU_LIVE_UPDATES, "UTF-8")
|
||||
+ "&purchaseToken=" + URLEncoder.encode(token, "UTF-8")
|
||||
+ "&email=" + URLEncoder.encode(email, "UTF-8"),
|
||||
"POST", "Sending purchase info...", new OnRequestResultListener() {
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put("userId", userId);
|
||||
parameters.put("sku", SKU_LIVE_UPDATES);
|
||||
parameters.put("purchaseToken", token);
|
||||
parameters.put("email", email);
|
||||
|
||||
sendRequestAsync("http://download.osmand.net/subscription/purchased.php",
|
||||
parameters, "Sending purchase info...", new OnRequestResultListener() {
|
||||
@Override
|
||||
public void onResult(String result) {
|
||||
if (result != null && result.trim().toLowerCase().equals("ok")) {
|
||||
|
@ -411,6 +387,7 @@ public class InAppHelper {
|
|||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "sendToken Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,33 +400,63 @@ public class InAppHelper {
|
|||
ctx.showToastMessage(message);
|
||||
}
|
||||
|
||||
private String sendRequest(String url, String requestMethod, String userOperation) {
|
||||
private String sendRequest(String url, Map<String, String> parameters, String userOperation) {
|
||||
Log.d(TAG, "Sending request " + url); //$NON-NLS-1$
|
||||
HttpURLConnection connection = null;
|
||||
try {
|
||||
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
||||
connection = NetworkUtils.getHttpURLConnection(url);
|
||||
|
||||
connection.setRequestProperty("Accept-Charset", "UTF-8");
|
||||
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx));
|
||||
connection.setConnectTimeout(15000);
|
||||
connection.setRequestMethod(requestMethod);
|
||||
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$
|
||||
StringBuilder responseBody = new StringBuilder();
|
||||
|
||||
if (parameters != null && parameters.size() > 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
|
||||
}
|
||||
String params = sb.toString();
|
||||
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
connection.setUseCaches(false);
|
||||
connection.setRequestMethod("POST");
|
||||
|
||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
|
||||
connection.setRequestProperty("Content-Length", String.valueOf(params.getBytes("UTF-8").length));
|
||||
connection.setFixedLengthStreamingMode(params.getBytes("UTF-8").length);
|
||||
|
||||
OutputStream output = new BufferedOutputStream(connection.getOutputStream());
|
||||
output.write(params.getBytes("UTF-8"));
|
||||
output.flush();
|
||||
output.close();
|
||||
|
||||
} else {
|
||||
connection.setRequestMethod("GET");
|
||||
connection.connect();
|
||||
}
|
||||
|
||||
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||
String msg = userOperation
|
||||
+ " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage(); //$NON-NLS-1$//$NON-NLS-2$
|
||||
+ " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage();
|
||||
Log.e(TAG, msg);
|
||||
showToast(msg);
|
||||
} else {
|
||||
Log.d(TAG, "Response : " + connection.getResponseMessage()); //$NON-NLS-1$
|
||||
Log.d(TAG, "Response : " + connection.getResponseMessage());
|
||||
// populate return fields.
|
||||
StringBuilder responseBody = new StringBuilder();
|
||||
responseBody.setLength(0);
|
||||
InputStream i = connection.getInputStream();
|
||||
if (i != null) {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256);
|
||||
String s;
|
||||
boolean f = true;
|
||||
while ((s = in.readLine()) != null) {
|
||||
if (!f) {
|
||||
responseBody.append("\n"); //$NON-NLS-1$
|
||||
responseBody.append("\n");
|
||||
} else {
|
||||
f = false;
|
||||
}
|
||||
|
@ -459,37 +466,42 @@ public class InAppHelper {
|
|||
in.close();
|
||||
i.close();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "sendRequest", e);
|
||||
}
|
||||
}
|
||||
return responseBody.toString();
|
||||
}
|
||||
connection.disconnect();
|
||||
|
||||
} catch (NullPointerException e) {
|
||||
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
|
||||
String msg = ctx.getString(R.string.auth_failed);
|
||||
Log.e(TAG, msg, e);
|
||||
showToast(msg);
|
||||
} catch (MalformedURLException e) {
|
||||
Log.e(TAG, userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
|
||||
Log.e(TAG, userOperation + " " + ctx.getString(R.string.failed_op), e);
|
||||
showToast(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
|
||||
Log.e(TAG, userOperation + " " + ctx.getString(R.string.failed_op), e);
|
||||
showToast(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sendRequestAsync(final String url, final String requestMethod, final String userOperation, final OnRequestResultListener listener) {
|
||||
private void sendRequestAsync(final String url, final Map<String, String> parameters, final String userOperation, final OnRequestResultListener listener) {
|
||||
|
||||
new AsyncTask<Void, Void, String>() {
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
try {
|
||||
return sendRequest(url, requestMethod, userOperation);
|
||||
return sendRequest(url, parameters, userOperation);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
package net.osmand.plus.liveupdates;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class CountrySelectionFragment extends BaseOsmAndDialogFragment {
|
||||
|
||||
private List<CountryItem> countryItems = new ArrayList<>();
|
||||
private OnFragmentInteractionListener mListener;
|
||||
|
||||
public List<CountryItem> getCountryItems() {
|
||||
return countryItems;
|
||||
}
|
||||
|
||||
public CountryItem getCountryItem(String downloadName) {
|
||||
if (!Algorithms.isEmpty(downloadName)) {
|
||||
for (CountryItem item : countryItems) {
|
||||
if (downloadName.equals(item.downloadName)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
if (countryItems.size() == 0) {
|
||||
initCountries(getMyApplication());
|
||||
}
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_search_list, container, false);
|
||||
ListView listView = (ListView) view.findViewById(android.R.id.list);
|
||||
final ArrayAdapter<CountryItem> adapter = new ListAdapter(getListItemIcon());
|
||||
if (countryItems.size() > 0) {
|
||||
adapter.addAll(countryItems);
|
||||
}
|
||||
listView.setAdapter(adapter);
|
||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
mListener.onSearchResult(adapter.getItem(position));
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
final EditText searchEditText = (EditText) view.findViewById(R.id.searchEditText);
|
||||
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
adapter.getFilter().filter(s);
|
||||
}
|
||||
});
|
||||
ImageButton clearButton = (ImageButton) view.findViewById(R.id.clearButton);
|
||||
setThemedDrawable(clearButton, R.drawable.ic_action_remove_dark);
|
||||
clearButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof OnFragmentInteractionListener) {
|
||||
mListener = (OnFragmentInteractionListener) context;
|
||||
} else if (getParentFragment() instanceof OnFragmentInteractionListener) {
|
||||
mListener = (OnFragmentInteractionListener) getParentFragment();
|
||||
} else {
|
||||
throw new RuntimeException(context.toString()
|
||||
+ " must implement OnFragmentInteractionListener");
|
||||
}
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
protected int getListItemIcon() {
|
||||
return R.drawable.ic_map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
public interface OnFragmentInteractionListener {
|
||||
void onSearchResult(CountryItem name);
|
||||
}
|
||||
|
||||
|
||||
public void initCountries(OsmandApplication app) {
|
||||
final WorldRegion root = app.getRegions().getWorldRegion();
|
||||
ArrayList<WorldRegion> groups = new ArrayList<>();
|
||||
groups.add(root);
|
||||
processGroup(root, groups);
|
||||
Collections.sort(groups, new Comparator<WorldRegion>() {
|
||||
@Override
|
||||
public int compare(WorldRegion lhs, WorldRegion rhs) {
|
||||
if (lhs == root) {
|
||||
return -1;
|
||||
}
|
||||
if (rhs == root) {
|
||||
return 1;
|
||||
}
|
||||
return getHumanReadableName(lhs).compareTo(getHumanReadableName(rhs));
|
||||
}
|
||||
});
|
||||
for (WorldRegion group : groups) {
|
||||
String name = getHumanReadableName(group);
|
||||
countryItems.add(new CountryItem(name, group.getRegionDownloadName()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void processGroup(WorldRegion group,
|
||||
List<WorldRegion> nameList) {
|
||||
if (group.isRegionMapDownload()) {
|
||||
nameList.add(group);
|
||||
}
|
||||
|
||||
if (group.getSubregions() != null) {
|
||||
for (WorldRegion g : group.getSubregions()) {
|
||||
processGroup(g, nameList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHumanReadableName(WorldRegion group) {
|
||||
String name;
|
||||
if (group.getLevel() > 2 || (group.getLevel() == 2
|
||||
&& group.getSuperregion().getRegionId().equals(WorldRegion.RUSSIA_REGION_ID))) {
|
||||
WorldRegion parent = group.getSuperregion();
|
||||
WorldRegion parentsParent = group.getSuperregion().getSuperregion();
|
||||
if (group.getLevel() == 3) {
|
||||
if (parentsParent.getRegionId().equals(WorldRegion.RUSSIA_REGION_ID)) {
|
||||
name = parentsParent.getLocaleName() + " " + group.getLocaleName();
|
||||
} else if (!parent.getRegionId().equals(WorldRegion.UNITED_KINGDOM_REGION_ID)) {
|
||||
name = parent.getLocaleName() + " " + group.getLocaleName();
|
||||
} else {
|
||||
name = group.getLocaleName();
|
||||
}
|
||||
} else {
|
||||
name = parent.getLocaleName() + " " + group.getLocaleName();
|
||||
}
|
||||
} else {
|
||||
name = group.getLocaleName();
|
||||
}
|
||||
if (name == null) {
|
||||
name = "";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static class CountryItem {
|
||||
private String localName;
|
||||
private String downloadName;
|
||||
|
||||
public CountryItem(String localName, String downloadName) {
|
||||
this.localName = localName;
|
||||
this.downloadName = downloadName;
|
||||
}
|
||||
|
||||
public String getLocalName() {
|
||||
return localName;
|
||||
}
|
||||
|
||||
public String getDownloadName() {
|
||||
return downloadName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return localName;
|
||||
}
|
||||
}
|
||||
|
||||
private class ListAdapter extends ArrayAdapter<CountryItem> {
|
||||
private final Drawable drawableLeft;
|
||||
|
||||
public ListAdapter(@DrawableRes int drawableLeftId) {
|
||||
super(getMyActivity(), android.R.layout.simple_list_item_1);
|
||||
this.drawableLeft = drawableLeftId == -1 ? null : getContentIcon(drawableLeftId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
CountryItem item = getItem(position);
|
||||
TextView view = (TextView) super.getView(position, convertView, parent);
|
||||
view.setText(item.localName);
|
||||
view.setCompoundDrawablesWithIntrinsicBounds(drawableLeft, null, null, null);
|
||||
view.setCompoundDrawablePadding(getResources().getDimensionPixelSize(R.dimen.list_content_padding));
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import android.widget.ImageButton;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -106,6 +107,29 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
});
|
||||
if (InAppHelper.isSubscribedToLiveUpdates()) {
|
||||
TextView statusTextView = (TextView) subscriptionHeader.findViewById(R.id.statusTextView);
|
||||
TextView regionNameTextView = (TextView) subscriptionHeader.findViewById(R.id.regionTextView);
|
||||
TextView emailTextView = (TextView) subscriptionHeader.findViewById(R.id.emailTextView);
|
||||
TextView userNameTextView = (TextView) subscriptionHeader.findViewById(R.id.userNameTextView);
|
||||
|
||||
if (InAppHelper.isSubscribedToLiveUpdates()) {
|
||||
statusTextView.setText(getString(R.string.osm_live_active));
|
||||
} else {
|
||||
statusTextView.setText(getString(R.string.osm_live_not_active));
|
||||
}
|
||||
|
||||
OsmandSettings settings = getMyApplication().getSettings();
|
||||
|
||||
String countryName = settings.BILLING_USER_COUNTRY.get();
|
||||
if (Algorithms.isEmpty(countryName)) {
|
||||
WorldRegion world = getMyApplication().getRegions().getWorldRegion();
|
||||
countryName = world.getLocaleName();
|
||||
}
|
||||
regionNameTextView.setText(countryName);
|
||||
|
||||
emailTextView.setText(settings.BILLING_USER_EMAIL.get());
|
||||
userNameTextView.setText(settings.BILLING_USER_NAME.get());
|
||||
|
||||
subscriptionBanner.setVisibility(View.GONE);
|
||||
subscriptionInfo.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
|
|
|
@ -22,23 +22,19 @@ import com.google.gson.Gson;
|
|||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.BaseOsmAndFragment;
|
||||
import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ReportsFragment extends BaseOsmAndFragment implements SearchSelectionFragment.OnFragmentInteractionListener {
|
||||
public class ReportsFragment extends BaseOsmAndFragment implements CountrySelectionFragment.OnFragmentInteractionListener {
|
||||
public static final String TITLE = "Report";
|
||||
public static final String TOTAL_CHANGES_BY_MONTH_URL_PATTERN = "http://download.osmand.net/" +
|
||||
"reports/query_report.php?report=total_changes_by_month&month=%s®ion=%s";
|
||||
|
@ -50,11 +46,9 @@ public class ReportsFragment extends BaseOsmAndFragment implements SearchSelecti
|
|||
private Spinner montReportsSpinner;
|
||||
private MonthsForReportsAdapter monthsForReportsAdapter;
|
||||
|
||||
CountrySearchSelectionFragment searchSelectionFragment = new CountrySearchSelectionFragment();
|
||||
private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment();
|
||||
private TextView countryNameTextView;
|
||||
|
||||
HashMap<String, String> queryRegionNames = new HashMap<>();
|
||||
ArrayList<String> regionNames = new ArrayList<>();
|
||||
private CountryItem selectedCountryItem;
|
||||
|
||||
private ImageView numberOfContributorsIcon;
|
||||
private ImageView numberOfEditsIcon;
|
||||
|
@ -69,7 +63,6 @@ public class ReportsFragment extends BaseOsmAndFragment implements SearchSelecti
|
|||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
initCountries();
|
||||
View view = inflater.inflate(R.layout.fragment_reports, container, false);
|
||||
montReportsSpinner = (Spinner) view.findViewById(R.id.montReportsSpinner);
|
||||
monthsForReportsAdapter = new MonthsForReportsAdapter(getActivity());
|
||||
|
@ -79,15 +72,15 @@ public class ReportsFragment extends BaseOsmAndFragment implements SearchSelecti
|
|||
regionReportsButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SearchSelectionFragment countrySearchSelectionFragment =
|
||||
searchSelectionFragment;
|
||||
countrySearchSelectionFragment
|
||||
.show(getChildFragmentManager(), "CountriesSearchSelectionFragment");
|
||||
countrySelectionFragment.show(getChildFragmentManager(), "CountriesSearchSelectionFragment");
|
||||
}
|
||||
});
|
||||
|
||||
countrySelectionFragment.initCountries(getMyApplication());
|
||||
selectedCountryItem = countrySelectionFragment.getCountryItems().get(0);
|
||||
|
||||
countryNameTextView = (TextView) regionReportsButton.findViewById(android.R.id.text1);
|
||||
countryNameTextView.setText(regionNames.get(0));
|
||||
countryNameTextView.setText(selectedCountryItem.getLocalName());
|
||||
|
||||
setThemedDrawable(view, R.id.calendarImageView, R.drawable.ic_action_data);
|
||||
setThemedDrawable(view, R.id.regionIconImageView, R.drawable.ic_world_globe_dark);
|
||||
|
@ -127,7 +120,7 @@ public class ReportsFragment extends BaseOsmAndFragment implements SearchSelecti
|
|||
public void requestAndUpdateUi() {
|
||||
int monthItemPosition = montReportsSpinner.getSelectedItemPosition();
|
||||
String monthUrlString = monthsForReportsAdapter.getQueryString(monthItemPosition);
|
||||
String countryUrlString = queryRegionNames.get(countryNameTextView.getText().toString());
|
||||
String countryUrlString = selectedCountryItem.getDownloadName();
|
||||
|
||||
tryUpdateData(monthUrlString, countryUrlString);
|
||||
}
|
||||
|
@ -171,79 +164,12 @@ public class ReportsFragment extends BaseOsmAndFragment implements SearchSelecti
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSearchResult(String name) {
|
||||
countryNameTextView.setText(name);
|
||||
public void onSearchResult(CountryItem item) {
|
||||
selectedCountryItem = item;
|
||||
countryNameTextView.setText(item.getLocalName());
|
||||
requestAndUpdateUi();
|
||||
}
|
||||
|
||||
private void initCountries() {
|
||||
final WorldRegion root = getMyApplication().getRegions().getWorldRegion();
|
||||
ArrayList<WorldRegion> groups = new ArrayList<>();
|
||||
groups.add(root);
|
||||
processGroup(root, groups, getActivity());
|
||||
Collections.sort(groups, new Comparator<WorldRegion>() {
|
||||
@Override
|
||||
public int compare(WorldRegion lhs, WorldRegion rhs) {
|
||||
if (lhs == root) {
|
||||
return -1;
|
||||
}
|
||||
if (rhs == root) {
|
||||
return 1;
|
||||
}
|
||||
return getHumanReadableName(lhs).compareTo(getHumanReadableName(rhs));
|
||||
}
|
||||
});
|
||||
for (WorldRegion group : groups) {
|
||||
String name = getHumanReadableName(group);
|
||||
regionNames.add(name);
|
||||
queryRegionNames.put(name, group == root ? "" : group.getRegionDownloadName());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHumanReadableName(WorldRegion group) {
|
||||
String name;
|
||||
if (group.getLevel() > 2 || (group.getLevel() == 2
|
||||
&& group.getSuperregion().getRegionId().equals(WorldRegion.RUSSIA_REGION_ID))) {
|
||||
WorldRegion parent = group.getSuperregion();
|
||||
WorldRegion parentsParent = group.getSuperregion().getSuperregion();
|
||||
if (group.getLevel() == 3) {
|
||||
if (parentsParent.getRegionId().equals(WorldRegion.RUSSIA_REGION_ID)) {
|
||||
name = parentsParent.getLocaleName() + " " + group.getLocaleName();
|
||||
} else if (!parent.getRegionId().equals(WorldRegion.UNITED_KINGDOM_REGION_ID)) {
|
||||
name = parent.getLocaleName() + " " + group.getLocaleName();
|
||||
} else {
|
||||
name = group.getLocaleName();
|
||||
}
|
||||
} else {
|
||||
name = parent.getLocaleName() + " " + group.getLocaleName();
|
||||
}
|
||||
} else {
|
||||
name = group.getLocaleName();
|
||||
}
|
||||
if (name == null) {
|
||||
name = "";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getQueryString(int position) {
|
||||
return queryRegionNames.get(position);
|
||||
}
|
||||
|
||||
private static void processGroup(WorldRegion group,
|
||||
List<WorldRegion> nameList,
|
||||
Context context) {
|
||||
if (group.isRegionMapDownload()) {
|
||||
nameList.add(group);
|
||||
}
|
||||
|
||||
if (group.getSubregions() != null) {
|
||||
for (WorldRegion g : group.getSubregions()) {
|
||||
processGroup(g, nameList, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MonthsForReportsAdapter extends ArrayAdapter<String> {
|
||||
private static final SimpleDateFormat queryFormat = new SimpleDateFormat("yyyy-MM", Locale.US);
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
|
@ -325,18 +251,6 @@ public class ReportsFragment extends BaseOsmAndFragment implements SearchSelecti
|
|||
}
|
||||
}
|
||||
|
||||
public static class CountrySearchSelectionFragment extends SearchSelectionFragment {
|
||||
@Override
|
||||
protected ArrayList<String> getList() {
|
||||
return ((ReportsFragment) getParentFragment()).regionNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getListItemIcon() {
|
||||
return R.drawable.ic_map;
|
||||
}
|
||||
}
|
||||
|
||||
private void enableProgress() {
|
||||
numberOfContributorsIcon.setImageDrawable(getPaintedContentIcon(R.drawable.ic_group, inactiveColor));
|
||||
numberOfEditsIcon.setImageDrawable(getPaintedContentIcon(R.drawable.ic_map, inactiveColor));
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
package net.osmand.plus.liveupdates;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class SearchSelectionFragment extends BaseOsmAndDialogFragment {
|
||||
private OnFragmentInteractionListener mListener;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_search_list, container, false);
|
||||
ListView listView = (ListView) view.findViewById(android.R.id.list);
|
||||
final ArrayAdapter<String> adapter = new ListAdapter(getActivity(), getListItemIcon());
|
||||
if (getArray() != null) {
|
||||
adapter.addAll(getArray());
|
||||
} else if (getList() != null) {
|
||||
adapter.addAll(getList());
|
||||
} else {
|
||||
throw new RuntimeException("Either getArray() or getList() must return non null value.");
|
||||
}
|
||||
listView.setAdapter(adapter);
|
||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
mListener.onSearchResult(adapter.getItem(position));
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
final EditText searchEditText = (EditText) view.findViewById(R.id.searchEditText);
|
||||
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
adapter.getFilter().filter(s);
|
||||
}
|
||||
});
|
||||
ImageButton clearButton = (ImageButton) view.findViewById(R.id.clearButton);
|
||||
setThemedDrawable(clearButton, R.drawable.ic_action_remove_dark);
|
||||
clearButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof OnFragmentInteractionListener) {
|
||||
mListener = (OnFragmentInteractionListener) context;
|
||||
} else if (getParentFragment() instanceof OnFragmentInteractionListener) {
|
||||
mListener = (OnFragmentInteractionListener) getParentFragment();
|
||||
} else {
|
||||
throw new RuntimeException(context.toString()
|
||||
+ " must implement OnFragmentInteractionListener");
|
||||
}
|
||||
}
|
||||
|
||||
protected String[] getArray() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ArrayList<String> getList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
protected int getListItemIcon() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
public interface OnFragmentInteractionListener {
|
||||
void onSearchResult(String name);
|
||||
}
|
||||
|
||||
private class ListAdapter extends ArrayAdapter<String> {
|
||||
private final Drawable drawableLeft;
|
||||
|
||||
public ListAdapter(Context context, @DrawableRes int drawableLeftId) {
|
||||
super(getMyActivity(), android.R.layout.simple_list_item_1);
|
||||
this.drawableLeft = drawableLeftId == -1 ? null : getContentIcon(drawableLeftId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
TextView view = (TextView) super.getView(position, convertView, parent);
|
||||
view.setCompoundDrawablesWithIntrinsicBounds(drawableLeft, null, null, null);
|
||||
view.setCompoundDrawablePadding(getResources().getDimensionPixelSize(R.dimen.list_content_padding));
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package net.osmand.plus.liveupdates;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -10,27 +9,23 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||
import net.osmand.plus.inapp.InAppHelper;
|
||||
import net.osmand.plus.inapp.InAppHelper.InAppCallbacks;
|
||||
import net.osmand.plus.liveupdates.SearchSelectionFragment.OnFragmentInteractionListener;
|
||||
import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem;
|
||||
import net.osmand.plus.liveupdates.CountrySelectionFragment.OnFragmentInteractionListener;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class SubscriptionFragment extends BaseOsmAndDialogFragment implements InAppCallbacks, OnFragmentInteractionListener{
|
||||
public class SubscriptionFragment extends BaseOsmAndDialogFragment implements InAppCallbacks, OnFragmentInteractionListener {
|
||||
|
||||
public static final String TAG = "SubscriptionFragment";
|
||||
|
||||
|
@ -40,11 +35,9 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
|||
|
||||
private String userName;
|
||||
private String email;
|
||||
private String country;
|
||||
private CountryItem selectedCountryItem;
|
||||
|
||||
ArrayList<String> regionNames = new ArrayList<>();
|
||||
private CountrySearchSelectionFragment searchSelectionFragment
|
||||
= new CountrySearchSelectionFragment();
|
||||
private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -73,8 +66,6 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
|||
}
|
||||
});
|
||||
|
||||
initCountries();
|
||||
|
||||
userName = settings.BILLING_USER_NAME.get();
|
||||
final EditText userNameEdit = (EditText) view.findViewById(R.id.userNameEdit);
|
||||
if (!Algorithms.isEmpty(userName)) {
|
||||
|
@ -87,52 +78,62 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
|||
emailEdit.setText(email);
|
||||
}
|
||||
|
||||
country = settings.BILLING_USER_COUNTRY.get();
|
||||
countrySelectionFragment.initCountries(getMyApplication());
|
||||
String countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get();
|
||||
if (Algorithms.isEmpty(countryDownloadName)) {
|
||||
selectedCountryItem = countrySelectionFragment.getCountryItems().get(0);
|
||||
} else {
|
||||
selectedCountryItem = countrySelectionFragment.getCountryItem(countryDownloadName);
|
||||
}
|
||||
|
||||
final EditText selectCountryEdit = (EditText) view.findViewById(R.id.selectCountryEdit);
|
||||
if (!Algorithms.isEmpty(country)) {
|
||||
selectCountryEdit.setText(country);
|
||||
if (selectedCountryItem != null) {
|
||||
selectCountryEdit.setText(selectedCountryItem.getLocalName());
|
||||
}
|
||||
selectCountryEdit.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
SearchSelectionFragment countrySearchSelectionFragment =
|
||||
searchSelectionFragment;
|
||||
countrySearchSelectionFragment
|
||||
CountrySelectionFragment countryCountrySelectionFragment =
|
||||
countrySelectionFragment;
|
||||
countryCountrySelectionFragment
|
||||
.show(getChildFragmentManager(), "CountriesSearchSelectionFragment");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
updatePrice();
|
||||
updatePrice(view);
|
||||
|
||||
Button subscribeButton = (Button) view.findViewById(R.id.subscribeButton);
|
||||
final Button subscribeButton = (Button) view.findViewById(R.id.subscribeButton);
|
||||
final CheckBox hideUserNameCheckbox = (CheckBox) view.findViewById(R.id.hideUserNameCheckbox);
|
||||
boolean hideUserName = settings.BILLING_HIDE_USER_NAME.get();
|
||||
hideUserNameCheckbox.setChecked(hideUserName);
|
||||
subscribeButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (inAppHelper != null) {
|
||||
userName = userNameEdit.getText().toString().trim();
|
||||
email = emailEdit.getText().toString().trim();
|
||||
country = selectCountryEdit.getText().toString().trim();
|
||||
String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : "";
|
||||
String countryDownloadName = selectedCountryItem != null ? selectedCountryItem.getDownloadName() : "";
|
||||
|
||||
if (Algorithms.isEmpty(userName)) {
|
||||
getMyApplication().showToastMessage("Please enter visible name");
|
||||
return;
|
||||
}
|
||||
if (Algorithms.isEmpty(email) || !AndroidUtils.isValidEmail(email)) {
|
||||
getMyApplication().showToastMessage("Please enter valid E-mail address");
|
||||
return;
|
||||
}
|
||||
if (Algorithms.isEmpty(userName) && !hideUserNameCheckbox.isChecked()) {
|
||||
getMyApplication().showToastMessage("Please enter Public Name");
|
||||
return;
|
||||
}
|
||||
|
||||
settings.BILLING_USER_NAME.set(userName);
|
||||
settings.BILLING_USER_EMAIL.set(email);
|
||||
settings.BILLING_USER_COUNTRY.set(country);
|
||||
settings.BILLING_USER_COUNTRY.set(countryName);
|
||||
settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(countryDownloadName);
|
||||
settings.BILLING_HIDE_USER_NAME.set(hideUserNameCheckbox.isChecked());
|
||||
|
||||
final WorldRegion world = getMyApplication().getRegions().getWorldRegion();
|
||||
String countryParam = country.equals(world.getLocaleName()) ? "" : country;
|
||||
|
||||
inAppHelper.purchaseLiveUpdates(getActivity(), email, userName, countryParam);
|
||||
inAppHelper.purchaseLiveUpdates(getActivity(), email, userName, countryDownloadName);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -165,7 +166,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
|||
|
||||
@Override
|
||||
public void onGetItems() {
|
||||
updatePrice();
|
||||
updatePrice(getView());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -201,18 +202,21 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSearchResult(String name) {
|
||||
public void onSearchResult(CountryItem item) {
|
||||
selectedCountryItem = item;
|
||||
View view = getView();
|
||||
if (view != null) {
|
||||
EditText selectCountryEdit = (EditText) view.findViewById(R.id.selectCountryEdit);
|
||||
if (selectCountryEdit != null) {
|
||||
selectCountryEdit.setText(name);
|
||||
selectCountryEdit.setText(item.getLocalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePrice() {
|
||||
View view = getView();
|
||||
private void updatePrice(View view) {
|
||||
if (view == null) {
|
||||
view = getView();
|
||||
}
|
||||
if (view != null) {
|
||||
TextView priceTextView = (TextView) view.findViewById(R.id.priceTextView);
|
||||
if (InAppHelper.getLiveUpdatesPrice() != null) {
|
||||
|
@ -220,79 +224,4 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initCountries() {
|
||||
final WorldRegion root = getMyApplication().getRegions().getWorldRegion();
|
||||
ArrayList<WorldRegion> groups = new ArrayList<>();
|
||||
groups.add(root);
|
||||
processGroup(root, groups, getActivity());
|
||||
Collections.sort(groups, new Comparator<WorldRegion>() {
|
||||
@Override
|
||||
public int compare(WorldRegion lhs, WorldRegion rhs) {
|
||||
if (lhs == root) {
|
||||
return -1;
|
||||
}
|
||||
if (rhs == root) {
|
||||
return 1;
|
||||
}
|
||||
return getHumanReadableName(lhs).compareTo(getHumanReadableName(rhs));
|
||||
}
|
||||
});
|
||||
for (WorldRegion group : groups) {
|
||||
String name = getHumanReadableName(group);
|
||||
regionNames.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processGroup(WorldRegion group,
|
||||
List<WorldRegion> nameList,
|
||||
Context context) {
|
||||
if (group.isRegionMapDownload()) {
|
||||
nameList.add(group);
|
||||
}
|
||||
|
||||
if (group.getSubregions() != null) {
|
||||
for (WorldRegion g : group.getSubregions()) {
|
||||
processGroup(g, nameList, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHumanReadableName(WorldRegion group) {
|
||||
String name;
|
||||
if (group.getLevel() > 2 || (group.getLevel() == 2
|
||||
&& group.getSuperregion().getRegionId().equals(WorldRegion.RUSSIA_REGION_ID))) {
|
||||
WorldRegion parent = group.getSuperregion();
|
||||
WorldRegion parentsParent = group.getSuperregion().getSuperregion();
|
||||
if (group.getLevel() == 3) {
|
||||
if (parentsParent.getRegionId().equals(WorldRegion.RUSSIA_REGION_ID)) {
|
||||
name = parentsParent.getLocaleName() + " " + group.getLocaleName();
|
||||
} else if (!parent.getRegionId().equals(WorldRegion.UNITED_KINGDOM_REGION_ID)) {
|
||||
name = parent.getLocaleName() + " " + group.getLocaleName();
|
||||
} else {
|
||||
name = group.getLocaleName();
|
||||
}
|
||||
} else {
|
||||
name = parent.getLocaleName() + " " + group.getLocaleName();
|
||||
}
|
||||
} else {
|
||||
name = group.getLocaleName();
|
||||
}
|
||||
if (name == null) {
|
||||
name = "";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static class CountrySearchSelectionFragment extends SearchSelectionFragment {
|
||||
@Override
|
||||
protected ArrayList<String> getList() {
|
||||
return ((SubscriptionFragment) getParentFragment()).regionNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getListItemIcon() {
|
||||
return R.drawable.ic_map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue