diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java b/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java
index 40a551515..7b774b681 100644
--- a/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java
+++ b/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java
@@ -24,7 +24,11 @@ public class Plain extends SaslMechanism {
@Override
public String getClientFirstMessage() {
- final String sasl = '\u0000' + account.getUsername() + '\u0000' + account.getPassword();
- return Base64.encodeToString(sasl.getBytes(Charset.defaultCharset()), Base64.NO_WRAP);
+ return getMessage(account.getUsername(), account.getPassword());
+ }
+
+ public static String getMessage(String username, String password) {
+ final String message = '\u0000' + username + '\u0000' + password;
+ return Base64.encodeToString(message.getBytes(Charset.defaultCharset()), Base64.NO_WRAP);
}
}
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index f401c0f45..b006e3478 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -760,9 +760,11 @@
Please enter your phone number.
Search countries
Verify %s
- %s.]]>
+ %s.]]>
+ We have sent you the SMS again.
Please enter the 6 digit pin below.
Resend SMS
+ Resend SMS (%s)
back
Automatically pasted possible pin from clipboard.
Please enter your 6 digit pin.
@@ -770,4 +772,5 @@
Yes
No
Verifying…
+ Requesting SMS…
diff --git a/src/quick/java/eu/siacs/conversations/services/QuickConversationsService.java b/src/quick/java/eu/siacs/conversations/services/QuickConversationsService.java
index 7b73df8d9..1ce9a78fb 100644
--- a/src/quick/java/eu/siacs/conversations/services/QuickConversationsService.java
+++ b/src/quick/java/eu/siacs/conversations/services/QuickConversationsService.java
@@ -1,8 +1,17 @@
package eu.siacs.conversations.services;
+import android.os.SystemClock;
import android.util.Log;
+import java.io.BufferedWriter;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.util.Collections;
import java.util.Set;
@@ -10,7 +19,9 @@ import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import eu.siacs.conversations.Config;
+import eu.siacs.conversations.crypto.sasl.Plain;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.utils.AccountUtils;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
import io.michaelrocks.libphonenumber.android.Phonenumber;
@@ -18,12 +29,20 @@ import rocks.xmpp.addr.Jid;
public class QuickConversationsService {
+
+ public static final int API_ERROR_OTHER = -1;
+ public static final int API_ERROR_UNKNOWN_HOST = -2;
+ public static final int API_ERROR_CONNECT = -3;
+
+ private static final String BASE_URL = "https://venus.fritz.box:4567";
+
private final XmppConnectionService service;
private final Set mOnVerificationRequested = Collections.newSetFromMap(new WeakHashMap<>());
private final Set mOnVerification = Collections.newSetFromMap(new WeakHashMap<>());
private final AtomicBoolean mVerificationInProgress = new AtomicBoolean(false);
+ private final AtomicBoolean mVerificationRequestInProgress = new AtomicBoolean(false);
QuickConversationsService(XmppConnectionService xmppConnectionService) {
this.service = xmppConnectionService;
@@ -54,31 +73,136 @@ public class QuickConversationsService {
}
public void requestVerification(Phonenumber.PhoneNumber phoneNumber) {
+ final String e164 = PhoneNumberUtilWrapper.normalize(service, phoneNumber);
+
+ /**
+ * GET /authentication/+phoneNumber
+ *
+ * - returns too many requests, (sms ist unterwegs), retry after seconden -- auf jeden fall in nächste activity (verify activity) weiter leiten weil es sein kann das sms noch ankommt
+ * - returns OK; success (auch in activity weiter lassen. aber ohne error paramater; dh send again button is activ; und vielleicht kurzer toast bzw snackbar
+ * - returns invalid request user error wenn die phone number falsch ist
+ */
+ if (mVerificationRequestInProgress.compareAndSet(false, true)) {
+ new Thread(() -> {
+ try {
+
+ Thread.sleep(5000);
+
+ final URL url = new URL(BASE_URL + "/authentication/" + e164);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000);
+ connection.setReadTimeout(Config.SOCKET_TIMEOUT * 1000);
+ final int code = connection.getResponseCode();
+ if (code == 200) {
+ createAccountAndWait(phoneNumber, 0L);
+ } else if (code == 429) {
+ createAccountAndWait(phoneNumber, retryAfter(connection));
+ } else {
+ synchronized (mOnVerificationRequested) {
+ for (OnVerificationRequested onVerificationRequested : mOnVerificationRequested) {
+ onVerificationRequested.onVerificationRequestFailed(code);
+ }
+ }
+ }
+ } catch (Exception e) {
+ final int code = getApiErrorCode(e);
+ synchronized (mOnVerificationRequested) {
+ for (OnVerificationRequested onVerificationRequested : mOnVerificationRequested) {
+ onVerificationRequested.onVerificationRequestFailed(code);
+ }
+ }
+ } finally {
+ mVerificationRequestInProgress.set(false);
+ }
+ }).start();
+ }
+
+
+ }
+
+ private void createAccountAndWait(Phonenumber.PhoneNumber phoneNumber, final long timestamp) {
String local = PhoneNumberUtilWrapper.normalize(service, phoneNumber);
- Log.d(Config.LOGTAG,"requesting verification for "+PhoneNumberUtilWrapper.normalize(service,phoneNumber));
- Account account = new Account(Jid.of(local,"quick.conversations.im",null), CryptoHelper.createPassword(new SecureRandom()));
- account.setOption(Account.OPTION_DISABLED, true);
- account.setOption(Account.OPTION_UNVERIFIED, true);
- service.createAccount(account);
+ Log.d(Config.LOGTAG, "requesting verification for " + PhoneNumberUtilWrapper.normalize(service, phoneNumber));
+ Jid jid = Jid.of(local, "quick.conversations.im", null);
+ Account account = AccountUtils.getFirst(service);
+ if (account == null || !account.getJid().asBareJid().equals(jid.asBareJid())) {
+ if (account != null) {
+ service.deleteAccount(account);
+ }
+ account = new Account(jid, CryptoHelper.createPassword(new SecureRandom()));
+ account.setOption(Account.OPTION_DISABLED, true);
+ account.setOption(Account.OPTION_UNVERIFIED, true);
+ service.createAccount(account);
+ }
synchronized (mOnVerificationRequested) {
- for(OnVerificationRequested onVerificationRequested : mOnVerificationRequested) {
- onVerificationRequested.onVerificationRequested();
+ for (OnVerificationRequested onVerificationRequested : mOnVerificationRequested) {
+ if (timestamp <= 0) {
+ onVerificationRequested.onVerificationRequested();
+ } else {
+ onVerificationRequested.onVerificationRequestedRetryAt(timestamp);
+ }
}
}
}
public void verify(Account account, String pin) {
+ /**
+ * POST /password
+ * authentication gesetzt mit telephone nummber und verification code
+ * body = password
+ *
+ * retry after, too many requests
+ * code wrong
+ * OK (weiterleiten auf publish avatar activity
+ *
+ */
if (mVerificationInProgress.compareAndSet(false, true)) {
new Thread(() -> {
try {
+
Thread.sleep(5000);
- synchronized (mOnVerification) {
- for (OnVerification onVerification : mOnVerification) {
- onVerification.onVerificationFailed();
+
+ final URL url = new URL(BASE_URL + "/password");
+ final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000);
+ connection.setReadTimeout(Config.SOCKET_TIMEOUT * 1000);
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Authorization", Plain.getMessage(account.getUsername(), pin));
+ final OutputStream os = connection.getOutputStream();
+ final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
+ writer.write(account.getPassword());
+ writer.flush();
+ writer.close();
+ os.close();
+ connection.connect();
+ final int code = connection.getResponseCode();
+ if (code == 200) {
+ synchronized (mOnVerification) {
+ for (OnVerification onVerification : mOnVerification) {
+ onVerification.onVerificationSucceeded();
+ }
+ }
+ } else if (code == 429) {
+ final long retryAfter = retryAfter(connection);
+ synchronized (mOnVerification) {
+ for (OnVerification onVerification : mOnVerification) {
+ onVerification.onVerificationRetryAt(retryAfter);
+ }
+ }
+ } else {
+ synchronized (mOnVerification) {
+ for (OnVerification onVerification : mOnVerification) {
+ onVerification.onVerificationFailed(code);
+ }
+ }
+ }
+ } catch (Exception e) {
+ final int code = getApiErrorCode(e);
+ synchronized (mOnVerification) {
+ for (OnVerification onVerification : mOnVerification) {
+ onVerification.onVerificationFailed(code);
}
}
- } catch (InterruptedException e) {
- e.printStackTrace();
} finally {
mVerificationInProgress.set(false);
}
@@ -86,17 +210,46 @@ public class QuickConversationsService {
}
}
+ private static int getApiErrorCode(Exception e) {
+ if (e instanceof UnknownHostException) {
+ return API_ERROR_UNKNOWN_HOST;
+ } else if (e instanceof ConnectException) {
+ return API_ERROR_CONNECT;
+ } else {
+ Log.d(Config.LOGTAG,e.getClass().getName());
+ return API_ERROR_OTHER;
+ }
+ }
+
+ private static long retryAfter(HttpURLConnection connection) {
+ try {
+ return SystemClock.elapsedRealtime() + (Long.parseLong(connection.getHeaderField("Retry-After")) * 1000L);
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
public boolean isVerifying() {
return mVerificationInProgress.get();
}
+ public boolean isRequestingVerification() {
+ return mVerificationRequestInProgress.get();
+ }
+
public interface OnVerificationRequested {
void onVerificationRequestFailed(int code);
+
void onVerificationRequested();
+
+ void onVerificationRequestedRetryAt(long timestamp);
}
public interface OnVerification {
- void onVerificationFailed();
+ void onVerificationFailed(int code);
+
void onVerificationSucceeded();
+
+ void onVerificationRetryAt(long timestamp);
}
}
\ No newline at end of file
diff --git a/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java b/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java
index eae5c7315..24670a31b 100644
--- a/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java
+++ b/src/quick/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java
@@ -30,7 +30,10 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
private static final int REQUEST_CHOOSE_COUNTRY = 0x1234;
private ActivityEnterNumberBinding binding;
+
private String region = null;
+ private boolean requestingVerification = false;
+
private final TextWatcher countryCodeTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@@ -78,6 +81,7 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
super.onCreate(savedInstanceState);
String region = savedInstanceState != null ? savedInstanceState.getString("region") : null;
+ boolean requestingVerification = savedInstanceState != null && savedInstanceState.getBoolean("requesting_verification", false);
if (region != null) {
this.region = region;
} else {
@@ -91,6 +95,7 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
setSupportActionBar((Toolbar) this.binding.toolbar);
this.binding.countryCode.addTextChangedListener(this.countryCodeTextWatcher);
this.binding.countryCode.setText(String.valueOf(PhoneNumberUtilWrapper.getInstance(this).getCountryCodeForRegion(this.region)));
+ setRequestingVerificationState(requestingVerification);
}
@Override
@@ -98,6 +103,7 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
if (this.region != null) {
savedInstanceState.putString("region", this.region);
}
+ savedInstanceState.putBoolean("requesting_verification", this.requestingVerification);
super.onSaveInstanceState(savedInstanceState);
}
@@ -142,9 +148,19 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
}
private void onPhoneNumberEntered(Phonenumber.PhoneNumber phoneNumber) {
+ setRequestingVerificationState(true);
xmppConnectionService.getQuickConversationsService().requestVerification(phoneNumber);
}
+ private void setRequestingVerificationState(boolean requesting) {
+ this.requestingVerification = requesting;
+ this.binding.countryCode.setEnabled(!requesting);
+ this.binding.country.setEnabled(!requesting);
+ this.binding.number.setEnabled(!requesting);
+ this.binding.next.setEnabled(!requesting);
+ this.binding.next.setText(requesting ? R.string.requesting_sms : R.string.next);
+ }
+
@Override
public void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
@@ -160,13 +176,25 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
@Override
public void onVerificationRequestFailed(int code) {
-
+ runOnUiThread(()->{
+ setRequestingVerificationState(false);
+ });
}
@Override
public void onVerificationRequested() {
runOnUiThread(() -> {
- startActivity(new Intent(this,VerifyActivity.class));
+ startActivity(new Intent(this, VerifyActivity.class));
+ finish();
+ });
+ }
+
+ @Override
+ public void onVerificationRequestedRetryAt(long timestamp) {
+ runOnUiThread(() -> {
+ Intent intent = new Intent(this, VerifyActivity.class);
+ intent.putExtra(VerifyActivity.EXTRA_RETRY_SMS_AFTER, timestamp);
+ startActivity(intent);
finish();
});
}
diff --git a/src/quick/java/eu/siacs/conversations/ui/VerifyActivity.java b/src/quick/java/eu/siacs/conversations/ui/VerifyActivity.java
index f1425e272..edecb52ae 100644
--- a/src/quick/java/eu/siacs/conversations/ui/VerifyActivity.java
+++ b/src/quick/java/eu/siacs/conversations/ui/VerifyActivity.java
@@ -8,11 +8,15 @@ import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.Toolbar;
import android.text.Html;
+import android.util.Log;
import android.view.View;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.ActivityVerifyBinding;
import eu.siacs.conversations.entities.Account;
@@ -20,10 +24,14 @@ import eu.siacs.conversations.services.QuickConversationsService;
import eu.siacs.conversations.ui.util.PinEntryWrapper;
import eu.siacs.conversations.utils.AccountUtils;
import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
+import eu.siacs.conversations.utils.TimeframeUtils;
+import io.michaelrocks.libphonenumber.android.NumberParseException;
import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN;
-public class VerifyActivity extends XmppActivity implements ClipboardManager.OnPrimaryClipChangedListener, QuickConversationsService.OnVerification {
+public class VerifyActivity extends XmppActivity implements ClipboardManager.OnPrimaryClipChangedListener, QuickConversationsService.OnVerification, QuickConversationsService.OnVerificationRequested {
+
+ public static final String EXTRA_RETRY_SMS_AFTER = "retry_sms_after";
private ActivityVerifyBinding binding;
private Account account;
@@ -31,14 +39,43 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
private ClipboardManager clipboardManager;
private String pasted = null;
private boolean verifying = false;
+ private boolean requestingVerification = false;
+ private long retrySmsAfter = 0;
+ private final Handler mHandler = new Handler();
+
+
+ private final Runnable SMS_TIMEOUT_UPDATER = new Runnable() {
+ @Override
+ public void run() {
+ if (setTimeoutLabelInResendButton()) {
+ mHandler.postDelayed(this,300);
+ }
+ }
+ };
+
+ private boolean setTimeoutLabelInResendButton() {
+ if (retrySmsAfter != 0) {
+ long remaining = retrySmsAfter - SystemClock.elapsedRealtime();
+ if (remaining >= 0) {
+ binding.resendSms.setEnabled(false);
+ binding.resendSms.setText(getString(R.string.resend_sms_in, TimeframeUtils.resolve(VerifyActivity.this,remaining)));
+ return true;
+ }
+ }
+ binding.resendSms.setEnabled(true);
+ binding.resendSms.setText(R.string.resend_sms);
+ return false;
+ }
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String pin = savedInstanceState != null ? savedInstanceState.getString("pin") : null;
boolean verifying = savedInstanceState != null && savedInstanceState.getBoolean("verifying");
+ boolean requestingVerification = savedInstanceState != null && savedInstanceState.getBoolean("requesting_verification", false);
this.pasted = savedInstanceState != null ? savedInstanceState.getString("pasted") : null;
+ this.retrySmsAfter = savedInstanceState != null ? savedInstanceState.getLong(EXTRA_RETRY_SMS_AFTER,0L) : 0L;
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_verify);
setSupportActionBar((Toolbar) this.binding.toolbar);
this.pinEntryWrapper = new PinEntryWrapper(binding.pinBox);
@@ -47,8 +84,10 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
}
binding.back.setOnClickListener(this::onBackButton);
binding.next.setOnClickListener(this::onNextButton);
+ binding.resendSms.setOnClickListener(this::onResendSmsButton);
clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
setVerifyingState(verifying);
+ setRequestingVerificationState(requestingVerification);
}
private void onBackButton(View view) {
@@ -88,6 +127,15 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
}
}
+ private void onResendSmsButton(View view) {
+ try {
+ xmppConnectionService.getQuickConversationsService().requestVerification(PhoneNumberUtilWrapper.toPhoneNumber(this, account.getJid()));
+ setRequestingVerificationState(true);
+ } catch (NumberParseException e) {
+
+ }
+ }
+
private void setVerifyingState(boolean verifying) {
this.verifying = verifying;
this.binding.back.setText(verifying ? R.string.cancel : R.string.back);
@@ -99,6 +147,17 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
this.binding.progressBar.setIndeterminate(verifying);
}
+ private void setRequestingVerificationState(boolean requesting) {
+ this.requestingVerification = requesting;
+ if (requesting) {
+ this.binding.resendSms.setEnabled(false);
+ this.binding.resendSms.setText(R.string.requesting_sms);
+ } else {
+ setTimeoutLabelInResendButton();
+ }
+
+ }
+
@Override
protected void refreshUiReal() {
@@ -107,18 +166,22 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
@Override
void onBackendConnected() {
xmppConnectionService.getQuickConversationsService().addOnVerificationListener(this);
+ xmppConnectionService.getQuickConversationsService().addOnVerificationRequestedListener(this);
this.account = AccountUtils.getFirst(xmppConnectionService);
if (this.account == null) {
return;
}
- this.binding.weHaveSent.setText(Html.fromHtml(getString(R.string.we_have_sent_you_an_sms, PhoneNumberUtilWrapper.prettyPhoneNumber(this, this.account.getJid()))));
+ this.binding.weHaveSent.setText(Html.fromHtml(getString(R.string.we_have_sent_you_an_sms_to_x, PhoneNumberUtilWrapper.toFormattedPhoneNumber(this, this.account.getJid()))));
setVerifyingState(xmppConnectionService.getQuickConversationsService().isVerifying());
+ setRequestingVerificationState(xmppConnectionService.getQuickConversationsService().isRequestingVerification());
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("pin", this.pinEntryWrapper.getPin());
savedInstanceState.putBoolean("verifying", this.verifying);
+ savedInstanceState.putBoolean("requesting_verification", this.requestingVerification);
+ savedInstanceState.putLong(EXTRA_RETRY_SMS_AFTER, this.retrySmsAfter);
if (this.pasted != null) {
savedInstanceState.putString("pasted", this.pasted);
}
@@ -129,14 +192,19 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
public void onStart() {
super.onStart();
clipboardManager.addPrimaryClipChangedListener(this);
+ if (this.retrySmsAfter > 0) {
+ mHandler.post(SMS_TIMEOUT_UPDATER);
+ }
}
@Override
public void onStop() {
super.onStop();
+ mHandler.removeCallbacks(SMS_TIMEOUT_UPDATER);
clipboardManager.removePrimaryClipChangedListener(this);
if (xmppConnectionService != null) {
xmppConnectionService.getQuickConversationsService().removeOnVerificationListener(this);
+ xmppConnectionService.getQuickConversationsService().removeOnVerificationRequestedListener(this);
}
}
@@ -174,14 +242,49 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
}
@Override
- public void onVerificationFailed() {
+ public void onVerificationFailed(int code) {
runOnUiThread(() -> {
setVerifyingState(false);
});
+ Log.d(Config.LOGTAG,"code="+code);
}
@Override
public void onVerificationSucceeded() {
}
+
+ @Override
+ public void onVerificationRetryAt(long timestamp) {
+
+ }
+
+ //send sms again button callback
+ @Override
+ public void onVerificationRequestFailed(int code) {
+ runOnUiThread(()->{
+ setRequestingVerificationState(false);
+ });
+ Log.d(Config.LOGTAG,"code="+code);
+ }
+
+ //send sms again button callback
+ @Override
+ public void onVerificationRequested() {
+ runOnUiThread(()-> {
+ setRequestingVerificationState(false);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(R.string.we_have_sent_you_the_sms_again);
+ builder.setPositiveButton(R.string.ok, null);
+ builder.create().show();
+ });
+ }
+
+ @Override
+ public void onVerificationRequestedRetryAt(long timestamp) {
+ this.retrySmsAfter = timestamp;
+ runOnUiThread(()-> setRequestingVerificationState(false));
+ mHandler.removeCallbacks(SMS_TIMEOUT_UPDATER);
+ runOnUiThread(SMS_TIMEOUT_UPDATER);
+ }
}
diff --git a/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java b/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java
index 650ba7d0f..bccad767f 100644
--- a/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java
+++ b/src/quick/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java
@@ -41,16 +41,18 @@ public class PhoneNumberUtilWrapper {
return locale.getCountry();
}
- public static String prettyPhoneNumber(Context context, Jid jid) {
- PhoneNumberUtil phoneNumberUtil = getInstance(context);
+ public static String toFormattedPhoneNumber(Context context, Jid jid) {
try {
- Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(jid.getEscapedLocal(), "de");
- return phoneNumberUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
+ return getInstance(context).format(toPhoneNumber(context, jid), PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
} catch (Exception e) {
return jid.getEscapedLocal();
}
}
+ public static Phonenumber.PhoneNumber toPhoneNumber(Context context, Jid jid) throws NumberParseException {
+ return getInstance(context).parse(jid.getEscapedLocal(), "de");
+ }
+
public static String normalize(Context context, String number) throws NumberParseException {
return normalize(context, getInstance(context).parse(number, getUserCountry(context)));
}
diff --git a/src/quick/res/layout/activity_verify.xml b/src/quick/res/layout/activity_verify.xml
index 4d44883a0..6d9d13ef4 100644
--- a/src/quick/res/layout/activity_verify.xml
+++ b/src/quick/res/layout/activity_verify.xml
@@ -39,7 +39,7 @@
android:id="@+id/we_have_sent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/we_have_sent_you_an_sms"
+ android:text="@string/we_have_sent_you_an_sms_to_x"
android:textAppearance="@style/TextAppearance.Conversations.Subhead" />