diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 88416f45b1..2f7eb76a81 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -62,6 +62,11 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index eacd477392..08564888c8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -120,6 +120,11 @@
Invalid Passphrase!
+
+ You must specify an MMSC URL for your carrier.
+ MMS Settings Updated
+ You can modify these values from the TextSecure settings menu at any time.
+
ERROR:\n\nYou have received a corrupted public key. This key can not be processed, please re-initiate a secure session.
ERROR:\n\nYou have received a public key from an unsupported version of the protocol. This key can not be processed, please re-initiate a secure session.
@@ -295,6 +300,13 @@
TEXTSECURE PASSPHRASE
Unlock
+
+ TextSecure requires APN settings to deliver media messages via your wireless carrier. Your device does not make this information available, which is occasionally true for locked devices and other restrictive configurations.
+ To send media messages, please complete the necessary APN information below. The values for your carrier can generally be located by searching for \'<your carrier> APN\'. You will only need to do this once.
+ MMSC URL (REQUIRED):
+ MMS PROXY HOST (OPTIONAL):
+ MMS PROXY PORT (OPTIONAL):
+
Session
Identities
diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java
index 94b4e84587..1de2fe1f51 100644
--- a/src/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationActivity.java
@@ -58,6 +58,7 @@ import org.thoughtcrime.securesms.database.DraftDatabase.Draft;
import org.thoughtcrime.securesms.mms.AttachmentManager;
import org.thoughtcrime.securesms.mms.AttachmentTypeSelectorAdapter;
import org.thoughtcrime.securesms.mms.MediaTooLargeException;
+import org.thoughtcrime.securesms.mms.MmsSendHelper;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
@@ -120,6 +121,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
private Recipients recipients;
private long threadId;
private boolean isEncryptedConversation;
+ private boolean isMmsEnabled = true;
private CharacterCalculator characterCalculator = new CharacterCalculator();
@@ -137,9 +139,11 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
}
@Override
- protected void onPause() {
- super.onPause();
- MessageNotifier.setVisibleThread(-1L);
+ protected void onStart() {
+ super.onStart();
+
+ if (!isExistingConversation())
+ initializeRecipientsInput();
}
@Override
@@ -147,6 +151,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
super.onResume();
initializeSecurity();
initializeTitleBar();
+ initializeMmsEnabledCheck();
calculateCharactersRemaining();
MessageNotifier.setVisibleThread(threadId);
@@ -154,11 +159,9 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
}
@Override
- protected void onStart() {
- super.onStart();
-
- if (!isExistingConversation())
- initializeRecipientsInput();
+ protected void onPause() {
+ super.onPause();
+ MessageNotifier.setVisibleThread(-1L);
}
@Override
@@ -369,11 +372,15 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
}
private void handleAddAttachment() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setIcon(R.drawable.ic_dialog_attach);
- builder.setTitle(R.string.ConversationActivity_add_attachment);
- builder.setAdapter(attachmentAdapter, new AttachmentTypeListener());
- builder.show();
+ if (this.isMmsEnabled) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setIcon(R.drawable.ic_dialog_attach);
+ builder.setTitle(R.string.ConversationActivity_add_attachment);
+ builder.setAdapter(attachmentAdapter, new AttachmentTypeListener());
+ builder.show();
+ } else {
+ startActivity(new Intent(this, PromptApnActivity.class));
+ }
}
///// Initializers
@@ -472,6 +479,20 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
calculateCharactersRemaining();
}
+ private void initializeMmsEnabledCheck() {
+ new AsyncTask() {
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ return MmsSendHelper.hasNecessaryApnDetails(ConversationActivity.this);
+ }
+
+ @Override
+ protected void onPostExecute(Boolean isMmsEnabled) {
+ ConversationActivity.this.isMmsEnabled = isMmsEnabled;
+ }
+ }.execute();
+ }
+
private void initializeResources() {
recipientsPanel = (RecipientsPanel)findViewById(R.id.recipients);
recipients = getIntent().getParcelableExtra("recipients");
diff --git a/src/org/thoughtcrime/securesms/PromptApnActivity.java b/src/org/thoughtcrime/securesms/PromptApnActivity.java
new file mode 100644
index 0000000000..d3d6978aac
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/PromptApnActivity.java
@@ -0,0 +1,86 @@
+package org.thoughtcrime.securesms;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import org.thoughtcrime.securesms.util.Util;
+
+public class PromptApnActivity extends PassphraseRequiredSherlockActivity {
+
+ private EditText mmsc;
+ private EditText proxyHost;
+ private EditText proxyPort;
+
+ private Button okButton;
+ private Button cancelButton;
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ setContentView(R.layout.prompt_apn_activity);
+
+ initializeResources();
+ initializeValues();
+ }
+
+ private void initializeValues() {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ mmsc.setText(preferences.getString(ApplicationPreferencesActivity.MMSC_HOST_PREF, ""));
+ proxyHost.setText(preferences.getString(ApplicationPreferencesActivity.MMSC_PROXY_HOST_PREF, ""));
+ proxyPort.setText(preferences.getString(ApplicationPreferencesActivity.MMSC_PROXY_PORT_PREF, ""));
+ }
+
+ private void initializeResources() {
+ this.mmsc = (EditText)findViewById(R.id.mmsc_url);
+ this.proxyHost = (EditText)findViewById(R.id.mms_proxy_host);
+ this.proxyPort = (EditText)findViewById(R.id.mms_proxy_port);
+ this.okButton = (Button)findViewById(R.id.ok_button);
+ this.cancelButton = (Button)findViewById(R.id.cancel_button);
+
+ this.okButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ handleSettings();
+ }
+ });
+
+ this.cancelButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+ }
+
+ private void handleSettings() {
+ if (Util.isEmpty(mmsc)) {
+ Toast.makeText(this, R.string.PromptApnActivity_you_must_specify_an_mmsc_url_for_your_carrier, Toast.LENGTH_LONG).show();
+ return;
+ }
+
+ PreferenceManager.getDefaultSharedPreferences(this).edit()
+ .putBoolean(ApplicationPreferencesActivity.USE_LOCAL_MMS_APNS_PREF, true)
+ .putString(ApplicationPreferencesActivity.MMSC_HOST_PREF, mmsc.getText().toString().trim())
+ .putString(ApplicationPreferencesActivity.MMSC_PROXY_HOST_PREF, proxyHost.getText().toString().trim())
+ .putString(ApplicationPreferencesActivity.MMSC_PROXY_PORT_PREF, proxyPort.getText().toString().trim())
+ .commit();
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.PromptApnActivity_mms_settings_updated);
+ builder.setMessage(R.string.PromptApnActivity_you_can_modify_these_values_from_the_textsecure_settings_menu_at_any_time_);
+ builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
+ builder.show();
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/mms/MmsCommunication.java b/src/org/thoughtcrime/securesms/mms/MmsCommunication.java
index da0076cb0d..eed4d4624d 100644
--- a/src/org/thoughtcrime/securesms/mms/MmsCommunication.java
+++ b/src/org/thoughtcrime/securesms/mms/MmsCommunication.java
@@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.service.MmsDownloader;
import org.thoughtcrime.securesms.util.Conversions;
+import org.thoughtcrime.securesms.util.Util;
import java.io.DataInputStream;
import java.io.IOException;
@@ -85,7 +86,7 @@ public class MmsCommunication {
port = cursor.getString(cursor.getColumnIndexOrThrow("mmsport"));
}
- if (mmsc != null && !mmsc.equals(""))
+ if (!Util.isEmpty(mmsc))
return new MmsConnectionParameters(mmsc, proxy, port);
} while (cursor.moveToNext());
diff --git a/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java b/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java
index bb727a2d4b..174ba59b31 100644
--- a/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java
+++ b/src/org/thoughtcrime/securesms/mms/MmsSendHelper.java
@@ -17,6 +17,7 @@
package org.thoughtcrime.securesms.mms;
import android.content.Context;
+import android.net.ConnectivityManager;
import android.net.http.AndroidHttpClient;
import android.util.Log;
@@ -26,6 +27,7 @@ import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
+import org.thoughtcrime.securesms.service.MmscProcessor;
import ws.com.google.android.mms.pdu.PduParser;
import ws.com.google.android.mms.pdu.SendConf;
@@ -84,4 +86,17 @@ public class MmsSendHelper extends MmsCommunication {
throw new IOException("Failed to get MMSC information...");
}
}
+
+ public static boolean hasNecessaryApnDetails(Context context) {
+ try {
+ ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ String apn = connectivityManager.getNetworkInfo(MmscProcessor.TYPE_MOBILE_MMS).getExtraInfo();
+
+ MmsCommunication.getMmsConnectionParameters(context, apn, true);
+ return true;
+ } catch (ApnUnavailableException e) {
+ Log.w("MmsSendHelper", e);
+ return false;
+ }
+ }
}