5
0
mirror of https://github.com/cwinfo/envayasms.git synced 2024-11-09 10:20:25 +00:00

add settings screen for ignored phone numbers; allow user to specify if they want to ignore non-numeric senders and shortcodes

This commit is contained in:
Jesse Young 2011-11-25 19:36:04 -08:00
parent f430ddbe29
commit 22f8c26da1
13 changed files with 317 additions and 85 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.envaya.sms" package="org.envaya.sms"
android:versionCode="15" android:versionCode="16"
android:versionName="2.0.2"> android:versionName="2.0.3">
<uses-sdk android:minSdkVersion="4" /> <uses-sdk android:minSdkVersion="4" />
@ -35,6 +35,9 @@
<activity android:name=".ui.TestPhoneNumbers" android:label="EnvayaSMS : Test Phone Numbers"> <activity android:name=".ui.TestPhoneNumbers" android:label="EnvayaSMS : Test Phone Numbers">
</activity> </activity>
<activity android:name=".ui.IgnoredPhoneNumbers" android:label="EnvayaSMS : Ignored Phone Numbers">
</activity>
<activity android:name=".ui.MessagingInbox" android:label="EnvayaSMS : Forward Inbox"> <activity android:name=".ui.MessagingInbox" android:label="EnvayaSMS : Forward Inbox">
</activity> </activity>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android" <EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/add_test_sender_text" android:id="@+id/add_phone_number_text"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:inputType="phone" android:inputType="phone"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#333333">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10sp"
android:text="@string/ignored_phone_numbers">
</TextView>
<CheckBox android:id="@+id/ignore_shortcodes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="ignoreShortcodesClicked"
android:text="Ignore all shortcodes"
/>
<CheckBox android:id="@+id/ignore_non_numeric"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="ignoreNonNumericClicked"
android:text="Ignore all non-numeric senders"
/>
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
<Button
android:id="@+id/add_phone_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:onClick="addIgnoredPhoneNumber"
android:text="Add Ignored Phone Number" />
</LinearLayout>

View File

@ -8,7 +8,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="10sp" android:padding="10sp"
android:text="@string/test_senders"> android:text="@string/test_phone_numbers">
</TextView> </TextView>
<ListView android:id="@android:id/list" <ListView android:id="@android:id/list"
@ -17,12 +17,12 @@
android:layout_weight="1" /> android:layout_weight="1" />
<Button <Button
android:id="@+id/add_test_phone_number" android:id="@+id/add_phone_number"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="10dp" android:padding="10dp"
android:onClick="addTestSender" android:onClick="addTestPhoneNumber"
android:text="Add Test Sender" /> android:text="Add Test Phone Number" />
</LinearLayout> </LinearLayout>

View File

@ -9,8 +9,11 @@
<string name="retry_now">Retry</string> <string name="retry_now">Retry</string>
<string name="forward_inbox">Fwd Inbox...</string> <string name="forward_inbox">Fwd Inbox...</string>
<string name='service_started'>New SMS will be forwarded to server</string> <string name='service_started'>New SMS will be forwarded to server</string>
<string name='test_senders'>When running EnvayaSMS in Test Mode, <string name='test_phone_numbers'>When running EnvayaSMS in Test Mode,
EnvayaSMS will only forward SMS messages from the phone numbers EnvayaSMS will only forward SMS messages from the phone numbers
listed below. (Incoming SMS messages from other phone numbers will be saved listed below. (Incoming SMS messages from other phone numbers will be saved
in the normal Messaging inbox, and outgoing messages will be ignored.)</string> in the normal Messaging inbox, and outgoing messages will be ignored.)</string>
<string name='ignored_phone_numbers'>
EnvayaSMS will ignore SMS messages from the phone numbers listed below.
Incoming messages from these senders will be saved in the normal Messaging inbox.</string>
</resources> </resources>

View File

@ -56,11 +56,22 @@
<CheckBoxPreference <CheckBoxPreference
android:key="network_failover" android:key="network_failover"
android:title="Network Failover" android:title="Network failover"
android:summaryOff="Do nothing if phone can't connect to server via Wi-Fi" android:summaryOff="Do nothing if phone can't connect to server via Wi-Fi"
android:summaryOn="Automatically switch to mobile data if phone can't connect to server via Wi-Fi" android:summaryOn="Automatically switch to mobile data if phone can't connect to server via Wi-Fi"
></CheckBoxPreference> ></CheckBoxPreference>
<PreferenceScreen
android:key="ignored_numbers"
android:title="Ignored phones"
android:summary="Configure the phone numbers that EnvayaSMS will ignore"
>
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="org.envaya.sms"
android:targetClass="org.envaya.sms.ui.IgnoredPhoneNumbers" />
</PreferenceScreen>
<CheckBoxPreference <CheckBoxPreference
android:key="test_mode" android:key="test_mode"
android:title="Test mode" android:title="Test mode"

View File

@ -431,6 +431,16 @@ public final class App extends Application {
return settings.getBoolean("keep_in_inbox", false); return settings.getBoolean("keep_in_inbox", false);
} }
public boolean ignoreShortcodes()
{
return settings.getBoolean("ignore_shortcodes", true);
}
public boolean ignoreNonNumeric()
{
return settings.getBoolean("ignore_non_numeric", true);
}
public String getPassword() { public String getPassword() {
return settings.getString("password", ""); return settings.getString("password", "");
} }
@ -552,70 +562,134 @@ public final class App extends Application {
} }
private List<String> testPhoneNumbers; private List<String> testPhoneNumbers;
public synchronized List<String> getTestPhoneNumbers()
public List<String> getTestPhoneNumbers()
{ {
if (testPhoneNumbers == null) if (testPhoneNumbers == null)
{ {
testPhoneNumbers = new ArrayList<String>(); testPhoneNumbers = loadStringListSetting("test_phone_numbers");
String phoneNumbersJson = settings.getString("test_phone_numbers", "");
if (phoneNumbersJson.length() > 0)
{
try
{
JSONArray arr = new JSONArray(phoneNumbersJson);
int numSenders = arr.length();
for (int i = 0; i < numSenders; i++)
{
testPhoneNumbers.add(arr.getString(i));
}
}
catch (JSONException ex)
{
logError("Error parsing test phone numbers", ex);
}
}
} }
return testPhoneNumbers; return testPhoneNumbers;
} }
public void addTestPhoneNumber(String phoneNumber) public synchronized void addTestPhoneNumber(String phoneNumber)
{ {
List<String> phoneNumbers = getTestPhoneNumbers(); List<String> phoneNumbers = getTestPhoneNumbers();
log("Added test phone number: " + phoneNumber); log("Added test phone number: " + phoneNumber);
phoneNumbers.add(phoneNumber); phoneNumbers.add(phoneNumber);
saveTestPhoneNumbers(phoneNumbers); saveStringListSetting("test_phone_numbers", phoneNumbers);
} }
public void removeTestPhoneNumber(String phoneNumber) public synchronized void removeTestPhoneNumber(String phoneNumber)
{ {
List<String> phoneNumbers = getTestPhoneNumbers(); List<String> phoneNumbers = getTestPhoneNumbers();
phoneNumbers.remove(phoneNumber); phoneNumbers.remove(phoneNumber);
log("Removed test phone number: " + phoneNumber); log("Removed test phone number: " + phoneNumber);
saveTestPhoneNumbers(phoneNumbers); saveStringListSetting("test_phone_numbers", phoneNumbers);
} }
private void saveTestPhoneNumbers(List<String> phoneNumbers) private List<String> ignoredPhoneNumbers;
public synchronized List<String> getIgnoredPhoneNumbers()
{ {
settings.edit().putString("test_phone_numbers", if (ignoredPhoneNumbers == null)
new JSONArray(phoneNumbers).toString() {
ignoredPhoneNumbers = loadStringListSetting("ignored_phone_numbers");
}
return ignoredPhoneNumbers;
}
public synchronized void addIgnoredPhoneNumber(String phoneNumber)
{
List<String> phoneNumbers = getIgnoredPhoneNumbers();
log("Added ignored phone number: " + phoneNumber);
phoneNumbers.add(phoneNumber);
saveStringListSetting("ignored_phone_numbers", phoneNumbers);
}
public synchronized void removeIgnoredPhoneNumber(String phoneNumber)
{
List<String> phoneNumbers = getIgnoredPhoneNumbers();
phoneNumbers.remove(phoneNumber);
log("Removed ignored phone number: " + phoneNumber);
saveStringListSetting("ignored_phone_numbers", phoneNumbers);
}
public synchronized void saveStringListSetting(String key, List<String> values)
{
settings.edit().putString(key,
new JSONArray(values).toString()
).commit(); ).commit();
} }
public boolean isTestPhoneNumber(String phoneNumber) public synchronized void saveBooleanSetting(String key, boolean value)
{ {
for (String testNumber : getTestPhoneNumbers()) settings.edit().putBoolean(key, value).commit();
}
private List<String> loadStringListSetting(String key)
{ {
// handle inexactness due to various different ways of formatting numbers List<String> values = new ArrayList<String>();
if (testNumber.contains(phoneNumber) || phoneNumber.contains(testNumber)) String valuesJson = settings.getString(key, "");
if (valuesJson.length() > 0)
{ {
return true; try
{
JSONArray arr = new JSONArray(valuesJson);
int numSenders = arr.length();
for (int i = 0; i < numSenders; i++)
{
values.add(arr.getString(i));
} }
} }
catch (JSONException ex)
{
logError("Error parsing setting " + key, ex);
}
}
return values;
}
public boolean isForwardablePhoneNumber(String phoneNumber)
{
if (isTestMode())
{
return getTestPhoneNumbers().contains(phoneNumber);
}
if (getIgnoredPhoneNumbers().contains(phoneNumber))
{
return false; return false;
} }
int numDigits = 0;
int length = phoneNumber.length();
for (int i = 0; i < length; i++)
{
if (Character.isDigit(phoneNumber.charAt(i)))
{
numDigits++;
}
}
if (numDigits == 0)
{
if (ignoreNonNumeric())
{
return false;
}
}
else if (numDigits < 7)
{
if (ignoreShortcodes())
{
return false;
}
}
return true;
}
private HttpClient httpClient; private HttpClient httpClient;
public HttpParams getDefaultHttpParams() public HttpParams getDefaultHttpParams()

View File

@ -43,35 +43,7 @@ public abstract class IncomingMessage extends QueuedMessage {
public boolean isForwardable() public boolean isForwardable()
{ {
if (app.isTestMode() && !app.isTestPhoneNumber(from)) return app.isForwardablePhoneNumber(from);
{
return false;
}
/*
* Don't forward messages from shortcodes or users with
* addresses like 'Vodacom' because they're likely to be
* messages from network, or spam. At least for network
* messages we should let them go in to the Messaging inbox
* because the person managing this phone needs to know
* when they're out of credit, etc.
*
* The minimum length of normal subscriber numbers doesn't
* seem to be specified, but in practice seems to be
* at least 7 digits everywhere.
*/
int fromDigits = 0;
int fromLength = from.length();
for (int i = 0; i < fromLength; i++)
{
if (Character.isDigit(from.charAt(i)))
{
fromDigits++;
}
}
return fromDigits >= 7;
} }
public String getFrom() public String getFrom()

View File

@ -143,12 +143,12 @@ public class Outbox {
return; return;
} }
if (app.isTestMode() && !app.isTestPhoneNumber(to)) if (!app.isForwardablePhoneNumber(to))
{ {
// this is mostly to prevent accidentally sending real messages to // this is mostly to prevent accidentally sending real messages to
// random people while testing... // random people while testing...
notifyMessageStatus(sms, App.STATUS_FAILED, notifyMessageStatus(sms, App.STATUS_FAILED,
"Destination number is not in list of test senders"); "Destination address is not allowed");
return; return;
} }

View File

@ -0,0 +1,131 @@
package org.envaya.sms.ui;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import org.envaya.sms.App;
import org.envaya.sms.R;
public class IgnoredPhoneNumbers extends ListActivity {
private App app;
private CheckBox ignoreNonNumeric;
private CheckBox ignoreShortcodes;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.ignored_phone_numbers);
app = (App)getApplication();
ignoreNonNumeric = (CheckBox)findViewById(R.id.ignore_non_numeric);
ignoreNonNumeric.setChecked(app.ignoreNonNumeric());
ignoreShortcodes = (CheckBox)findViewById(R.id.ignore_shortcodes);
ignoreShortcodes.setChecked(app.ignoreShortcodes());
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
final String phoneNumber = ((TextView) view).getText().toString();
new AlertDialog.Builder(IgnoredPhoneNumbers.this)
.setTitle("Remove Ignored Phone")
.setMessage("Do you want to remove "+phoneNumber
+" from the list of ignored phone numbers?")
.setPositiveButton("OK",
new OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
app.removeIgnoredPhoneNumber(phoneNumber);
updateIgnoredPhoneNumbers();
dialog.dismiss();
}
}
)
.setNegativeButton("Cancel",
new OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
}
)
.show();
}
});
updateIgnoredPhoneNumbers();
}
public void updateIgnoredPhoneNumbers()
{
String[] ignoredNumbers = app.getIgnoredPhoneNumbers().toArray(new String[]{});
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
R.layout.phone_number,
ignoredNumbers);
setListAdapter(arrayAdapter);
}
public void ignoreShortcodesClicked(View v)
{
boolean checked = ignoreShortcodes.isChecked();
app.log("Ignore all shortcodes set to " + (checked ? "ON" : "OFF"));
app.saveBooleanSetting("ignore_shortcodes", checked);
}
public void ignoreNonNumericClicked(View v)
{
boolean checked = ignoreNonNumeric.isChecked();
app.log("Ignore all non-numeric senders set to " + (checked ? "ON" : "OFF"));
app.saveBooleanSetting("ignore_non_numeric", checked);
}
public void addIgnoredPhoneNumber(View v)
{
LayoutInflater factory = LayoutInflater.from(this);
final EditText textEntryView =
(EditText)factory.inflate(R.layout.add_phone_number, null);
new AlertDialog.Builder(this)
.setTitle("Add Ignored Phone")
.setMessage("Enter the phone number that you want to ignore:")
.setView(textEntryView)
.setPositiveButton("OK",
new OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
app.addIgnoredPhoneNumber(textEntryView.getText().toString());
updateIgnoredPhoneNumbers();
dialog.dismiss();
}
}
)
.setNegativeButton("Cancel",
new OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
}
)
.show();
}
}

View File

@ -68,17 +68,17 @@ public class TestPhoneNumbers extends ListActivity {
String[] senders = app.getTestPhoneNumbers().toArray(new String[]{}); String[] senders = app.getTestPhoneNumbers().toArray(new String[]{});
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
R.layout.test_phone_number, R.layout.phone_number,
senders); senders);
setListAdapter(arrayAdapter); setListAdapter(arrayAdapter);
} }
public void addTestSender(View v) public void addTestPhoneNumber(View v)
{ {
LayoutInflater factory = LayoutInflater.from(this); LayoutInflater factory = LayoutInflater.from(this);
final EditText textEntryView = final EditText textEntryView =
(EditText)factory.inflate(R.layout.add_test_phone_number, null); (EditText)factory.inflate(R.layout.add_phone_number, null);
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle("Add Test Phone") .setTitle("Add Test Phone")