Initial import.

This commit is contained in:
Erik C. Thauvin 2008-11-04 08:31:08 +00:00
parent fa089fb10b
commit 6abee2bae2
14 changed files with 695 additions and 0 deletions

15
AndroidManifest.xml Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.thauvin.erik.android.googsms" android:versionCode="1"
android:versionName="0.1">
<uses-permission android:name="android.permission.SEND_SMS" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".GoogSMS" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PrefsScreen" android:label="@string/app_name" />
</application>
</manifest>

BIN
res/drawable/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

11
res/layout/about.xml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:gravity="center">
<TextView android:id="@+id/about_text_fld"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginTop="20dip" android:gravity="center"
android:autoLink="web|email" android:layout_marginBottom="20dip"
android:layout_height="fill_parent" android:layout_width="fill_parent"
android:text="@string/about_txt"></TextView>
</LinearLayout>

26
res/layout/main.xml Normal file
View file

@ -0,0 +1,26 @@
<?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:padding="10dip">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/main_query_lbl"
android:text="@string/main_query_lbl_txt" android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<AutoCompleteTextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="@+id/main_query_fld"
android:singleLine="true"></AutoCompleteTextView>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/main_type_lbl"
android:text="@string/main_type_lbl_txt" android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
<Spinner android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="@+id/main_type_spin"></Spinner>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:paddingTop="10dip">
<Button android:text="@string/main_send_btn_txt" android:id="@+id/main_send_btn"
android:minEms="8" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentRight="true"></Button>
</RelativeLayout>
</LinearLayout>

77
res/values/arrays.xml Normal file
View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="main_type_array">
<item>Search</item>
<item>Web Snippets</item>
<item>Local Search</item>
<item>Local Movies</item>
<item>Local Weather</item>
<item>Airports</item>
<item>Area Codes</item>
<item>Calculator</item>
<item>Currency Conversion</item>
<item>Directions</item>
<item>Flights</item>
<item>Glossary</item>
<item>METAR</item>
<item>Maps</item>
<item>Movies</item>
<item>Products</item>
<item>Q&amp;A</item>
<item>Sports</item>
<item>Stocks</item>
<item>Translation</item>
<item>Weather</item>
<item>Zip Codes</item>
</string-array>
<string-array name="main_cmd_array">
<item>%s</item>
<item>web %s</item>
<item>%s %l</item>
<item>movies %%s %l</item>
<item>weather %l</item>
<item>%s airport</item>
<item>area code %s</item>
<item>%s</item>
<item>%s</item>
<item>directions %s</item>
<item>flight %s</item>
<item>define %s</item>
<item>metar %s</item>
<item>map %s</item>
<item>movies %s</item>
<item>price %s</item>
<item>%s</item>
<item>score %s</item>
<item>stock %s</item>
<item>translate %s</item>
<item>weather %s</item>
<item>zip code %s</item>
</string-array>
<string-array name="main_hint_array">
<item>blockbuster seattle wa</item>
<item>search terms, e.g.: t-mobile g1</item>
<item>business listing, sushi, pizza, etc.</item>
<item>No query or current movie name</item>
<item>No query required</item>
<item>airport code, e.g.: sfo</item>
<item>area code, e.g.: 650</item>
<item>1 us pint in liters, 5+2/2, etc.</item>
<item>8 usd in yen</item>
<item>pasadena ca to 94043</item>
<item>aa 2111, ua 14, etc.</item>
<item>word to define, e.g.: zenith</item>
<item>ICAO airport code, e.g.: khio</item>
<item>5th avenue new york</item>
<item>current movie name boston, ma</item>
<item>ipod 40gb, UPC/ISBN, etc.</item>
<item>india population</item>
<item>NBA/NHL/MLB/NFL/NCAA team</item>
<item>ticker symbol, e.g.: goog</item>
<item>hello in french</item>
<item>new york, ny</item>
<item>90210</item>
</string-array>
</resources>

27
res/values/strings.xml Normal file
View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, GoogSMS</string>
<string name="app_name">GoogSMS</string>
<string name="main_query_lbl_txt">Query:</string>
<string name="main_type_lbl_txt">Type:</string>
<string name="main_send_btn_txt">Send via SMS</string>
<string name="main_sms_sent_txt">Your message was sent.</string>
<string name="main_query_err_txt">Please enter a query...</string>
<string name="main_location_err_txt">Please set your location...</string>
<string name="default_google_sms">466453</string>
<string name="about_txt">© 2008 Erik C. Thauvin\nAll Rights Reserved\n\nerik@thauvin.net\n\nhttp://mobile.thauvin.net</string>
<string name="about_menu_txt">About</string>
<string name="prefs_menu_txt">Preferences</string>
<string name="alert_dialog_ok">OK</string>
<string name="prefs_dialog_title">Preferences</string>
<string name="prefs_location_dialog_title">Set Your Location...</string>
<string name="prefs_location_title">Location</string>
<string name="prefs_location_summary">Your current city and state or zip.</string>
<string name="prefs_location_hint">e.g.: san francisco ca or 94123</string>
<string name="prefs_sms_dialog_title">Set SMS Number...</string>
<string name="prefs_sms_title">Google SMS</string>
<string name="prefs_sms_summary">The short code or number of the Google SMS service.</string>
<string name="prefs_sms_hint">e.g.: 466453</string>
<string name="prefs_key_sms">prefs_sms</string>
<string name="prefs_key_loc">prefs_loc</string>
</resources>

12
res/xml/prefs.xml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/prefs_dialog_title">
<EditTextPreference android:title="@string/prefs_location_title"
android:summary="@string/prefs_location_summary" android:dialogTitle="@string/prefs_location_dialog_title"
android:key="@string/prefs_key_loc" android:hint="@string/prefs_location_hint" android:singleLine="true"/>
<EditTextPreference android:title="@string/prefs_sms_title"
android:summary="@string/prefs_sms_summary" android:dialogTitle="@string/prefs_sms_dialog_title"
android:key="@string/prefs_key_sms" android:numeric="integer"
android:hint="@string/prefs_sms_hint" android:singleLine="true"/>
</PreferenceCategory>
</PreferenceScreen>

BIN
screenshots/1.psd Normal file

Binary file not shown.

BIN
screenshots/2.psd Normal file

Binary file not shown.

BIN
screenshots/googsms.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

10
sign.bat Normal file
View file

@ -0,0 +1,10 @@
@echo off
"%JAVA_HOME%\bin\jarsigner" -verbose -keystore "%USERPROFILE%\personal\android.keystore" "%1" android
if errorlevel 1 goto ERROR
"%JAVA_HOME%\bin\jarsigner" -verify "%1"
if errorlevel 1 goto ERROR
goto DONE
:ERROR
@pause
:DONE
@echo on

View file

@ -0,0 +1,390 @@
/*
* @(#)GoogSMS.java
*
* Copyright (c) 2008, Erik C. Thauvin (http://erik.thauvin.net/)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the authors nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*
*/
package net.thauvin.erik.android.googsms;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.telephony.gsm.SmsManager;
import android.text.ClipboardManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;
/**
* The <code>GoogSMS</code> class implements a simple front-end for Google SMS.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @version $Revision$, $Date$
* @created Nov 2, 2008
* @since 1.0
*/
public class GoogSMS extends Activity
{
private static final int MAX_HISTORY_SIZE = 15;
private static final int MENU_ABOUT = 0;
private static final int MENU_PREFS = 1;
private static final String PREFS_HISTORY = "history";
private final List<String> mHistory = new ArrayList<String>(MAX_HISTORY_SIZE);
private String mLocation;
private String mSmsNumber;
/**
* Adds to the history.
*
* @param entry The entry to add.
*/
private void addHistory(String entry)
{
if (!mHistory.contains(entry))
{
if (mHistory.size() >= MAX_HISTORY_SIZE)
{
mHistory.remove(0);
}
mHistory.add(entry);
final SharedPreferences settings = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = settings.edit();
editor.putString(PREFS_HISTORY, TextUtils.join(",", mHistory));
editor.commit();
}
}
/**
* Returns the location.
*
* @return the location
*/
private String getLocation()
{
return mLocation;
}
/**
* Returns the SMS service number.
*
* @return the SMS number
*/
private String getSmsNumber()
{
return mSmsNumber;
}
/**
* Returns the current version number.
*
* @return The current version number or empty.
*/
private String getVersionNumber()
{
try
{
return getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
}
catch (final NameNotFoundException e)
{
return "";
}
}
/**
* Returns whether the location has been set.
*
* @return <code>true</code> if set, <code>false</code> otherwise.
*/
private boolean hasLocation()
{
return !TextUtils.isEmpty(mLocation);
}
/**
* Initializes the various controls.
*/
private void init()
{
loadPrefs();
final AutoCompleteTextView queryFld = (AutoCompleteTextView) findViewById(R.id.main_query_fld);
final Spinner typeSpin = (Spinner) findViewById(R.id.main_type_spin);
final Button sendBtn = (Button) findViewById(R.id.main_send_btn);
final SharedPreferences settings = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
setHistory(settings.getString(PREFS_HISTORY, ""));
setAutoComplete(queryFld);
final ArrayAdapter<CharSequence> typeAdapter = ArrayAdapter.createFromResource(this, R.array.main_type_array,
android.R.layout.simple_spinner_item);
typeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
typeSpin.setAdapter(typeAdapter);
final ClipboardManager clip = (ClipboardManager) getSystemService(android.content.Context.CLIPBOARD_SERVICE);
if (clip.hasText())
{
queryFld.setText(clip.getText());
}
final String[] hints = getResources().getStringArray(R.array.main_hint_array);
final String[] cmds = getResources().getStringArray(R.array.main_cmd_array);
typeSpin.setOnItemSelectedListener(new Spinner.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
queryFld.setHint(hints[position]);
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
; // do nothing
}
});
sendBtn.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View view)
{
final String localToken = "%l";
final String searchToken = "%s";
final String optSearchToken = "%%s";
final String cmd = cmds[typeSpin.getSelectedItemPosition()];
final String query = queryFld.getText().toString();
final boolean isLocal = (cmd.indexOf(localToken) != -1);
final boolean isQuery = (cmd.indexOf(searchToken) != -1);
final boolean isOptQuery = (cmd.indexOf(optSearchToken) != -1);
if ((!isOptQuery) && TextUtils.isEmpty(query) && isQuery)
{
Toast.makeText(GoogSMS.this, R.string.main_query_err_txt, Toast.LENGTH_SHORT).show();
}
else if (!hasLocation() && isLocal)
{
Toast.makeText(GoogSMS.this, R.string.main_location_err_txt, Toast.LENGTH_SHORT).show();
launchPrefs();
}
else
{
final String s1;
if (isLocal)
{
s1 = cmd.replace(localToken, getLocation());
}
else
{
s1 = cmd;
}
final String s2;
if (isOptQuery)
{
if (TextUtils.isEmpty(query))
{
s2 = s1.replace(' ' + optSearchToken, "");
}
else
{
s2 = s1.replace(optSearchToken, query);
}
}
else if (isQuery)
{
s2 = s1.replace(searchToken, query);
}
else
{
s2 = s1;
}
final SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(getSmsNumber(), null, s2, null, null);
addHistory(query);
setAutoComplete(queryFld);
Toast.makeText(GoogSMS.this, R.string.main_sms_sent_txt, Toast.LENGTH_SHORT).show();
Log.v("SMS SENT: ", s2);
}
}
});
}
/**
* Launches the preferences screen.
*/
private void launchPrefs()
{
startActivity(new Intent(this, PrefsScreen.class));
}
/**
* Loads the preferences.
*
* @param isFirst The first call flag.
*/
public void loadPrefs()
{
final SharedPreferences settings = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
setLocation(settings.getString(getString(R.string.prefs_key_loc), ""));
setSmsNumber(settings.getString(getString(R.string.prefs_key_sms), getString(R.string.default_google_sms)));
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(0, MENU_ABOUT, 0, R.string.about_menu_txt).setIcon(android.R.drawable.ic_menu_info_details);
menu.add(0, MENU_PREFS, 0, R.string.prefs_menu_txt).setIcon(android.R.drawable.ic_menu_preferences);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == MENU_ABOUT)
{
final LayoutInflater factory = LayoutInflater.from(this);
final View aboutView = factory.inflate(R.layout.about, null);
new AlertDialog.Builder(this).setView(aboutView).setIcon(android.R.drawable.ic_dialog_info).setTitle(
getString(R.string.app_name) + ' ' + getVersionNumber()).setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
// do nothing
}
}).show();
return true;
}
else if (item.getItemId() == MENU_PREFS)
{
launchPrefs();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume()
{
super.onResume();
loadPrefs();
}
/**
* Sets the auto-complete values of the specified field.
*
* @param field The field to the auto-complete for.
*/
private void setAutoComplete(AutoCompleteTextView field)
{
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, mHistory);
field.setAdapter(adapter);
}
/**
* Sets the history.
*
* @param history The comma-delimited history string.
*/
private void setHistory(String history)
{
final String[] entries = TextUtils.split(history, ",");
for (final String entry : entries)
{
mHistory.add(entry);
}
}
/**
* Sets the location.
*
* @param location the location to set
*/
private void setLocation(String location)
{
mLocation = location;
}
/**
* Sets the SMS service number.
*
* @param smsNumber the SMS number to set
*/
private void setSmsNumber(String smsNumber)
{
mSmsNumber = smsNumber;
}
}

View file

@ -0,0 +1,65 @@
/*
* @(#)PrefsScreen.java
*
* Copyright (c) 2008, Erik C. Thauvin (http://erik.thauvin.net/)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the authors nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*
*/
package net.thauvin.erik.android.googsms;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.widget.TextView;
/**
* The <code>GoogSMS</code> class implements a the preferences screen for Google SMS.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @version $Revision$, $Date$
* @created Nov 2, 2008
* @since 1.0
*/
public class PrefsScreen extends PreferenceActivity
{
public TextView mLocationHint;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(getString(R.string.app_name));
addPreferencesFromResource(R.xml.prefs);
}
}

View file

@ -0,0 +1,62 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package net.thauvin.erik.android.googsms;
public final class R {
public static final class array {
public static final int main_cmd_array=0x7f050001;
public static final int main_hint_array=0x7f050002;
public static final int main_type_array=0x7f050000;
}
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class id {
public static final int about_text_fld=0x7f070000;
public static final int main_query_fld=0x7f070002;
public static final int main_query_lbl=0x7f070001;
public static final int main_send_btn=0x7f070005;
public static final int main_type_lbl=0x7f070003;
public static final int main_type_spin=0x7f070004;
}
public static final class layout {
public static final int about=0x7f030000;
public static final int main=0x7f030001;
}
public static final class string {
public static final int about_menu_txt=0x7f06000a;
public static final int about_txt=0x7f060009;
public static final int alert_dialog_ok=0x7f06000c;
public static final int app_name=0x7f060001;
public static final int default_google_sms=0x7f060008;
public static final int hello=0x7f060000;
public static final int main_location_err_txt=0x7f060007;
public static final int main_query_err_txt=0x7f060006;
public static final int main_query_lbl_txt=0x7f060002;
public static final int main_send_btn_txt=0x7f060004;
public static final int main_sms_sent_txt=0x7f060005;
public static final int main_type_lbl_txt=0x7f060003;
public static final int prefs_dialog_title=0x7f06000d;
public static final int prefs_key_loc=0x7f060017;
public static final int prefs_key_sms=0x7f060016;
public static final int prefs_location_dialog_title=0x7f06000e;
public static final int prefs_location_hint=0x7f060011;
public static final int prefs_location_summary=0x7f060010;
public static final int prefs_location_title=0x7f06000f;
public static final int prefs_menu_txt=0x7f06000b;
public static final int prefs_sms_dialog_title=0x7f060012;
public static final int prefs_sms_hint=0x7f060015;
public static final int prefs_sms_summary=0x7f060014;
public static final int prefs_sms_title=0x7f060013;
}
public static final class xml {
public static final int prefs=0x7f040000;
}
}