Cleaned up code

This commit is contained in:
2012-07-22 09:37:28 -04:00
parent 19b5c13206
commit f06f790b48
37 changed files with 2889 additions and 2692 deletions

View File

@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.TwentyCodes.android.LocationRinger"
android:installLocation="internalOnly"
android:versionCode="65"
android:versionName="c708c3d" >
android:versionCode="67"
android:versionName="19b5c13" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>

View File

@@ -8,6 +8,7 @@ package com.TwentyCodes.android.LocationRinger;
/**
* A simple listener to allow fragments to set scrolling enabled
*
* @author ricky
*/
public interface EnableScrollingListener {

View File

@@ -10,12 +10,14 @@ import android.support.v4.app.Fragment;
/**
* This interface will be used to notify
*
* @author ricky barrette
*/
public interface FeatureRemovedListener {
/**
* Called when a feature is removed from the list
*
* @author ricky barrette
*/
public void onFeatureRemoved(Fragment fragment);

View File

@@ -8,16 +8,17 @@ package com.TwentyCodes.android.LocationRinger;
import android.content.ContentValues;
/**
* This interface will be used to pass the content updated in fragments down to the main FragmentActivity
* This interface will be used to pass the content updated in fragments down to
* the main FragmentActivity
*
* @author ricky
*/
public interface OnContentChangedListener {
void onRingerContentChanged(ContentValues ringer);
void onInfoContentChanged(ContentValues info);
void onInfoContentRemoved(String... keys);
void onRingerContentChanged(ContentValues ringer);
}

View File

@@ -7,13 +7,16 @@
package com.TwentyCodes.android.LocationRinger;
/**
* A simple interface to allow a compent other than an activity to handle a seach event
* A simple interface to allow a compent other than an activity to handle a
* seach event
*
* @author ricky barrette
*/
public interface SearchRequestedListener {
/**
* Called when the a seach is request via seach button
*
* @return
* @author ricky barrette
*/

View File

@@ -7,17 +7,19 @@
package com.TwentyCodes.android.LocationRinger.db;
/**
* This interface will be used to listen to see when the database events are complete
* This interface will be used to listen to see when the database events are
* complete
*
* @author ricky barrette
*/
public interface DatabaseListener {
public void onDatabaseUpgradeComplete();
public void onDatabaseUpgrade();
public void onRingerDeletionComplete();
public void onDatabaseUpgradeComplete();
public void onRestoreComplete();
public void onDatabaseUpgrade();
public void onRingerDeletionComplete();
}

View File

@@ -32,123 +32,48 @@ import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This class will be the main interface between location ringer and it's database
* This class will be the main interface between location ringer and it's
* database
*
* @author ricky barrette
*/
public class RingerDatabase {
private static final String TAG = "RingerDatabase";
private final Context mContext;
private SQLiteDatabase mDb;
private static DatabaseListener mListener;
public boolean isUpgrading = false;
private final static Handler mHandler;
protected static final int DELETIONCOMPLETE = 0;
protected static final int DATABASEUPGRADECOMPLETE = 1;
static{
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(mListener != null)
switch(msg.what){
case DELETIONCOMPLETE:
mListener.onRingerDeletionComplete();
break;
case DATABASEUPGRADECOMPLETE:
mListener.onDatabaseUpgradeComplete();
break;
}
}
};
}
/*
* database information values
*/
private final int DATABASE_VERSION = 4;
/*
* the following is for the table that holds the other table names
*/
private final String DATABASE_NAME = "ringers.db";
private final String RINGER_TABLE = "ringers";
private static final String RINGER_INFO_TABLE = "ringer_info";
/*
* Database keys
*/
@Deprecated
public final static String KEY_LOCATION_LAT = "location_lat";
@Deprecated
public final static String KEY_LOCATION_LON = "location_lon";
@Deprecated
public final static String KEY_RINGTONE = "home_ringtone";
@Deprecated
public final static String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
@Deprecated
public final static String KEY_RINGTONE_IS_SILENT = "ringtone_is_silent";
@Deprecated
public final static String KEY_NOTIFICATION_IS_SILENT = "notification_is_silent";
public final static String KEY_IS_ENABLED = "is_enabled";
public final static String KEY_RADIUS = "radius";
public final static String KEY_RINGER_NAME = "ringer_name";
public final static String KEY_LOCATION = "location";
public final static String KEY_RINGTONE_URI = "ringtone_uri";
public final static String KEY_NOTIFICATION_RINGTONE_URI = "away_notification_uri";
public final static String KEY_RINGTONE_VOLUME = "ringtone_volume";
public final static String KEY_NOTIFICATION_RINGTONE_VOLUME = "notification_ringtone_volume";
public final static String KEY_WIFI = "wifi";
public final static String KEY_BT = "bt";
public final static String KEY_MUSIC_VOLUME = "music_volume";
public final static String KEY_ALARM_VOLUME = "alarm_volume";
public static final String KEY_VALUE = "value";
public static final String KEY = "key";
public static final String KEY_UPDATE_INTERVAL = "update_interval";
public static final String KEY_PLUS_BUTTON_HINT = "plus_button_hint";
public static final String KEY_DTMF_VOLUME = "dtmf_volume";
public static final String KEY_SYSTEM_VOLUME = "system_volume";
public static final String KEY_CALL_VOLUME = "call_volume";
public static final String KEY_RINGER_DESCRIPTION = "ringer_description";
/**
* A helper class to manage database creation and version management.
*
* @author ricky barrette
*/
private class OpenHelper extends SQLiteOpenHelper {
/**
* Creates a new OpenHelper
*
* @param context
* @author ricky barrette
*/
public OpenHelper(Context context) {
public OpenHelper(final Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* Converts the database from version 2 to 3
*
* @param db
* @author ricky barrette
*/
private void convert2to3(SQLiteDatabase db){
private void convert2to3(final SQLiteDatabase db) {
// get all the ringer information from the old table
final Cursor cursor = db.query("two", new String[] { KEY_RINGER_NAME, KEY_RINGTONE,
KEY_NOTIFICATION_RINGTONE, KEY_RINGTONE_IS_SILENT,
KEY_NOTIFICATION_IS_SILENT, KEY_IS_ENABLED,
KEY_RADIUS, KEY_LOCATION_LAT, KEY_LOCATION_LON,
KEY_RINGTONE_URI, KEY_NOTIFICATION_RINGTONE_URI,
KEY_RINGTONE_VOLUME, KEY_NOTIFICATION_RINGTONE_VOLUME,
KEY_WIFI, KEY_BT, KEY_MUSIC_VOLUME, KEY_ALARM_VOLUME
}, null, null, null, null, null);
final Cursor cursor = db.query("two", new String[] { KEY_RINGER_NAME, KEY_RINGTONE, KEY_NOTIFICATION_RINGTONE, KEY_RINGTONE_IS_SILENT,
KEY_NOTIFICATION_IS_SILENT, KEY_IS_ENABLED, KEY_RADIUS, KEY_LOCATION_LAT, KEY_LOCATION_LON, KEY_RINGTONE_URI, KEY_NOTIFICATION_RINGTONE_URI,
KEY_RINGTONE_VOLUME, KEY_NOTIFICATION_RINGTONE_VOLUME, KEY_WIFI, KEY_BT, KEY_MUSIC_VOLUME, KEY_ALARM_VOLUME }, null, null, null, null, null);
/*
* iterate through the database moving data over to the version 3 tables
* iterate through the database moving data over to the version 3
* tables
*/
int count = cursor.getColumnCount();
if (cursor.moveToFirst()) {
final int count = cursor.getColumnCount();
if (cursor.moveToFirst())
do {
final ContentValues ringer = new ContentValues();
if (Debug.DEBUG)
@@ -173,7 +98,7 @@ public class RingerDatabase {
ringer.put(KEY_LOCATION_LON, cursor.getString(i));
break;
default:
ContentValues values = new ContentValues();
final ContentValues values = new ContentValues();
values.put(KEY_RINGER_NAME, cursor.getString(0));
values.put(KEY, cursor.getColumnName(i));
values.put(KEY_VALUE, cursor.getString(i));
@@ -182,62 +107,54 @@ public class RingerDatabase {
}
db.insert(RINGER_TABLE, null, ringer);
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
if (cursor != null && !cursor.isClosed())
cursor.close();
}
}
/**
* Creates the initial database structure
*
* @param db
* @author ricky barrette
*/
private void createDatabase(SQLiteDatabase db){
db.execSQL("CREATE TABLE " + RINGER_TABLE +
"(id INTEGER PRIMARY KEY, " +
KEY_RINGER_NAME+" TEXT, " +
KEY_IS_ENABLED+" TEXT)");
db.execSQL("CREATE TABLE " + RINGER_INFO_TABLE +
"(id INTEGER PRIMARY KEY, " +
KEY_RINGER_NAME+" TEXT, " +
KEY+" TEXT, " +
KEY_VALUE+" TEXT)");
private void createDatabase(final SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + RINGER_TABLE + "(id INTEGER PRIMARY KEY, " + KEY_RINGER_NAME + " TEXT, " + KEY_IS_ENABLED + " TEXT)");
db.execSQL("CREATE TABLE " + RINGER_INFO_TABLE + "(id INTEGER PRIMARY KEY, " + KEY_RINGER_NAME + " TEXT, " + KEY + " TEXT, " + KEY_VALUE + " TEXT)");
}
/**
* called when the database is created for the first time. this will create our Ringer database
* (non-Javadoc)
* called when the database is created for the first time. this will
* create our Ringer database (non-Javadoc)
*
* @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
* @author ricky barrette
*/
@Override
public void onCreate(SQLiteDatabase db) {
public void onCreate(final SQLiteDatabase db) {
if (Debug.DROP_TABLE_EVERY_TIME)
db.execSQL("DROP TABLE IF EXISTS " + RINGER_TABLE);
createDatabase(db);
// insert the default ringer into this table
db.execSQL("insert into " + RINGER_TABLE + "(" + KEY_RINGER_NAME + ") values ('"+RingerDatabase.this.mContext.getString(R.string.default_ringer)+"')");
db.execSQL("insert into " + RINGER_INFO_TABLE + "(" + KEY_RINGER_NAME + ", " + KEY + ", " + KEY_VALUE +
") values ('"+RingerDatabase.this.mContext.getString(R.string.default_ringer)
+ "', '" + KEY_RINGER_DESCRIPTION
+ "', '" + RingerDatabase.this.mContext.getString(R.string.about_default_ringer)+"')");
db.execSQL("insert into " + RINGER_TABLE + "(" + KEY_RINGER_NAME + ") values ('" + mContext.getString(R.string.default_ringer) + "')");
db.execSQL("insert into " + RINGER_INFO_TABLE + "(" + KEY_RINGER_NAME + ", " + KEY + ", " + KEY_VALUE + ") values ('"
+ mContext.getString(R.string.default_ringer) + "', '" + KEY_RINGER_DESCRIPTION + "', '" + mContext.getString(R.string.about_default_ringer) + "')");
}
/**
* called when the database needs to be updated
* (non-Javadoc)
* @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
* called when the database needs to be updated (non-Javadoc)
*
* @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase,
* int, int)
* @author ricky barrette
*/
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, int newVersion) {
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
if (mListener != null)
mListener.onDatabaseUpgrade();
RingerDatabase.this.isUpgrading = true;
isUpgrading = true;
// upgrade thread
new Thread(new Runnable() {
@@ -258,93 +175,170 @@ public class RingerDatabase {
// remove old tables
db.execSQL("DROP TABLE IF EXISTS two");
case 3:
Cursor c = db.query(RINGER_TABLE, new String[] { "id", KEY_RINGER_NAME, KEY_LOCATION_LAT, KEY_LOCATION_LON, KEY_RADIUS }, null, null, null, null, null);;
final Cursor c = db.query(RINGER_TABLE, new String[] { "id", KEY_RINGER_NAME, KEY_LOCATION_LAT, KEY_LOCATION_LON, KEY_RADIUS }, null, null, null,
null, null);
;
c.moveToFirst();
if (c.moveToFirst()) {
if (c.moveToFirst())
do {
if (Debug.DEBUG)
Log.d(TAG, "Moving: " + c.getInt(0) + " " + c.getString(1) + " " + c.getInt(2) + ", " + c.getInt(3) + " @ " + c.getInt(4) + "m");
ContentValues ringer = new ContentValues();
ContentValues info = new ContentValues();
final ContentValues ringer = new ContentValues();
final ContentValues info = new ContentValues();
ringer.put(KEY_RINGER_NAME, c.getString(1));
info.put(KEY_LOCATION_LAT, c.getInt(2));
info.put(KEY_LOCATION_LON, c.getInt(3));
info.put(KEY_RADIUS, c.getInt(4));
updateRinger(c.getInt(0), ringer, info);
} while (c.moveToNext());
}
// drop old location trigger information
db.execSQL("CREATE TABLE ringers_new (" +
"id INTEGER PRIMARY KEY, " +
KEY_RINGER_NAME+" TEXT, " +
KEY_IS_ENABLED+" TEXT)");
db.execSQL("CREATE TABLE ringers_new (" + "id INTEGER PRIMARY KEY, " + KEY_RINGER_NAME + " TEXT, " + KEY_IS_ENABLED + " TEXT)");
db.execSQL("INSERT INTO ringers_new SELECT id, " + KEY_RINGER_NAME + ", " + KEY_IS_ENABLED + " FROM " + RINGER_TABLE);
db.execSQL("DROP TABLE " + RINGER_TABLE);
db.execSQL("ALTER TABLE ringers_new RENAME TO " + RINGER_TABLE);
}
mHandler.sendEmptyMessage(DATABASEUPGRADECOMPLETE);
RingerDatabase.this.isUpgrading = false;
isUpgrading = false;
}
}).start();
}
}
/**
* Creates a new RingerDatabase
* @param context
* @author ricky barrette
*/
public RingerDatabase(Context context){
this(context, null);
private static final String TAG = "RingerDatabase";
private final Context mContext;
private SQLiteDatabase mDb;
private static DatabaseListener mListener;
public boolean isUpgrading = false;
private final static Handler mHandler;
protected static final int DELETIONCOMPLETE = 0;
protected static final int DATABASEUPGRADECOMPLETE = 1;
static {
mHandler = new Handler() {
@Override
public void handleMessage(final Message msg) {
if (mListener != null)
switch (msg.what) {
case DELETIONCOMPLETE:
mListener.onRingerDeletionComplete();
break;
case DATABASEUPGRADECOMPLETE:
mListener.onDatabaseUpgradeComplete();
break;
}
}
};
}
/**
* Creates a new RingerDatabase
* @param context
* @param listener
* @author ricky barrette
/*
* database information values
*/
public RingerDatabase(Context context, DatabaseListener listener){
mListener = listener;
this.mContext = context;
this.mDb = new OpenHelper(this.mContext).getWritableDatabase();
}
private final int DATABASE_VERSION = 4;
/*
* the following is for the table that holds the other table names
*/
private final String DATABASE_NAME = "ringers.db";
private final String RINGER_TABLE = "ringers";
private static final String RINGER_INFO_TABLE = "ringer_info";
/*
* Database keys
*/
@Deprecated
public final static String KEY_LOCATION_LAT = "location_lat";
@Deprecated
public final static String KEY_LOCATION_LON = "location_lon";
@Deprecated
public final static String KEY_RINGTONE = "home_ringtone";
@Deprecated
public final static String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
@Deprecated
public final static String KEY_RINGTONE_IS_SILENT = "ringtone_is_silent";
@Deprecated
public final static String KEY_NOTIFICATION_IS_SILENT = "notification_is_silent";
public final static String KEY_IS_ENABLED = "is_enabled";
public final static String KEY_RADIUS = "radius";
public final static String KEY_RINGER_NAME = "ringer_name";
public final static String KEY_LOCATION = "location";
public final static String KEY_RINGTONE_URI = "ringtone_uri";
public final static String KEY_NOTIFICATION_RINGTONE_URI = "away_notification_uri";
public final static String KEY_RINGTONE_VOLUME = "ringtone_volume";
public final static String KEY_NOTIFICATION_RINGTONE_VOLUME = "notification_ringtone_volume";
public final static String KEY_WIFI = "wifi";
public final static String KEY_BT = "bt";
public final static String KEY_MUSIC_VOLUME = "music_volume";
public final static String KEY_ALARM_VOLUME = "alarm_volume";
public static final String KEY_VALUE = "value";
public static final String KEY = "key";
public static final String KEY_UPDATE_INTERVAL = "update_interval";
public static final String KEY_PLUS_BUTTON_HINT = "plus_button_hint";
public static final String KEY_DTMF_VOLUME = "dtmf_volume";
public static final String KEY_SYSTEM_VOLUME = "system_volume";
public static final String KEY_CALL_VOLUME = "call_volume";
public static final String KEY_RINGER_DESCRIPTION = "ringer_description";
/**
* Parses a string boolean from the database
*
* @param bool
* @return true or false
* @author ricky barrette
*/
public static boolean parseBoolean(String bool){
public static boolean parseBoolean(final String bool) {
try {
return bool == null ? false : Integer.parseInt(bool) == 1 ? true : false;
} catch (NumberFormatException e) {
} catch (final NumberFormatException e) {
return false;
}
}
/**
* Creates a new RingerDatabase
*
* @param context
* @author ricky barrette
*/
public RingerDatabase(final Context context) {
this(context, null);
}
/**
* Creates a new RingerDatabase
*
* @param context
* @param listener
* @author ricky barrette
*/
public RingerDatabase(final Context context, final DatabaseListener listener) {
mListener = listener;
mContext = context;
mDb = new OpenHelper(mContext).getWritableDatabase();
}
/**
* Backs up the database
*
* @return true if successful
* @author ricky barrette
*/
public boolean backup() {
final File dbFile = new File(Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/" + DATABASE_NAME);
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/"+this.mContext.getString(R.string.app_name));
if (!exportDir.exists()) {
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/" + mContext.getString(R.string.app_name));
if (!exportDir.exists())
exportDir.mkdirs();
}
final File file = new File(exportDir, dbFile.getName());
try {
file.createNewFile();
this.copyFile(dbFile, file);
copyFile(dbFile, file);
return true;
} catch (IOException e) {
} catch (final IOException e) {
e.printStackTrace();
return false;
}
@@ -352,34 +346,39 @@ public class RingerDatabase {
/**
* Checks to see if this ringer name is original, if not it renames it
*
* @param name
* @return
*/
private String checkRingerName(final String name) {
final List<String> names = this.getAllRingerTitles();
final List<String> names = getAllRingerTitles();
String ringerName = name;
int count = 1;
for(int index = 0; index < names.size(); index++ ){
for (int index = 0; index < names.size(); index++)
if (ringerName.equals(names.get(index))) {
ringerName = name + count++ + "";
index = 0;
}
}
return ringerName;
}
/**
* Copies a file
* @param src file
* @param dst file
*
* @param src
* file
* @param dst
* file
* @throws IOException
* @author ricky barrette
*/
private void copyFile(final File src, final File dst) throws IOException {
final FileChannel inChannel = new FileInputStream(src).getChannel();
final FileChannel outChannel = new FileOutputStream(dst).getChannel();
final FileInputStream in = new FileInputStream(src);
final FileOutputStream out = new FileOutputStream(dst);
final FileChannel inChannel = in.getChannel();
final FileChannel outChannel = out.getChannel();
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} finally {
@@ -387,11 +386,17 @@ public class RingerDatabase {
inChannel.close();
if (outChannel != null)
outChannel.close();
if (in != null)
in.close();
if (out != null)
out.close();
}
}
/**
* deletes a note by its row id
*
* @param id
* @author ricky barrette
*/
@@ -406,14 +411,15 @@ public class RingerDatabase {
Looper.prepare();
/*
* get the ringer name from the id, and then delete all its information from the ringer information table
* get the ringer name from the id, and then delete all its
* information from the ringer information table
*/
RingerDatabase.this.mDb.delete(RINGER_INFO_TABLE, KEY_RINGER_NAME +" = "+ DatabaseUtils.sqlEscapeString(RingerDatabase.this.getRingerName(id)), null);
mDb.delete(RINGER_INFO_TABLE, KEY_RINGER_NAME + " = " + DatabaseUtils.sqlEscapeString(RingerDatabase.this.getRingerName(id)), null);
/*
* finally delete the ringer from the ringer table
*/
RingerDatabase.this.mDb.delete(RINGER_TABLE, "id = "+ id, null);
mDb.delete(RINGER_TABLE, "id = " + id, null);
updateRowIds(id + 1);
mHandler.sendEmptyMessage(DELETIONCOMPLETE);
progress.dismiss();
@@ -422,98 +428,103 @@ public class RingerDatabase {
}
/**
* @return a cursor containing all ringers
* @author ricky barrette
*/
public Cursor getAllRingers(){
return this.mDb.query(RINGER_TABLE, new String[] { KEY_RINGER_NAME, KEY_IS_ENABLED }, null, null, null, null, null);
}
/**
* returns all ringer names in the database, where or not if they are enabled
* @return list of all strings in the database table
* @author ricky barrette
*/
public List<String> getAllRingerTitles() {
final List<String> list = new ArrayList<String>();
final Cursor cursor = this.mDb.query(RINGER_TABLE, new String[] { KEY_RINGER_NAME }, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
list.add(cursor.getString(0));
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
return list;
}
/**
* returns all ringer descriptions in the database, where or not if they are enabled
* returns all ringer descriptions in the database, where or not if they are
* enabled
*
* @return list of all strings in the database table
* @author ricky barrette
*/
public List<String> getAllRingerDescriptions() {
final List<String> list = new ArrayList<String>();
final List<String> ringers = getAllRingerTitles();
for(String ringer: ringers){
for (final String ringer : ringers)
list.add(getRingerInfo(ringer).getAsString(KEY_RINGER_DESCRIPTION));
return list;
}
/**
* @return a cursor containing all ringers
* @author ricky barrette
*/
public Cursor getAllRingers() {
return mDb.query(RINGER_TABLE, new String[] { KEY_RINGER_NAME, KEY_IS_ENABLED }, null, null, null, null, null);
}
/**
* returns all ringer names in the database, where or not if they are
* enabled
*
* @return list of all strings in the database table
* @author ricky barrette
*/
public List<String> getAllRingerTitles() {
final List<String> list = new ArrayList<String>();
final Cursor cursor = mDb.query(RINGER_TABLE, new String[] { KEY_RINGER_NAME }, null, null, null, null, null);
if (cursor.moveToFirst())
do
list.add(cursor.getString(0));
while (cursor.moveToNext());
if (cursor != null && !cursor.isClosed())
cursor.close();
return list;
}
/**
* gets a ringer from a row id;
*
* @param id
* @return cursor containing the note
* @author ricky barrette
*/
public Cursor getRingerFromId(long id) {
return this.mDb.query(RINGER_TABLE, new String[]{ KEY_RINGER_NAME, KEY_IS_ENABLED }, "id = "+id, null, null, null, null);
public Cursor getRingerFromId(final long id) {
return mDb.query(RINGER_TABLE, new String[] { KEY_RINGER_NAME, KEY_IS_ENABLED }, "id = " + id, null, null, null, null);
}
/**
* gets a ringer's info from the supplied ringer name
*
* @param ringerName
* @return
* @author ricky barrette
*/
public ContentValues getRingerInfo(final String ringerName) {
final ContentValues values = new ContentValues();
final Cursor info = this.mDb.query(RINGER_INFO_TABLE, new String[]{ KEY, KEY_VALUE }, KEY_RINGER_NAME +" = "+ DatabaseUtils.sqlEscapeString(ringerName), null, null, null, null);
if (info.moveToFirst()) {
do {
final Cursor info = mDb.query(RINGER_INFO_TABLE, new String[] { KEY, KEY_VALUE }, KEY_RINGER_NAME + " = " + DatabaseUtils.sqlEscapeString(ringerName), null,
null, null, null);
if (info.moveToFirst())
do
values.put(info.getString(0), info.getString(1));
} while (info.moveToNext());
}
if (info != null && !info.isClosed()) {
while (info.moveToNext());
if (info != null && !info.isClosed())
info.close();
}
return values;
}
/**
* Retrieves the ringer's name form the ringer table
*
* @param id
* @return ringer's name
* @author ricky barrette
*/
public String getRingerName(final long id) {
String name = null;
final Cursor cursor = this.mDb.query(RINGER_TABLE, new String[]{ KEY_RINGER_NAME }, "id = "+id, null, null, null, null);;
if (cursor.moveToFirst()) {
final Cursor cursor = mDb.query(RINGER_TABLE, new String[] { KEY_RINGER_NAME }, "id = " + id, null, null, null, null);
;
if (cursor.moveToFirst())
name = cursor.getString(0);
}
if (cursor != null && !cursor.isClosed()) {
if (cursor != null && !cursor.isClosed())
cursor.close();
}
return name;
}
/**
* Inserts a new ringer into the database
* @param ringer values
* @param ringerInfo values
*
* @param ringer
* values
* @param ringerInfo
* values
* @author ricky barrette
*/
public void insertRinger(final ContentValues ringer, final ContentValues ringerInfo) {
@@ -527,20 +538,17 @@ public class RingerDatabase {
values.put(KEY_RINGER_NAME, ringerName);
values.put(KEY, item.getKey());
/*
* Try get the value.
* If there is a class cast exception, try casting to the next object type.
* Try get the value. If there is a class cast exception, try
* casting to the next object type.
*
* The following types are tried:
* String
* Integer
* Boolean
* The following types are tried: String Integer Boolean
*/
try {
values.put(KEY_VALUE, (String) item.getValue());
} catch (ClassCastException e) {
} catch (final ClassCastException e) {
try {
values.put(KEY_VALUE, (Boolean) item.getValue() ? 1 : 0);
} catch (ClassCastException e1) {
} catch (final ClassCastException e1) {
values.put(KEY_VALUE, (Integer) item.getValue());
}
}
@@ -550,12 +558,14 @@ public class RingerDatabase {
/**
* Checks to see if a ringer is enabled
* @param row id
*
* @param row
* id
* @return true if the ringer is enabled
* @author ricky barrette
*/
public boolean isRingerEnabled(final long id) {
final Cursor cursor = this.mDb.query(RINGER_TABLE, new String[] { KEY_IS_ENABLED }, "id = "+id, null, null, null, null);
final Cursor cursor = mDb.query(RINGER_TABLE, new String[] { KEY_IS_ENABLED }, "id = " + id, null, null, null, null);
if (cursor.moveToFirst()) {
if (Debug.DEBUG)
Log.d(TAG, "isRingerEnabled(" + id + ") = " + cursor.getString(0));
@@ -566,31 +576,31 @@ public class RingerDatabase {
/**
* Restores the database from the sdcard
*
* @return true if successful
* @author ricky barrette
*/
public void restore() {
final File dbFile = new File(Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/" + DATABASE_NAME);
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/"+this.mContext.getString(R.string.app_name));
if (!exportDir.exists()) {
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/" + mContext.getString(R.string.app_name));
if (!exportDir.exists())
exportDir.mkdirs();
}
final File file = new File(exportDir, dbFile.getName());
try {
file.createNewFile();
this.copyFile(file, dbFile);
} catch (IOException e) {
copyFile(file, dbFile);
} catch (final IOException e) {
e.printStackTrace();
}
/*
* close and reopen the database to upgrade it.
*/
this.mDb.close();
this.mDb = new OpenHelper(this.mContext).getWritableDatabase();
if(this.mDb.isOpen() && ! this.isUpgrading)
mDb.close();
mDb = new OpenHelper(mContext).getWritableDatabase();
if (mDb.isOpen() && !isUpgrading)
if (mListener != null)
mListener.onRestoreComplete();
}
@@ -605,9 +615,12 @@ public class RingerDatabase {
/**
* updates a ringer by it's id
*
* @param id
* @param ringer values
* @param info values
* @param ringer
* values
* @param info
* values
* @author ricky barrette
*/
public void updateRinger(final long id, final ContentValues ringer, final ContentValues info) throws NullPointerException {
@@ -618,18 +631,17 @@ public class RingerDatabase {
final String ringer_name = getRingerName(id);
/*
* here we retrive the old values.
* we will compare the old value against the new values.
* we will delete all values that are NOT included in the new values.
* here we retrive the old values. we will compare the old value against
* the new values. we will delete all values that are NOT included in
* the new values.
*/
final ContentValues old = getRingerInfo(ringer_name);
for(final Entry<String, Object> item : info.valueSet()){
for (final Entry<String, Object> item : info.valueSet())
if (old.containsKey(item.getKey()))
old.remove(item.getKey());
}
for(final Entry<String, Object> item : old.valueSet()){
RingerDatabase.this.mDb.delete(RINGER_INFO_TABLE, KEY +" = "+ DatabaseUtils.sqlEscapeString(item.getKey()) +" and "+ KEY_RINGER_NAME +" = "+DatabaseUtils.sqlEscapeString(ringer_name), null);
}
for (final Entry<String, Object> item : old.valueSet())
RingerDatabase.this.mDb.delete(RINGER_INFO_TABLE, KEY + " = " + DatabaseUtils.sqlEscapeString(item.getKey()) + " and " + KEY_RINGER_NAME + " = "
+ DatabaseUtils.sqlEscapeString(ringer_name), null);
/*
* here we want to update the ringer name if needed
@@ -646,19 +658,20 @@ public class RingerDatabase {
values.put(KEY, item.getKey());
try {
values.put(KEY_VALUE, (String) item.getValue());
} catch (ClassCastException e) {
} catch (final ClassCastException e) {
try {
values.put(KEY_VALUE, (Boolean) item.getValue() ? 1 : 0);
} catch (ClassCastException e1) {
} catch (final ClassCastException e1) {
values.put(KEY_VALUE, (Integer) item.getValue());
}
}
/*
* here we are going to try to update a row,
* if that fails we will insert a row insead
* here we are going to try to update a row, if that fails we will
* insert a row insead
*/
if(!(mDb.update(RINGER_INFO_TABLE, values, KEY_RINGER_NAME + "="+ DatabaseUtils.sqlEscapeString(ringer_name) +" AND " + KEY +"='"+ item.getKey()+"'", null) > 0))
if (!(mDb.update(RINGER_INFO_TABLE, values, KEY_RINGER_NAME + "=" + DatabaseUtils.sqlEscapeString(ringer_name) + " AND " + KEY + "='" + item.getKey() + "'",
null) > 0))
mDb.insert(RINGER_INFO_TABLE, null, values);
}
@@ -668,14 +681,16 @@ public class RingerDatabase {
/**
* Updates the row ids after a row is deleted
* @param id of the row to start with
*
* @param id
* of the row to start with
* @author ricky barrette
*/
private void updateRowIds(long id) {
long currentRow;
final ContentValues values = new ContentValues();
final Cursor cursor = this.mDb.query(RINGER_TABLE, new String[] { "id" },null, null, null, null, null);
if (cursor.moveToFirst()) {
final Cursor cursor = mDb.query(RINGER_TABLE, new String[] { "id" }, null, null, null, null, null);
if (cursor.moveToFirst())
do {
currentRow = cursor.getLong(0);
if (currentRow == id) {
@@ -685,9 +700,7 @@ public class RingerDatabase {
mDb.update(RINGER_TABLE, values, "id" + "= " + currentRow, null);
}
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
if (cursor != null && !cursor.isClosed())
cursor.close();
}
}
}

View File

@@ -11,7 +11,9 @@ import android.content.Context;
/**
* A convince class containing debugging variables
* @author ricky barrette */
*
* @author ricky barrette
*/
public class Debug {
public static final boolean SUPPORTS_FROYO;
@@ -22,14 +24,14 @@ public class Debug {
public static final int SHARED_PREFS_MODE;
/**
* Sets the logging output of this application
*/
public static final boolean DEBUG = true;
/**
* The amount of intersecting that is needed between a users accuracy radius and a ringers location radius
* The amount of intersecting that is needed between a users accuracy radius
* and a ringers location radius
*/
public static final float FUDGE_FACTOR = .002f;
@@ -54,7 +56,8 @@ public class Debug {
public static final int ACCURACY = 100;
/**
* all lolcations with an accuracy greater then this will be ignored. in meters
* all lolcations with an accuracy greater then this will be ignored. in
* meters
*/
public static final int IGNORE = 500;

View File

@@ -21,7 +21,9 @@ import com.TwentyCodes.android.LocationRinger.services.LocationService;
import com.TwentyCodes.android.LocationRinger.ui.SettingsActivity;
/**
* This widget will be used to force a Location update from the users home screen
* This widget will be used to force a Location update from the users home
* screen
*
* @author ricky barrette
*/
public class GetLocationWidget extends AppWidgetProvider {
@@ -31,85 +33,99 @@ public class GetLocationWidget extends AppWidgetProvider {
public static final String ACTION_UPDATE = "action_update";
/**
* Called in response to the ACTION_APPWIDGET_UPDATE broadcast when this AppWidget provider is being asked to provide RemoteViews for a set of AppWidgets.
* Override this method to implement your own AppWidget functionality.
* @see android.appwidget.AppWidgetProvider#onUpdate(android.content.Context, android.appwidget.AppWidgetManager, int[])
* Called in response to the ACTION_APPWIDGET_DELETED broadcast when one or
* more AppWidget instances have been deleted. Override this method to
* implement your own AppWidget functionality. (non-Javadoc)
*
* @see android.appwidget.AppWidgetProvider#onDeleted(android.content.Context,
* int[])
* @param context
* @param appWidgetManager
* @param appWidgetIds
* @author ricky barrette
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
public void onDeleted(final Context context, final int[] appWidgetIds) {
if (Debug.DEBUG)
Log.v(TAG, "onUpdate()");
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = LocationService.getSingleShotServiceIntent(context);
//create a pending intent to start the post activity
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.get_location_widget);
views.setOnClickPendingIntent(R.id.widget_get_location_button, pendingIntent);
views.setTextViewText(R.id.widget_label, context.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE).getString(SettingsActivity.CURRENT, context.getString(R.string.default_ringer)));
// Tell the AppWidgetManager to perform an update on the current App Widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
Log.v(TAG, "onDelete()");
super.onDeleted(context, appWidgetIds);
}
/**
* Implements onReceive(Context, Intent) to dispatch calls to the various other methods on AppWidgetProvider.
* (non-Javadoc)
* @see android.appwidget.AppWidgetProvider#onReceive(android.content.Context, android.content.Intent)
* Implements onReceive(Context, Intent) to dispatch calls to the various
* other methods on AppWidgetProvider. (non-Javadoc)
*
* @see android.appwidget.AppWidgetProvider#onReceive(android.content.Context,
* android.content.Intent)
* @param context
* @param intent received
* @param intent
* received
* @author ricky barrette
*/
@Override
public void onReceive(Context context, Intent intent) {
public void onReceive(final Context context, final Intent intent) {
if (Debug.DEBUG)
Log.v(TAG, "onReceive");
// v1.5 fix that doesn't call onDelete Action
final String action = intent.getAction();
if (action.equals(ACTION_UPDATE)) {
AppWidgetManager mgr=AppWidgetManager.getInstance(context);
final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
onUpdate(context, mgr, mgr.getAppWidgetIds(new ComponentName(context, GetLocationWidget.class)));
}
if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
this.onDeleted(context, new int[] { appWidgetId });
}
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID)
onDeleted(context, new int[] { appWidgetId });
}
super.onReceive(context, intent);
}
/**
* Called in response to the ACTION_APPWIDGET_DELETED broadcast when one or more AppWidget instances have been deleted.
* Override this method to implement your own AppWidget functionality.
* (non-Javadoc)
* @see android.appwidget.AppWidgetProvider#onDeleted(android.content.Context, int[])
* Called in response to the ACTION_APPWIDGET_UPDATE broadcast when this
* AppWidget provider is being asked to provide RemoteViews for a set of
* AppWidgets. Override this method to implement your own AppWidget
* functionality.
*
* @see android.appwidget.AppWidgetProvider#onUpdate(android.content.Context,
* android.appwidget.AppWidgetManager, int[])
* @param context
* @param appWidgetManager
* @param appWidgetIds
* @author ricky barrette
*/
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
if (Debug.DEBUG)
Log.v(TAG, "onDelete()");
super.onDeleted(context, appWidgetIds);
Log.v(TAG, "onUpdate()");
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this
// provider
for (int i = 0; i < N; i++) {
final int appWidgetId = appWidgetIds[i];
final Intent intent = LocationService.getSingleShotServiceIntent(context);
// create a pending intent to start the post activity
final PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.get_location_widget);
views.setOnClickPendingIntent(R.id.widget_get_location_button, pendingIntent);
views.setTextViewText(
R.id.widget_label,
context.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE).getString(SettingsActivity.CURRENT,
context.getString(R.string.default_ringer)));
// Tell the AppWidgetManager to perform an update on the current App
// Widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
}

View File

@@ -16,7 +16,9 @@ import com.TwentyCodes.android.debug.LocationLibraryConstants;
import com.TwentyCodes.android.location.BaseLocationReceiver;
/**
* This class will receive broadcast from the location service. it will wake the ringer processing service.
* This class will receive broadcast from the location service. it will wake the
* ringer processing service.
*
* @author ricky barrette
*/
public class LocationChangedReceiver extends BaseLocationReceiver {
@@ -24,15 +26,13 @@ public class LocationChangedReceiver extends BaseLocationReceiver {
protected static String TAG = "LocationReceiver";
@Override
public void onLocationUpdate(Location location) {
public void onLocationUpdate(final Location location) {
if (location != null)
if (location.getAccuracy() <= Debug.IGNORE)
mContext.startService(new Intent(mContext, RingerProcessingService.class).putExtra(LocationLibraryConstants.INTENT_EXTRA_LOCATION_CHANGED, location));
else
if(Debug.DEBUG)
else if (Debug.DEBUG)
Log.d(TAG, "location accuracy = " + location.getAccuracy() + " ignoring");
else
if(Debug.DEBUG)
else if (Debug.DEBUG)
Log.d(TAG, "location was null");
}
}

View File

@@ -8,6 +8,7 @@ package com.TwentyCodes.android.LocationRinger.receivers;
/**
* This class will be used to listen for location updates passively.
*
* @author ricky barrette
*/
public class PassiveLocationChangedReceiver extends LocationChangedReceiver {

View File

@@ -20,6 +20,7 @@ import com.TwentyCodes.android.location.PassiveLocationListener;
/**
* This receiver will system events
*
* @author ricky barrette
*/
public class SystemReceiver extends BroadcastReceiver {
@@ -32,7 +33,9 @@ public class SystemReceiver extends BroadcastReceiver {
/**
* (non-Javadoc)
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
*
* @see android.content.BroadcastReceiver#onReceive(android.content.Context,
* android.content.Intent)
* @param context
* @param intent
* @author ricky barrette
@@ -43,39 +46,37 @@ public class SystemReceiver extends BroadcastReceiver {
Log.d(TAG, "onReceive() ~" + intent.getAction());
final SharedPreferences systemEventHistory = context.getSharedPreferences(TAG, Debug.SHARED_PREFS_MODE);
/*
* if the phone finishes booting, then start the service if the user enabled it
* if the phone finishes booting, then start the service if the user
* enabled it
*/
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
if (context.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE).getBoolean(SettingsActivity.START_ON_BOOT, false)) {
LocationService.startMultiShotService(context);
PassiveLocationListener.requestPassiveLocationUpdates(context, new Intent(context, PassiveLocationChangedReceiver.class));
}
}
/*
* if the battery is reported to be low then
* stop the service, and remove the pending alarm
* and finally record that the phone's battery was low in the shared_prefs
* if the battery is reported to be low then stop the service, and
* remove the pending alarm and finally record that the phone's battery
* was low in the shared_prefs
*/
if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW)) {
LocationService.stopService(context).run();
new Handler().postDelayed(LocationService.stopService(context), 30000L);
com.TwentyCodes.android.location.LocationService.stopService(context).run();
new Handler().postDelayed(com.TwentyCodes.android.location.LocationService.stopService(context), 30000L);
systemEventHistory.edit().putBoolean(BATTERY_LOW, true).commit();
}
/*
* if the phone is plugged in then
* check to see if the battery was reported low, if it was then
* restart the service, and remove shared_prefs entry
* if the phone is plugged in then check to see if the battery was
* reported low, if it was then restart the service, and remove
* shared_prefs entry
*/
if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)){
if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED))
if (systemEventHistory.getBoolean(BATTERY_LOW, false)) {
systemEventHistory.edit().remove(BATTERY_LOW).commit();
LocationService.startMultiShotService(context);
}
}
}
}

View File

@@ -23,92 +23,38 @@ import com.TwentyCodes.android.exception.ExceptionHandler;
/**
* We override the location service so we can attach the exception handler
*
* @author ricky barrette
*/
public class LocationService extends com.TwentyCodes.android.location.LocationService {
private final int GATHERING_LOCATION_ONGING_NOTIFICATION_ID = 232903877;
private SharedPreferences mSettings;
private NotificationManager mNotificationManager;
/**
* convince method for getting the single shot service intent
*
* @param context
* @return service intent
* @author ricky barrette
*/
public static Intent getSingleShotServiceIntent(Context context) {
return new Intent(context, LocationService.class)
.putExtra(LocationLibraryConstants.INTENT_EXTRA_REQUIRED_ACCURACY, Debug.ACCURACY)
.setAction(LocationLibraryConstants.INTENT_ACTION_UPDATE);
}
/* (non-Javadoc)
* @see com.TwentyCodes.android.SkyHook.SkyHookService#onCreate()
* @author ricky barrette
*/
@Override
public void onCreate() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
this.mSettings = this.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
this.mSettings.edit().putBoolean(SettingsActivity.IS_SERVICE_STARTED, true).commit();
startOnGoingNotification();
super.onCreate();
}
/* (non-Javadoc)
* @see com.TwentyCodes.android.SkyHook.SkyHookService#onDestroy()
* @author ricky barrette
*/
@Override
public void onDestroy() {
this.mSettings.edit().remove(SettingsActivity.IS_SERVICE_STARTED).commit();
this.mNotificationManager.cancel(this.GATHERING_LOCATION_ONGING_NOTIFICATION_ID);
super.onDestroy();
}
/* (non-Javadoc)
* @see com.TwentyCodes.android.SkyHook.SkyHookService#onStartCommand(android.content.Intent, int, int)
* @author ricky barrette
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.mPeriod = Debug.UPDATE_INTERVAL;
return super.onStartCommand(intent, flags, startId);
public static Intent getSingleShotServiceIntent(final Context context) {
return new Intent(context, LocationService.class).putExtra(LocationLibraryConstants.INTENT_EXTRA_REQUIRED_ACCURACY, Debug.ACCURACY).setAction(
LocationLibraryConstants.INTENT_ACTION_UPDATE);
}
/**
* Starts the location service in multi shot mode
*
* @param context
* @return
* @author ricky barrette
*/
public static ComponentName startMultiShotService(final Context context) {
Intent i = getSingleShotServiceIntent(context).putExtra(LocationLibraryConstants.INTENT_EXTRA_PERIOD_BETWEEN_UPDATES, Debug.UPDATE_INTERVAL);
final Intent i = getSingleShotServiceIntent(context).putExtra(LocationLibraryConstants.INTENT_EXTRA_PERIOD_BETWEEN_UPDATES, Debug.UPDATE_INTERVAL);
return context.startService(i);
}
/**
* starts a simple ongoing notification to inform the user that we are gathering location
* @author ricky barrette
*/
private void startOnGoingNotification() {
this.mNotificationManager = (NotificationManager) this.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle(getString(R.string.app_name))
.setContentText(this.getString(R.string.gathering))
.setTicker(this.getString(R.string.gathering))
.setSmallIcon(R.drawable.icon)
.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, ListActivity.class), android.content.Intent.FLAG_ACTIVITY_NEW_TASK))
.setWhen(System.currentTimeMillis())
.setOngoing(true);
this.mNotificationManager.notify(this.GATHERING_LOCATION_ONGING_NOTIFICATION_ID, builder.getNotification());
}
/**
* starts the service in single shot mode
*
* @param context
* @return
* @author ricky barrette
@@ -116,4 +62,72 @@ public class LocationService extends com.TwentyCodes.android.location.LocationSe
public static ComponentName startSingleShotService(final Context context) {
return context.startService(getSingleShotServiceIntent(context));
}
private final int GATHERING_LOCATION_ONGING_NOTIFICATION_ID = 232903877;
private SharedPreferences mSettings;
private NotificationManager mNotificationManager;
/*
* (non-Javadoc)
*
* @see com.TwentyCodes.android.SkyHook.SkyHookService#onCreate()
*
* @author ricky barrette
*/
@Override
public void onCreate() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
mSettings = getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
mSettings.edit().putBoolean(SettingsActivity.IS_SERVICE_STARTED, true).commit();
startOnGoingNotification();
super.onCreate();
}
/*
* (non-Javadoc)
*
* @see com.TwentyCodes.android.SkyHook.SkyHookService#onDestroy()
*
* @author ricky barrette
*/
@Override
public void onDestroy() {
mSettings.edit().remove(SettingsActivity.IS_SERVICE_STARTED).commit();
mNotificationManager.cancel(GATHERING_LOCATION_ONGING_NOTIFICATION_ID);
super.onDestroy();
}
/*
* (non-Javadoc)
*
* @see
* com.TwentyCodes.android.SkyHook.SkyHookService#onStartCommand(android
* .content.Intent, int, int)
*
* @author ricky barrette
*/
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
mPeriod = Debug.UPDATE_INTERVAL;
return super.onStartCommand(intent, flags, startId);
}
/**
* starts a simple ongoing notification to inform the user that we are
* gathering location
*
* @author ricky barrette
*/
private void startOnGoingNotification() {
mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext()).setContentTitle(getString(R.string.app_name))
.setContentText(this.getString(R.string.gathering)).setTicker(this.getString(R.string.gathering)).setSmallIcon(R.drawable.icon)
.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, ListActivity.class), android.content.Intent.FLAG_ACTIVITY_NEW_TASK))
.setWhen(System.currentTimeMillis()).setOngoing(true);
mNotificationManager.notify(GATHERING_LOCATION_ONGING_NOTIFICATION_ID, builder.getNotification());
}
}

View File

@@ -36,6 +36,7 @@ import com.google.android.maps.GeoPoint;
/**
* This service will handle processing the users location and the ringers
*
* @author ricky barrette
*/
public class RingerProcessingService extends Service {
@@ -52,6 +53,7 @@ public class RingerProcessingService extends Service {
/**
* Applies a ringers options to the current system settings
*
* @param id
* @author ricky barrette
*/
@@ -61,7 +63,7 @@ public class RingerProcessingService extends Service {
final String name = values.getAsString(RingerDatabase.KEY_RINGER_NAME);
this.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE).edit().putString(SettingsActivity.CURRENT, name).commit();
getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE).edit().putString(SettingsActivity.CURRENT, name).commit();
this.sendBroadcast(new Intent(this, GetLocationWidget.class).setAction(GetLocationWidget.ACTION_UPDATE));
@@ -87,8 +89,8 @@ public class RingerProcessingService extends Service {
}
/*
* music volume
* we will set the music volume only if music is not playing, and there is no wired head set
* music volume we will set the music volume only if music is not
* playing, and there is no wired head set
*/
if (values.containsKey(RingerDatabase.KEY_MUSIC_VOLUME))
if (values.get(RingerDatabase.KEY_MUSIC_VOLUME) != null)
@@ -120,54 +122,64 @@ public class RingerProcessingService extends Service {
/**
* Apply the ring tone
* @param stream audio stream to apply to
* @param isSilent true if silent
* @param uri of ringtone, if null silent will be applied
*
* @param stream
* audio stream to apply to
* @param isSilent
* true if silent
* @param uri
* of ringtone, if null silent will be applied
* @return string uri of applied ringtone, null if silent was applied
* @author ricky barrette
*/
private String applyRingtone(int type, String uri) {
private String applyRingtone(final int type, final String uri) {
RingtoneManager.setActualDefaultRingtoneUri(this, type, uri == null ? null : Uri.parse(uri));
return uri;
}
/**
* appends the new ringer's information in content values
*
* @param id
* @return
*/
private ContentValues getRinger(ContentValues values, long id) {
String name = this.mDb.getRingerName(id);
private ContentValues getRinger(final ContentValues values, final long id) {
final String name = mDb.getRingerName(id);
values.put(RingerDatabase.KEY_RINGER_NAME, name);
/*
* get the ringer's info, and parse it into content values
*/
values.putAll(this.mDb.getRingerInfo(name));
values.putAll(mDb.getRingerInfo(name));
return values;
}
/**
* returns all the ringers information as content values
*
* @param id
* @return
*/
private ContentValues getRinger(long id) {
private ContentValues getRinger(final long id) {
return getRinger(new ContentValues(), id);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see android.app.Service#onBind(android.content.Intent)
*
* @author ricky barrette
*/
@Override
public IBinder onBind(Intent intent) {
public IBinder onBind(final Intent intent) {
// TODO Auto-generated method stub
return null;
}
/**
* Called when the service is first created
*
* @author ricky barrette
*/
@Override
@@ -176,15 +188,15 @@ public class RingerProcessingService extends Service {
if (Debug.DEBUG)
Log.d(TAG, "onCreate()");
super.onCreate();
this.mDb = new RingerDatabase(this);
this.mSettings = this.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
mDb = new RingerDatabase(this);
mSettings = getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
this.mWakeLock = (WakeLock) pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
this.mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
this.mWifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE);
this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mWifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.mWakeLock.acquire();
mWakeLock.acquire();
}
@Override
@@ -197,28 +209,29 @@ public class RingerProcessingService extends Service {
/**
* Called when the service is first started
*
* @param intent
* @param flags
* @param startId
* @author ricky barrette
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
public int onStartCommand(final Intent intent, final int flags, final int startId) {
if (Debug.DEBUG)
Log.d(TAG, "onStartCommand: " + startId);
this.mStartId = startId;
mStartId = startId;
/*
* try to sleep so skyhook doesn't cock block us
*/
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
} catch (final InterruptedException e) {
e.printStackTrace();
}
if (intent.getParcelableExtra(LocationLibraryConstants.INTENT_EXTRA_LOCATION_CHANGED) != null) {
this.mLocation = intent.getParcelableExtra(LocationLibraryConstants.INTENT_EXTRA_LOCATION_CHANGED);
mLocation = intent.getParcelableExtra(LocationLibraryConstants.INTENT_EXTRA_LOCATION_CHANGED);
processRingers();
} else if (Debug.DEBUG)
Log.d(TAG, "Location was null");
@@ -227,6 +240,7 @@ public class RingerProcessingService extends Service {
/**
* Processes the ringer database for applicable ringers
*
* @author ricky barrette
*/
private void processRingers() {
@@ -241,37 +255,41 @@ public class RingerProcessingService extends Service {
final GeoPoint point = new GeoPoint((int) (mLocation.getLatitude() * 1E6), (int) (mLocation.getLongitude() * 1E6));
if (Debug.DEBUG) {
Log.d(TAG, "Processing ringers");
Log.d(TAG, "Current location "+(int) (mLocation.getLatitude() * 1E6)+", "+(int) (mLocation.getLongitude() * 1E6)+" @ "+ Float.valueOf(mLocation.getAccuracy()) / 1000+"km");
Log.d(TAG,
"Current location " + (int) (mLocation.getLatitude() * 1E6) + ", " + (int) (mLocation.getLongitude() * 1E6) + " @ "
+ Float.valueOf(mLocation.getAccuracy()) / 1000 + "km");
}
final Cursor c = mDb.getAllRingers();
c.moveToFirst();
if (c.moveToFirst()) {
if (c.moveToFirst())
do {
if (Debug.DEBUG)
Log.d(TAG, "Checking ringer " + c.getString(0));
if (RingerDatabase.parseBoolean(c.getString(1))) {
final ContentValues info = this.mDb.getRingerInfo(c.getString(0));
final ContentValues info = mDb.getRingerInfo(c.getString(0));
if (info.containsKey(RingerDatabase.KEY_LOCATION) && info.containsKey(RingerDatabase.KEY_RADIUS)) {
final String[] pointInfo = info.getAsString(RingerDatabase.KEY_LOCATION).split(",");
if(GeoUtils.isIntersecting(point, Float.valueOf(mLocation.getAccuracy()) / 1000, new GeoPoint(Integer.parseInt(pointInfo[0]), Integer.parseInt(pointInfo[1])), Float.valueOf(info.getAsInteger(RingerDatabase.KEY_RADIUS)) / 1000, Debug.FUDGE_FACTOR)){
if (GeoUtils.isIntersecting(point, Float.valueOf(mLocation.getAccuracy()) / 1000,
new GeoPoint(Integer.parseInt(pointInfo[0]), Integer.parseInt(pointInfo[1])),
Float.valueOf(info.getAsInteger(RingerDatabase.KEY_RADIUS)) / 1000, Debug.FUDGE_FACTOR)) {
c.close();
getRinger(ringer, index);
isDeafult = false;
//break loop, we will only apply the first applicable ringer
// break loop, we will only apply the first
// applicable ringer
break;
}
}
}
index++;
} while (c.moveToNext());
}
c.close();
if (Debug.DEBUG)
for(Entry<String,Object> item : ringer.valueSet())
for (final Entry<String, Object> item : ringer.valueSet())
Log.d(TAG, item.getKey());
applyRinger(ringer);
@@ -280,40 +298,41 @@ public class RingerProcessingService extends Service {
Log.d(TAG, "Finished processing ringers");
// store is default
this.mSettings.edit().putBoolean(SettingsActivity.IS_DEFAULT, isDeafult).commit();
mSettings.edit().putBoolean(SettingsActivity.IS_DEFAULT, isDeafult).commit();
this.stopSelf(mStartId);
}
/**
* set the volume of a particular stream
*
* @param volume
* @param stream
* @author ricky barrette
*/
private void setStreamVolume(int volume, int stream) {
private void setStreamVolume(final int volume, final int stream) {
/*
* if the seek bar is set to a value that is higher than what the the stream value is set for
* then subtract the seek bar's value from the current volume of the stream, and then
* raise the stream by that many times
* if the seek bar is set to a value that is higher than what the the
* stream value is set for then subtract the seek bar's value from the
* current volume of the stream, and then raise the stream by that many
* times
*/
if (volume > mAudioManager.getStreamVolume(stream)) {
int adjust = volume - mAudioManager.getStreamVolume(stream);
for (int i = 0; i < adjust; i++) {
final int adjust = volume - mAudioManager.getStreamVolume(stream);
for (int i = 0; i < adjust; i++)
mAudioManager.adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, stream, 0);
}
}
/*
* if the seek bar is set to a value that is lower than what the the stream value is set for
* then subtract the current volume of the stream from the seek bar's value, and then
* lower the stream by that many times
* if the seek bar is set to a value that is lower than what the the
* stream value is set for then subtract the current volume of the
* stream from the seek bar's value, and then lower the stream by that
* many times
*/
if (volume < mAudioManager.getStreamVolume(stream)) {
int adjust = mAudioManager.getStreamVolume(stream) - volume;
for (int i = 0; i < adjust; i++) {
final int adjust = mAudioManager.getStreamVolume(stream) - volume;
for (int i = 0; i < adjust; i++)
mAudioManager.adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, stream, 0);
}
}
}
}

View File

@@ -29,34 +29,36 @@ import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.services.LocationService;
/**
* This Activity actually handles two stages of a launcher shortcut's life cycle.
* This Activity actually handles two stages of a launcher shortcut's life
* cycle.
*
* 1. Your application offers to provide shortcuts to the launcher. When
* the user installs a shortcut, an activity within your application
* generates the actual shortcut and returns it to the launcher, where it
* is shown to the user as an icon.
* 1. Your application offers to provide shortcuts to the launcher. When the
* user installs a shortcut, an activity within your application generates the
* actual shortcut and returns it to the launcher, where it is shown to the user
* as an icon.
*
* 2. Any time the user clicks on an installed shortcut, an intent is sent.
* Typically this would then be handled as necessary by an activity within
* your application.
* Typically this would then be handled as necessary by an activity within your
* application.
*
* We handle stage 1 (creating a shortcut) by simply sending back the information (in the form
* of an {@link android.content.Intent} that the launcher will use to create the shortcut.
* We handle stage 1 (creating a shortcut) by simply sending back the
* information (in the form of an {@link android.content.Intent} that the
* launcher will use to create the shortcut.
*
* You can also implement this in an interactive way, by having your activity actually present
* UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL,
* media item, or action.
* You can also implement this in an interactive way, by having your activity
* actually present UI for the user to select the specific nature of the
* shortcut, such as a contact, picture, URL, media item, or action.
*
* We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents
* of the incoming {@link android.content.Intent}.
* We handle stage 2 (responding to a shortcut) in this sample by simply
* displaying the contents of the incoming {@link android.content.Intent}.
*
* In a real application, you would probably use the shortcut intent to display specific content
* or start a particular operation.
* In a real application, you would probably use the shortcut intent to display
* specific content or start a particular operation.
*/
public class CheckLocationShortcut extends Activity {
@Override
public void onCreate(Bundle icicle) {
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
// Resolve the intent
@@ -64,7 +66,8 @@ public class CheckLocationShortcut extends Activity {
final Intent intent = getIntent();
final String action = intent.getAction();
// If the intent is a request to create a shortcut, we'll do that and exit
// If the intent is a request to create a shortcut, we'll do that and
// exit
if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
setupShortcut();
@@ -77,51 +80,58 @@ public class CheckLocationShortcut extends Activity {
*/
LocationService.startSingleShotService(this);
this.finish();
finish();
}
/**
* This function creates a shortcut and returns it to the caller. There are actually two
* intents that you will send back.
* This function creates a shortcut and returns it to the caller. There are
* actually two intents that you will send back.
*
* The first intent serves as a container for the shortcut and is returned to the launcher by
* setResult(). This intent must contain three fields:
* The first intent serves as a container for the shortcut and is returned
* to the launcher by setResult(). This intent must contain three fields:
*
* <ul>
* <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li>
* <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with
* the shortcut.</li>
* <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a
* bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as
* a drawable resource.</li>
* <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut
* intent.</li>
* <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will
* be displayed with the shortcut.</li>
* <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's
* icon, if provided as a bitmap, <i>or</i>
* {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided
* as a drawable resource.</li>
* </ul>
*
* If you use a simple drawable resource, note that you must wrapper it using
* {@link android.content.Intent.ShortcutIconResource}, as shown below. This is required so
* that the launcher can access resources that are stored in your application's .apk file. If
* you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras
* bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}.
* If you use a simple drawable resource, note that you must wrapper it
* using {@link android.content.Intent.ShortcutIconResource}, as shown
* below. This is required so that the launcher can access resources that
* are stored in your application's .apk file. If you return a bitmap, such
* as a thumbnail, you can simply put the bitmap into the extras bundle
* using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}.
*
* The shortcut intent can be any intent that you wish the launcher to send, when the user
* clicks on the shortcut. Typically this will be {@link android.content.Intent#ACTION_VIEW}
* with an appropriate Uri for your content, but any Intent will work here as long as it
* triggers the desired action within your Activity.
* The shortcut intent can be any intent that you wish the launcher to send,
* when the user clicks on the shortcut. Typically this will be
* {@link android.content.Intent#ACTION_VIEW} with an appropriate Uri for
* your content, but any Intent will work here as long as it triggers the
* desired action within your Activity.
*/
private void setupShortcut() {
// First, set up the shortcut intent. For this example, we simply create an intent that
// will bring us directly back to this activity. A more typical implementation would use a
// data Uri in order to display a more specific result, or a custom action in order to
// First, set up the shortcut intent. For this example, we simply create
// an intent that
// will bring us directly back to this activity. A more typical
// implementation would use a
// data Uri in order to display a more specific result, or a custom
// action in order to
// launch a specific operation.
Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);
final Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);
shortcutIntent.setClassName(this, this.getClass().getName());
// Then, set up the container intent (the response to the caller)
Intent intent = new Intent();
final Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.start_location_service));
Parcelable iconResource = Intent.ShortcutIconResource.fromContext(this, R.drawable.icon);
final Parcelable iconResource = Intent.ShortcutIconResource.fromContext(this, R.drawable.icon);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
// Now, return the result to the launcher

View File

@@ -6,74 +6,78 @@
*/
package com.TwentyCodes.android.LocationRinger.ui;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
import android.app.Dialog;
import android.content.Context;
import android.view.View;
import android.view.Window;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This class will be used to display the first boot dialog
*
* @author ricky barrette
*/
public class FirstBootDialog extends Dialog implements android.view.View.OnClickListener {
/**
* Creates a new FirstBootDialog
*
* @param context
* @author ricky barrette
*/
public FirstBootDialog(Context context) {
public FirstBootDialog(final Context context) {
super(context);
build(context);
}
/**
* Creates a new FirstBootDialog
* @param context
* @param theme
* @author ricky barrette
*/
public FirstBootDialog(Context context, int theme) {
super(context, theme);
build(context);
}
/**
* Creates a new FirstBootDialog
*
* @param context
* @param cancelable
* @param cancelListener
* @author ricky barrette
*/
public FirstBootDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
public FirstBootDialog(final Context context, final boolean cancelable, final OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
build(context);
}
/**
* Creates a new FirstBootDialog
*
* @param context
* @param theme
* @author ricky barrette
*/
public FirstBootDialog(final Context context, final int theme) {
super(context, theme);
build(context);
}
/**
* Builds the dialog
*
* @param context
* @author ricky barrette
*/
private void build(Context context) {
this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
private void build(final Context context) {
requestWindowFeature(Window.FEATURE_LEFT_ICON);
this.setContentView(R.layout.first_boot_dialog);
this.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.icon);
setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.icon);
this.setTitle(R.string.welcome);
this.findViewById(R.id.ok_button).setOnClickListener(this);
findViewById(R.id.ok_button).setOnClickListener(this);
}
/**
* called when the ok button is clicked
*/
@Override
public void onClick(View arg0) {
this.getContext().getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE).edit().putBoolean(SettingsActivity.IS_FIRST_BOOT, false).commit();
this.dismiss();
public void onClick(final View arg0) {
getContext().getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE).edit().putBoolean(SettingsActivity.IS_FIRST_BOOT, false).commit();
dismiss();
}
}

View File

@@ -66,7 +66,7 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
}
@Override
public WPSContinuation handleError(WPSReturnCode arg0) {
public WPSContinuation handleError(final WPSReturnCode arg0) {
Toast.makeText(this, R.string.skyhook_error_registration, Toast.LENGTH_SHORT).show();
return WPSContinuation.WPS_CONTINUE;
}
@@ -74,13 +74,14 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
@Override
public void handleSuccess() {
Toast.makeText(this, R.string.registered, Toast.LENGTH_SHORT).show();
this.mSettings.edit().putBoolean(SettingsActivity.IS_REGISTERED, true).commit();
mSettings.edit().putBoolean(SettingsActivity.IS_REGISTERED, true).commit();
}
/**
* called when the note edit activity finishes
* (non-Javadoc)
* @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
* called when the note edit activity finishes (non-Javadoc)
*
* @see android.app.Activity#onActivityResult(int, int,
* android.content.Intent)
* @author ricky barrette
*/
@Override
@@ -89,18 +90,19 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
if (resultCode == RESULT_OK) {
final ProgressDialog progress = ProgressDialog.show(this, "", this.getText(R.string.saving), true, true);
final ProgressDialog progress = ProgressDialog.show(this, "", getText(R.string.saving), true, true);
new Thread(new Runnable() {
@Override
public void run() {
switch (requestCode) {
case ACTIVITY_CREATE:
ContentValues ringer = (ContentValues) intent.getParcelableExtra(KEY_RINGER);
final ContentValues ringer = (ContentValues) intent.getParcelableExtra(KEY_RINGER);
mDb.insertRinger(ringer, (ContentValues) intent.getParcelableExtra(KEY_INFO));
break;
case ACTIVITY_EDIT:
mDb.updateRinger(intent.getLongExtra(KEY_ROWID, 1), (ContentValues) intent.getParcelableExtra(KEY_RINGER), (ContentValues) intent.getParcelableExtra(KEY_INFO));
mDb.updateRinger(intent.getLongExtra(KEY_ROWID, 1), (ContentValues) intent.getParcelableExtra(KEY_RINGER),
(ContentValues) intent.getParcelableExtra(KEY_INFO));
break;
}
@@ -109,7 +111,7 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
if (action.equals(ACTION_NEW_RINGER))
finish();
else
ListActivity.this.mListView.post(new Runnable(){
mListView.post(new Runnable() {
@Override
public void run() {
progress.dismiss();
@@ -127,18 +129,19 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
}
@Override
public void onClick(View v) {
Intent i = new Intent(this, RingerInformationActivity.class);
public void onClick(final View v) {
final Intent i = new Intent(this, RingerInformationActivity.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
/**
* called when the context menu item has been selected
* (non-Javadoc)
* called when the context menu item has been selected (non-Javadoc)
*
* @see android.app.Activity#onContextItemSelected(android.view.MenuItem)
* @author ricky barrette
*/
public boolean onContextItemSelected(MenuItem item) {
@Override
public boolean onContextItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
@@ -155,13 +158,14 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getIntent();
final String action = intent.getAction();
// If the intent is a request to create a shortcut, we'll do that and exit
// If the intent is a request to create a shortcut, we'll do that and
// exit
if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
setupShortcut();
@@ -171,21 +175,20 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
setContentView(R.layout.ringer_list);
this.setTitle(R.string.app_name);
this.mDb = new RingerDatabase(this, this);
this.mListView = (ListView) findViewById(R.id.ringer_list);
this.mListView.setOnItemClickListener(this);
this.mListView.setOnCreateContextMenuListener(this);
this.mListView.setEmptyView(findViewById(android.R.id.empty));
mDb = new RingerDatabase(this, this);
mListView = (ListView) findViewById(R.id.ringer_list);
mListView.setOnItemClickListener(this);
mListView.setOnCreateContextMenuListener(this);
mListView.setEmptyView(findViewById(android.R.id.empty));
findViewById(R.id.add_ringer_button).setOnClickListener(this);
populate();
this.mSettings = this.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
mSettings = getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
if(this.mSettings.getBoolean(SettingsActivity.IS_FIRST_BOOT, true))
if (mSettings.getBoolean(SettingsActivity.IS_FIRST_BOOT, true))
new FirstBootDialog(this).show();
if(! this.mSettings.getBoolean(SettingsActivity.IS_REGISTERED, false)){
if (!mSettings.getBoolean(SettingsActivity.IS_REGISTERED, false))
new SkyHookRegistration(this).registerNewUser(this);
}
// if(!this.getIntent().hasExtra(NO_SPLASH))
// showSplashScreen();
@@ -197,26 +200,29 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
/**
* called when the activity is first created, creates a context menu
*
* @param menu
* @param v
* @param menuInfo
* @return
* @author ricky barrette
*/
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
@Override
public void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ringer_list_context_menu, menu);
}
/**
* called when the activity is first created, creates options menu
* (non-Javadoc)
*
* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
* @author ricky barrette
*/
@Override
public boolean onCreateOptionsMenu (Menu menu) {
public boolean onCreateOptionsMenu(final Menu menu) {
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ringer_list_menu, menu);
return super.onCreateOptionsMenu(menu);
@@ -225,26 +231,31 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
/**
* Called when a database is being upgraded
*
* @author ricky barrette
*/
@Override
public void onDatabaseUpgrade() {
this.mProgress = ProgressDialog.show(this, "", this.getText(R.string.upgrading), true, true);
mProgress = ProgressDialog.show(this, "", getText(R.string.upgrading), true, true);
}
/**
* called when a database upgrade is finished
*
* @author ricky barrette
*/
@Override
public void onDatabaseUpgradeComplete() {
populate();
if(this.mProgress != null)
this.mProgress.dismiss();
if (mProgress != null)
mProgress.dismiss();
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see android.app.Activity#onDestroy()
*
* @author ricky barrette
*/
@Override
@@ -255,16 +266,17 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
}
/**
* called when an item in the list view has been clicked,
* this will open the note edit dialog for the selected note
* (non-Javadoc)
* @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
* called when an item in the list view has been clicked, this will open the
* note edit dialog for the selected note (non-Javadoc)
*
* @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView,
* android.view.View, int, long)
* @author ricky barrette
*/
@Override
public void onItemClick(AdapterView<?> arg0, View v, int postion, final long id) {
public void onItemClick(final AdapterView<?> arg0, final View v, final int postion, final long id) {
final ProgressDialog progress = ProgressDialog.show(this, "", this.getText(R.string.loading), true, true);
final ProgressDialog progress = ProgressDialog.show(this, "", getText(R.string.loading), true, true);
// post to social sites in a new thread to prevent ANRs
new Thread(new Runnable() {
@@ -279,14 +291,13 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
*/
final Cursor ringer = mDb.getRingerFromId(id + 1);
if (ringer.moveToFirst()) {
ContentValues r = new ContentValues();
final ContentValues r = new ContentValues();
r.put(RingerDatabase.KEY_RINGER_NAME, ringer.getString(0));
r.put(RingerDatabase.KEY_IS_ENABLED, RingerDatabase.parseBoolean(ringer.getString(1)));
i.putExtra(KEY_RINGER, r);
if (ringer != null && !ringer.isClosed()) {
if (ringer != null && !ringer.isClosed())
ringer.close();
}
if (id == 0)
i.putExtra(KEY_IS_DEFAULT, true);
@@ -307,13 +318,13 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
}
/**
* called when an option is selected form the menu
* (non-Javadoc)
* called when an option is selected form the menu (non-Javadoc)
*
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
* @author ricky barrette
*/
@Override
public boolean onOptionsItemSelected (MenuItem item) {
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
@@ -334,6 +345,7 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
/**
* (non-Javadoc)
*
* @see android.app.Activity#onPause()
*/
@Override
@@ -360,10 +372,11 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
/**
* populates the list view from the data base
*
* @author ricky barrette
*/
private void populate() {
findViewById(R.id.add_ringer_button_hint).setVisibility(this.mDb.getAllRingerTitles().size() > 1 ? View.GONE : View.VISIBLE);
findViewById(R.id.add_ringer_button_hint).setVisibility(mDb.getAllRingerTitles().size() > 1 ? View.GONE : View.VISIBLE);
mListView.setAdapter(new RingerListAdapter(this, mDb));
}
@@ -379,13 +392,14 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
/**
* Restarts the service if its not already running.
*
* @author ricky barrette
*/
private void restartService() {
final SharedPreferences sharedPrefs = this.getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
final SharedPreferences sharedPrefs = getSharedPreferences(SettingsActivity.SETTINGS, Debug.SHARED_PREFS_MODE);
if (!sharedPrefs.getBoolean(SettingsActivity.IS_SERVICE_STARTED, false)) {
// cancel the previous service
LocationService.stopService(this).run();
com.TwentyCodes.android.location.LocationService.stopService(this).run();
// start the new service
LocationService.startMultiShotService(this);
}
@@ -393,17 +407,18 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
/**
* Creates a shortcut for the launcher
*
* @author ricky barrette
*/
private void setupShortcut() {
Intent shortcutIntent = new Intent(this, this.getClass());
final Intent shortcutIntent = new Intent(this, this.getClass());
shortcutIntent.setAction(ACTION_NEW_RINGER);
// set up the container intent and return to the launcher
Intent intent = new Intent();
final Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.new_ringer));
Parcelable iconResource = Intent.ShortcutIconResource.fromContext(this, R.drawable.icon);
final Parcelable iconResource = Intent.ShortcutIconResource.fromContext(this, R.drawable.icon);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
setResult(RESULT_OK, intent);
}
@@ -429,7 +444,8 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
// * uncomment the following to display the eula
// */
// // //loads first boot dialog if this is the first boot
//// if (! mSettings.getBoolean(Settings.ACCEPTED, false) || Debug.FORCE_FIRSTBOOT_DIALOG)
// // if (! mSettings.getBoolean(Settings.ACCEPTED, false) ||
// Debug.FORCE_FIRSTBOOT_DIALOG)
// // eulaAlert();
// // else
// // update();

View File

@@ -40,6 +40,7 @@ import com.jakewharton.android.viewpagerindicator.TitledFragmentAdapter;
/**
* This activity will handle displaying ringer options
*
* @author ricky
*/
public class RingerInformationActivity extends FragmentActivity implements OnContentChangedListener, EnableScrollingListener, OnPageChangeListener {
@@ -53,21 +54,23 @@ public class RingerInformationActivity extends FragmentActivity implements OnCon
/**
* Logs the content values
*
* @param values
* @author ricky barrette
*/
private void logContentValues(ContentValues values) {
for(Entry<String,Object> item : values.valueSet())
private void logContentValues(final ContentValues values) {
for (final Entry<String, Object> item : values.valueSet())
Log.d(TAG, item.getKey() + " = " + item.getValue());
}
/**
* Called when the activity is first created
* (non-Javadoc)
* Called when the activity is first created (non-Javadoc)
*
* @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle arg0) {
protected void onCreate(final Bundle arg0) {
super.onCreate(arg0);
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
@@ -81,98 +84,103 @@ public class RingerInformationActivity extends FragmentActivity implements OnCon
if (Debug.SUPPORTS_HONEYCOMB)
getActionBar().setDisplayHomeAsUpEnabled(true);
this.mData = new Intent().putExtras(intent);
mData = new Intent().putExtras(intent);
this.mRinger = this.mData.getParcelableExtra(ListActivity.KEY_RINGER);
this.mInfo = this.mData.getParcelableExtra(ListActivity.KEY_INFO);
mRinger = mData.getParcelableExtra(ListActivity.KEY_RINGER);
mInfo = mData.getParcelableExtra(ListActivity.KEY_INFO);
if(this.mRinger == null)
this.mRinger = new ContentValues();
if(this.mInfo == null)
this.mInfo = new ContentValues();
if (mRinger == null)
mRinger = new ContentValues();
if (mInfo == null)
mInfo = new ContentValues();
/*
* set the title
*/
this.setTitle(this.mRinger.containsKey(RingerDatabase.KEY_RINGER_NAME) ?this.getString(R.string.editing)+" "+this.mRinger.getAsString(RingerDatabase.KEY_RINGER_NAME)
this.setTitle(mRinger.containsKey(RingerDatabase.KEY_RINGER_NAME) ? this.getString(R.string.editing) + " " + mRinger.getAsString(RingerDatabase.KEY_RINGER_NAME)
: getString(R.string.new_ringer));
boolean isDefault = getString(R.string.default_ringer).equals(this.mRinger.getAsString(RingerDatabase.KEY_RINGER_NAME));
final boolean isDefault = getString(R.string.default_ringer).equals(mRinger.getAsString(RingerDatabase.KEY_RINGER_NAME));
/*
* Page titles
*/
String[] titles = this.getResources().getStringArray(isDefault ? R.array.ringer_info_titles_default : R.array.ringer_info_titles);
final String[] titles = getResources().getStringArray(isDefault ? R.array.ringer_info_titles_default : R.array.ringer_info_titles);
ArrayList<Fragment> fragments = new ArrayList<Fragment>();
final ArrayList<Fragment> fragments = new ArrayList<Fragment>();
/*
* about page
*/
if (!isDefault)
fragments.add(new AboutRingerFragment(this.mRinger, this.mInfo, this));
fragments.add(new AboutRingerFragment(mRinger, mInfo, this));
/*
* Location page
*/
if (!isDefault) {
this.mLocationInfomationFragment = new LocationInfomationFragment(this.mInfo, this, this);
fragments.add(this.mLocationInfomationFragment);
mLocationInfomationFragment = new LocationInfomationFragment(mInfo, this, this);
fragments.add(mLocationInfomationFragment);
}
fragments.add(new FeatureListFragment(this.mInfo, this));
fragments.add(new FeatureListFragment(mInfo, this));
// Populate the pager
this.mPager = (ViewPager)findViewById(R.id.pager);
if(this.mPager != null)
this.mPager.setAdapter(new TitledFragmentAdapter(this.getSupportFragmentManager(), fragments, titles));
mPager = (ViewPager) findViewById(R.id.pager);
if (mPager != null)
mPager.setAdapter(new TitledFragmentAdapter(getSupportFragmentManager(), fragments, titles));
// populate the pager's indicator
TitlePageIndicator indicator = (TitlePageIndicator)findViewById(R.id.indicator);
final TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.indicator);
if (indicator != null)
indicator.setViewPager(this.mPager);
indicator.setViewPager(mPager);
indicator.setOnPageChangeListener(this);
}
/**
* Creates the main menu that is displayed when the menu button is clicked
*
* @author ricky barrette
*/
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ringer_info_menu, menu);
return super.onCreateOptionsMenu(menu);
}
/**
* Called when the ringer info has changed
* (non-Javadoc)
* Called when the ringer info has changed (non-Javadoc)
*
* @see com.TwentyCodes.android.LocationRinger.OnContentChangedListener#onInfoContentChanged(android.content.ContentValues)
*/
@Override
public void onInfoContentChanged(ContentValues values) {
public void onInfoContentChanged(final ContentValues values) {
if (Debug.DEBUG) {
Log.v(TAG, "onInfoContentChanged()");
logContentValues(values);
}
this.mInfo.putAll(values);
mInfo.putAll(values);
}
/**
* Called when a feature is removed
* (non-Javadoc)
* Called when a feature is removed (non-Javadoc)
*
* @see com.TwentyCodes.android.LocationRinger.OnContentChangedListener#onInfoContentRemoved(java.lang.String[])
*/
@Override
public void onInfoContentRemoved(String... keys) {
for(String key : keys)
if(this.mInfo.containsKey(key))
this.mInfo.remove(key);
public void onInfoContentRemoved(final String... keys) {
for (final String key : keys)
if (mInfo.containsKey(key))
mInfo.remove(key);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*
* @author ricky barrette
*/
@Override
@@ -189,67 +197,70 @@ public class RingerInformationActivity extends FragmentActivity implements OnCon
return super.onOptionsItemSelected(item);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
public void onPageScrolled(final int arg0, final float arg1, final int arg2) {
// TODO Auto-generated method stub
}
/**
* called when the pager's page is changed
* we use this to dismiss the soft keyboard
* (non-Javadoc)
* called when the pager's page is changed we use this to dismiss the soft
* keyboard (non-Javadoc)
*
* @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
*/
@Override
public void onPageScrollStateChanged(int arg0) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
public void onPageScrollStateChanged(final int arg0) {
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mPager.getWindowToken(), 0);
}
@Override
public void onPageSelected(int arg0) {
public void onPageSelected(final int arg0) {
}
/**
* Called when the ringer content has been changed
* (non-Javadoc)
* Called when the ringer content has been changed (non-Javadoc)
*
* @see com.TwentyCodes.android.LocationRinger.OnContentChangedListener#onRingerContentChanged(android.content.ContentValues)
*/
@Override
public void onRingerContentChanged(ContentValues values) {
public void onRingerContentChanged(final ContentValues values) {
if (Debug.DEBUG) {
Log.v(TAG, "onRingerContentChanged()");
logContentValues(values);
}
this.mRinger.putAll(values);
mRinger.putAll(values);
}
/**
* (non-Javadoc)
*
* @see android.app.Activity#onSearchRequested()
*/
@Override
public boolean onSearchRequested() {
if(this.mLocationInfomationFragment != null && this.mPager.getCurrentItem() == 1)
return this.mLocationInfomationFragment.onSearchRequested();
if (mLocationInfomationFragment != null && mPager.getCurrentItem() == 1)
return mLocationInfomationFragment.onSearchRequested();
return super.onSearchRequested();
}
/**
* Prepares a bundle containing all the information that needs to be saved, and returns it to the starting activity
* Prepares a bundle containing all the information that needs to be saved,
* and returns it to the starting activity
*
* @author ricky barrette
*/
private void save() {
final ProgressDialog progress = ProgressDialog.show(this, "", this.getText(R.string.saving), true, true);
final ProgressDialog progress = ProgressDialog.show(this, "", getText(R.string.saving), true, true);
//Generate the intent in a thread to prevent anr's and allow for progress dialog
// Generate the intent in a thread to prevent anr's and allow for
// progress dialog
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
RingerInformationActivity.this.mData.putExtra(ListActivity.KEY_RINGER, RingerInformationActivity.this.mRinger).putExtra(ListActivity.KEY_INFO, RingerInformationActivity.this.mInfo);
RingerInformationActivity.this.setResult(Activity.RESULT_OK, RingerInformationActivity.this.mData);
mData.putExtra(ListActivity.KEY_RINGER, mRinger).putExtra(ListActivity.KEY_INFO, mInfo);
RingerInformationActivity.this.setResult(Activity.RESULT_OK, mData);
progress.dismiss();
RingerInformationActivity.this.finish();
}
@@ -259,11 +270,12 @@ public class RingerInformationActivity extends FragmentActivity implements OnCon
/**
* Called when the scrolling state of the view pager is changed
* (non-Javadoc)
*
* @see com.TwentyCodes.android.LocationRinger.EnableScrollingListener#setScrollEnabled(boolean)
*/
@Override
public void setScrollEnabled(boolean enabled) {
this.mPager.setScrollEnabled(enabled);
public void setScrollEnabled(final boolean enabled) {
mPager.setScrollEnabled(enabled);
}
}

View File

@@ -24,26 +24,35 @@ import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This adapter will be used to populate the list view with all the ringers names, and manage enabling/disabling of ringers based on their check box.
* This adapter will be used to populate the list view with all the ringers
* names, and manage enabling/disabling of ringers based on their check box.
*
* @author ricky barrette
*/
public class RingerListAdapter extends BaseAdapter {
private static final String TAG = "RingerListAdapter";
class ViewHolder {
TextView title;
TextView description;
CheckBox checkbox;
}
private RingerDatabase mDb;
private List<String> mTitles;
private LayoutInflater mInflater;
private List<String> mDescriptions;
private static final String TAG = "RingerListAdapter";
private final RingerDatabase mDb;
private final List<String> mTitles;
private final LayoutInflater mInflater;
private final List<String> mDescriptions;
/**
* Creates a new RingerListAdapter
*
* @param context
* @param listener
* @param db
* @author ricky barrette
*/
public RingerListAdapter(Context context, RingerDatabase db) {
public RingerListAdapter(final Context context, final RingerDatabase db) {
super();
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
@@ -58,29 +67,33 @@ public class RingerListAdapter extends BaseAdapter {
}
@Override
public String getItem(int position) {
public String getItem(final int position) {
return mTitles.get(position);
}
@Override
public long getItemId(int position) {
public long getItemId(final int position) {
return position;
}
@SuppressWarnings("unused")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
public View getView(final int position, View convertView, final ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unnecessary calls to findViewById() on each row.
// A ViewHolder keeps references to children views to avoid unnecessary
// calls to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// When convertView is not null, we can reuse it directly, there is no
// need
// to reinflate it. We only inflate a new View when the convertView
// supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
// Creates a ViewHolder and store references to the two children views
// Creates a ViewHolder and store references to the two children
// views
// we want to bind data to.
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(android.R.id.text1);
@@ -88,11 +101,10 @@ public class RingerListAdapter extends BaseAdapter {
holder.checkbox = (CheckBox) convertView.findViewById(R.id.ringer_enabled_checkbox);
convertView.setTag(holder);
} else {
} else
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
if (Debug.DEBUG) {
Log.d(TAG, "postion = " + position);
@@ -111,15 +123,15 @@ public class RingerListAdapter extends BaseAdapter {
}
/*
* Bind the data efficiently with the holder.
* Remember that you should always call setChecked() after calling setOnCheckedChangedListener.
* Bind the data efficiently with the holder. Remember that you should
* always call setChecked() after calling setOnCheckedChangedListener.
* This will prevent the list from changing the values on you.
*/
holder.title.setText(getItem(position));
holder.description.setText(mDescriptions.get(position));
holder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
mDb.setRingerEnabled(position + 1, isChecked);
}
});
@@ -130,16 +142,9 @@ public class RingerListAdapter extends BaseAdapter {
holder.checkbox.setVisibility(View.INVISIBLE);
if (holder.description.getText().toString() == null)
holder.description.setText(R.string.about_default_ringer);
}
else
} else
holder.checkbox.setVisibility(View.VISIBLE);
return convertView;
}
class ViewHolder {
TextView title;
TextView description;
CheckBox checkbox;
}
}

View File

@@ -36,26 +36,29 @@ import com.TwentyCodes.android.location.ReverseGeocoder;
import com.google.android.maps.GeoPoint;
/**
* This dialog will be used to get users input for the address that they want to search for. A GeoPoint location will be returned via LocationSelectedListener
* This dialog will be used to get users input for the address that they want to
* search for. A GeoPoint location will be returned via LocationSelectedListener
*
* @author ricky barrette
*/
public class SearchDialog extends Dialog implements android.view.View.OnClickListener, OnItemClickListener, OnEditorActionListener {
protected static final String TAG = "SearchDialog";
private ListView mAddressList;
private EditText mAddress;
private final ListView mAddressList;
private final EditText mAddress;
private JSONArray mResults;
private ProgressBar mProgress;
private Handler mHandler;
private Context mContext;
private OnLocationSelectedListener mListener;
private final ProgressBar mProgress;
private final Handler mHandler;
private final Context mContext;
private final OnLocationSelectedListener mListener;
/**
* Creates a new search dialog
*
* @param context
* @author ricky barrette
*/
public SearchDialog(Context context, OnLocationSelectedListener listener) {
public SearchDialog(final Context context, final OnLocationSelectedListener listener) {
super(context);
this.setTitle(R.string.search);
this.setContentView(R.layout.address_dialog);
@@ -64,28 +67,27 @@ public class SearchDialog extends Dialog implements android.view.View.OnClickLis
mAddressList.setOnItemClickListener(this);
mAddress = (EditText) findViewById(R.id.address);
mAddress.setOnEditorActionListener(this);
this.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
mProgress = (ProgressBar) findViewById(R.id.search_progress);
mHandler = new Handler();
mContext = context;
mListener = listener;
}
/**
* Retrieves all the strings from the JSON Array
*
* @return list of addresses
* @author ricky barrette
*/
private ArrayList<String> getAddress() {
if (Debug.DEBUG)
Log.d(TAG, "getAddress()");
ArrayList<String> list = new ArrayList<String>();
final ArrayList<String> list = new ArrayList<String>();
try {
for(int i = 0; i < mResults.length(); i++){
for (int i = 0; i < mResults.length(); i++)
list.add(mResults.getJSONObject(i).getString("address"));
}
} catch (JSONException e) {
} catch (final JSONException e) {
e.printStackTrace();
return null;
}
@@ -94,27 +96,29 @@ public class SearchDialog extends Dialog implements android.view.View.OnClickLis
/**
* Retrieves the GeoPoint from the JSON Array for the given index
* @param index for the place
*
* @param index
* for the place
* @return GeoPoint of the place
* @author ricky barrette
*/
private GeoPoint getCoords(int index){
private GeoPoint getCoords(final int index) {
if (Debug.DEBUG)
Log.d(TAG, "getCoords()");
try {
JSONArray coords = mResults.getJSONObject(index).getJSONObject("Point").getJSONArray("coordinates");
final JSONArray coords = mResults.getJSONObject(index).getJSONObject("Point").getJSONArray("coordinates");
if (Debug.DEBUG)
Log.d(TAG, "creating geopoint: " + new GeoPoint((int) (coords.getDouble(1) * 1E6), (int) (coords.getDouble(0) * 1E6)).toString());
return new GeoPoint((int) (coords.getDouble(1) * 1E6), (int) (coords.getDouble(0) * 1E6));
} catch (JSONException e) {
} catch (final JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* Called when the search button is clicked
* (non-Javadoc)
* Called when the search button is clicked (non-Javadoc)
*
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
@@ -129,31 +133,34 @@ public class SearchDialog extends Dialog implements android.view.View.OnClickLis
/**
* Called when the seach button on the soft keyboard is pressed
* (non-Javadoc)
* @see android.widget.TextView.OnEditorActionListener#onEditorAction(android.widget.TextView, int, android.view.KeyEvent)
*
* @see android.widget.TextView.OnEditorActionListener#onEditorAction(android.widget.TextView,
* int, android.view.KeyEvent)
*/
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
search();
return false;
}
/**
* Called when an Item from the list is selected
* (non-Javadoc)
* @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
* Called when an Item from the list is selected (non-Javadoc)
*
* @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView,
* android.view.View, int, long)
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
if (Debug.DEBUG)
Log.d(TAG, "slected " + (int) id);
mListener.onLocationSelected(getCoords((int) id));
this.dismiss();
dismiss();
}
private void search() {
final InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(this.mAddress.getWindowToken(), 0);
final View v = this.findViewById(R.id.ok);
imm.hideSoftInputFromWindow(mAddress.getWindowToken(), 0);
final View v = findViewById(R.id.ok);
v.setEnabled(false);
mProgress.setVisibility(View.VISIBLE);
mProgress.setIndeterminate(true);
@@ -164,9 +171,9 @@ public class SearchDialog extends Dialog implements android.view.View.OnClickLis
Log.d(TAG, "strarting search and parsing");
try {
mResults = ReverseGeocoder.addressSearch(mAddress.getText().toString());
} catch (IOException e) {
} catch (final IOException e) {
e.printStackTrace();
} catch (JSONException e) {
} catch (final JSONException e) {
e.printStackTrace();
}
if (mResults != null) {
@@ -186,7 +193,7 @@ public class SearchDialog extends Dialog implements android.view.View.OnClickLis
Log.d(TAG, "finished");
}
});
} else {
} else
// update the UI
mHandler.post(new Runnable() {
@Override
@@ -199,7 +206,6 @@ public class SearchDialog extends Dialog implements android.view.View.OnClickLis
}
});
}
}
}).start();
}
}

View File

@@ -31,6 +31,7 @@ import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This is the settings activity for location ringer
*
* @author ricky barrette
*/
public class SettingsActivity extends PreferenceActivity implements OnPreferenceClickListener {
@@ -49,6 +50,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
/**
* Backs up the database
*
* @return true if successful
* @author ricky barrette
*/
@@ -56,16 +58,15 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
final File dbFile = new File(Environment.getDataDirectory() + "/data/" + context.getPackageName() + "/shared_prefs/" + SETTINGS + ".xml");
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/" + context.getString(R.string.app_name));
if (!exportDir.exists()) {
if (!exportDir.exists())
exportDir.mkdirs();
}
final File file = new File(exportDir, dbFile.getName());
try {
file.createNewFile();
copyFile(dbFile, file);
return true;
} catch (IOException e) {
} catch (final IOException e) {
e.printStackTrace();
return false;
}
@@ -73,8 +74,11 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
/**
* Copies a file
* @param src file
* @param dst file
*
* @param src
* file
* @param dst
* file
* @throws IOException
* @author ricky barrette
*/
@@ -100,6 +104,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
/**
* Restores the database from the sdcard
*
* @return true if successful
* @author ricky barrette
*/
@@ -107,15 +112,14 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
final File dbFile = new File(Environment.getDataDirectory() + "/data/" + context.getPackageName() + "/shared_prefs/" + SETTINGS + ".xml");
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/" + context.getString(R.string.app_name));
if (!exportDir.exists()) {
if (!exportDir.exists())
exportDir.mkdirs();
}
final File file = new File(exportDir, dbFile.getName());
try {
file.createNewFile();
copyFile(file, dbFile);
} catch (IOException e) {
} catch (final IOException e) {
e.printStackTrace();
}
@@ -124,6 +128,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
/**
* generates the exception repost email intent
*
* @param report
* @return intent to start users email client
* @author ricky barrette
@@ -132,11 +137,11 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
/*
* get the build information, and build the string
*/
final PackageManager pm = this.getPackageManager();
final PackageManager pm = getPackageManager();
PackageInfo pi;
try {
pi = pm.getPackageInfo(this.getPackageName(), 0);
} catch (NameNotFoundException eNnf) {
pi = pm.getPackageInfo(getPackageName(), 0);
} catch (final NameNotFoundException eNnf) {
// doubt this will ever run since we want info about our own package
pi = new PackageInfo();
pi.versionName = "unknown";
@@ -158,10 +163,10 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getPreferenceManager().setSharedPreferencesMode(Debug.SHARED_PREFS_MODE);
this.getPreferenceManager().setSharedPreferencesName(SETTINGS);
getPreferenceManager().setSharedPreferencesMode(Debug.SHARED_PREFS_MODE);
getPreferenceManager().setSharedPreferencesName(SETTINGS);
addPreferencesFromResource(R.xml.setings);
this.findPreference(EMAIL).setOnPreferenceClickListener(this);
findPreference(EMAIL).setOnPreferenceClickListener(this);
/*
* Set up the action bar if required
@@ -172,6 +177,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
/**
* (non-Javadoc)
*
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
* @author ricky barrette
*/
@@ -190,7 +196,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
* called when the email preference button is clicked
*/
@Override
public boolean onPreferenceClick(Preference preference) {
public boolean onPreferenceClick(final Preference preference) {
this.startActivity(generateEmailIntent());
return false;
}

View File

@@ -11,60 +11,66 @@ import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* this class will be a simple TextView to be used in a preference activity. you set the text using the set title tag
* this class will be a simple TextView to be used in a preference activity. you
* set the text using the set title tag
*
* @author ricky barrette
*/
public class TextViewPreference extends Preference {
/**
* creates a preference that is nothing but a text view
*
* @param context
*/
public TextViewPreference(Context context) {
public TextViewPreference(final Context context) {
super(context);
// TODO Auto-generated constructor stub
}
/**
* creates a preference that is nothing but a text view
*
* @param context
* @param attrs
*/
public TextViewPreference(Context context, AttributeSet attrs) {
public TextViewPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
/**
* creates a preference that is nothing but a text view
*
* @param context
* @param attrs
* @param defStyle
*/
public TextViewPreference(Context context, AttributeSet attrs, int defStyle) {
public TextViewPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
/**
* creates a linear layout the contains only a textview.
* (non-Javadoc)
* creates a linear layout the contains only a textview. (non-Javadoc)
*
* @see android.preference.Preference#onCreateView(android.view.ViewGroup)
* @param parent
* @return
* @author ricky barrette
*/
@Override
protected View onCreateView(ViewGroup parent){
protected View onCreateView(final ViewGroup parent) {
/*
* create a vertical linear layout that width and height that wraps content
* create a vertical linear layout that width and height that wraps
* content
*/
LinearLayout layout = new LinearLayout(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
final LinearLayout layout = new LinearLayout(getContext());
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
layout.setPadding(15, 5, 10, 5);
layout.setOrientation(LinearLayout.VERTICAL);
@@ -72,10 +78,10 @@ public class TextViewPreference extends Preference {
layout.removeAllViews();
/*
* create a textview that will be used to display the title provided in xml
* and add it to the lay out
* create a textview that will be used to display the title provided in
* xml and add it to the lay out
*/
TextView title = new TextView(getContext());
final TextView title = new TextView(getContext());
title.setText(getTitle());
title.setTextSize(16);
title.setTypeface(Typeface.SANS_SERIF);

View File

@@ -22,7 +22,7 @@ public class ViewPager extends android.support.v4.view.ViewPager {
* @param apiKey
* @author ricky barrette
*/
public ViewPager(Context context) {
public ViewPager(final Context context) {
super(context);
}
@@ -31,27 +31,28 @@ public class ViewPager extends android.support.v4.view.ViewPager {
* @param attrs
* @author ricky barrette
*/
public ViewPager(Context context, AttributeSet attrs) {
public ViewPager(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
/**
* Enables or disabled the scrollview's ability to scroll
* @param enabled
* @author ricky barrette
*/
public void setScrollEnabled(boolean enabled){
isEnabled = enabled;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
public boolean onInterceptTouchEvent(final MotionEvent ev) {
return isEnabled ? super.onInterceptTouchEvent(ev) : false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
public boolean onTouchEvent(final MotionEvent ev) {
return isEnabled ? super.onTouchEvent(ev) : false;
}
/**
* Enables or disabled the scrollview's ability to scroll
*
* @param enabled
* @author ricky barrette
*/
public void setScrollEnabled(final boolean enabled) {
isEnabled = enabled;
}
}

View File

@@ -8,11 +8,6 @@ package com.TwentyCodes.android.LocationRinger.ui.fragments;
import java.util.Map.Entry;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.OnContentChangedListener;
import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
@@ -30,84 +25,23 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ToggleButton;
import com.TwentyCodes.android.LocationRinger.OnContentChangedListener;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This fragment will used to allow the user to enter/edit ringer information
*
* @author ricky
*/
@SuppressLint({ "ValidFragment", "ValidFragment" })
public class AboutRingerFragment extends Fragment implements OnCheckedChangeListener {
private static final String TAG = "AboutRingerFragment";
private ListeningEditText mRingerName;
private ListeningEditText mRingerDescription;
private ToggleButton mRingerEnabled;
private final OnContentChangedListener mListener;
private final ContentValues mInfo;
private final ContentValues mRinger;
public AboutRingerFragment(final ContentValues ringer, final ContentValues info, final OnContentChangedListener listener){
super();
this.mInfo = info;
this.mRinger = ringer;
this.mListener = listener;
}
@Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
if(this.mListener != null){
final ContentValues info = new ContentValues();
info.put(RingerDatabase.KEY_IS_ENABLED, isChecked);
this.mListener.onRingerContentChanged(info);
}
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
this.getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
final View view = inflater.inflate(R.layout.ringer_about_fragment, container, false);
if(Debug.DEBUG){
for(Entry<String,Object> item : this.mInfo.valueSet())
Log.d(TAG, item.getKey() +" = "+ item.getValue());
for(Entry<String,Object> item : this.mRinger.valueSet())
Log.d(TAG, item.getKey() +" = "+ item.getValue());
}
/*
* ringer name
*/
this.mRingerName = (ListeningEditText) view.findViewById(R.id.ringer_name);
if(this.mRinger.containsKey(RingerDatabase.KEY_RINGER_NAME))
this.mRingerName.setText(this.mRinger.getAsString(RingerDatabase.KEY_RINGER_NAME));
this.mRingerName.setKey(RingerDatabase.KEY_RINGER_NAME);
this.mRingerName.setListener(this.mListener);
/*
* ringer description
*/
this.mRingerDescription = (ListeningEditText) view.findViewById(R.id.ringer_description);
if(this.mInfo.containsKey(RingerDatabase.KEY_RINGER_DESCRIPTION))
this.mRingerDescription.setText(this.mInfo.getAsString(RingerDatabase.KEY_RINGER_DESCRIPTION));
this.mRingerDescription.setKey(RingerDatabase.KEY_RINGER_DESCRIPTION);
this.mRingerDescription.setListener(this.mListener);
/*
* ringer enabled
*/
this.mRingerEnabled = (ToggleButton) view.findViewById(R.id.ringer_enabled);
if(this.mRinger.containsKey(RingerDatabase.KEY_IS_ENABLED))
this.mRingerEnabled.setChecked(this.mRinger.getAsBoolean(RingerDatabase.KEY_IS_ENABLED));
this.mRingerEnabled.setOnCheckedChangeListener(this);
return view;
}
/**
* This Edit text class is used in place of a standard edit text.
* It will update the pass the updated information though a listener
* This Edit text class is used in place of a standard edit text. It will
* update the pass the updated information though a listener
*
* @author ricky barrette
*/
public static class ListeningEditText extends EditText {
@@ -117,70 +51,145 @@ public class AboutRingerFragment extends Fragment implements OnCheckedChangeList
/**
* Creates a new ListeningEditText
*
* @param context
* @author ricky barrette
*/
public ListeningEditText(Context context) {
public ListeningEditText(final Context context) {
super(context);
this.mTemp = new ContentValues();
mTemp = new ContentValues();
}
/**
* Creates a new ListeningEditText
*
* @param context
* @param attrs
* @author ricky barrette
*/
public ListeningEditText(Context context, AttributeSet attrs) {
public ListeningEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
this.mTemp = new ContentValues();
mTemp = new ContentValues();
}
/**
* Creates a new ListeningEditText
*
* @param context
* @param attrs
* @param defStyle
* @author ricky barrette
*/
public ListeningEditText(Context context, AttributeSet attrs, int defStyle) {
public ListeningEditText(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
this.mTemp = new ContentValues();
mTemp = new ContentValues();
}
/**
* Called when the edit text is drawn
*
* @author ricky barrette
*/
@Override
public void onDraw(Canvas canvas){
public void onDraw(final Canvas canvas) {
super.onDraw(canvas);
if (mListener != null) {
mTemp.put(this.mKey, this.getText().toString());
if(this.mKey.equals(RingerDatabase.KEY_RINGER_NAME))
this.mListener.onRingerContentChanged(mTemp);
mTemp.put(mKey, this.getText().toString());
if (mKey.equals(RingerDatabase.KEY_RINGER_NAME))
mListener.onRingerContentChanged(mTemp);
else
this.mListener.onInfoContentChanged(mTemp);
mListener.onInfoContentChanged(mTemp);
}
}
/**
* Sets the key for this ListeningEditText
*
* @param key
* @ author ricky barrette
*/
public void setKey(String key){
this.mKey = key;
public void setKey(final String key) {
mKey = key;
}
/**
* Sets the listener of this ListeningEditText
*
* @param listener
* @ author ricky barrette
*/
public void setListener(OnContentChangedListener listener){
this.mListener = listener;
public void setListener(final OnContentChangedListener listener) {
mListener = listener;
}
}
private static final String TAG = "AboutRingerFragment";
private ListeningEditText mRingerName;
private ListeningEditText mRingerDescription;
private ToggleButton mRingerEnabled;
private final OnContentChangedListener mListener;
private final ContentValues mInfo;
private final ContentValues mRinger;
public AboutRingerFragment(final ContentValues ringer, final ContentValues info, final OnContentChangedListener listener) {
super();
mInfo = info;
mRinger = ringer;
mListener = listener;
}
@Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
if (mListener != null) {
final ContentValues info = new ContentValues();
info.put(RingerDatabase.KEY_IS_ENABLED, isChecked);
mListener.onRingerContentChanged(info);
}
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
final View view = inflater.inflate(R.layout.ringer_about_fragment, container, false);
if (Debug.DEBUG) {
for (final Entry<String, Object> item : mInfo.valueSet())
Log.d(TAG, item.getKey() + " = " + item.getValue());
for (final Entry<String, Object> item : mRinger.valueSet())
Log.d(TAG, item.getKey() + " = " + item.getValue());
}
/*
* ringer name
*/
mRingerName = (ListeningEditText) view.findViewById(R.id.ringer_name);
if (mRinger.containsKey(RingerDatabase.KEY_RINGER_NAME))
mRingerName.setText(mRinger.getAsString(RingerDatabase.KEY_RINGER_NAME));
mRingerName.setKey(RingerDatabase.KEY_RINGER_NAME);
mRingerName.setListener(mListener);
/*
* ringer description
*/
mRingerDescription = (ListeningEditText) view.findViewById(R.id.ringer_description);
if (mInfo.containsKey(RingerDatabase.KEY_RINGER_DESCRIPTION))
mRingerDescription.setText(mInfo.getAsString(RingerDatabase.KEY_RINGER_DESCRIPTION));
mRingerDescription.setKey(RingerDatabase.KEY_RINGER_DESCRIPTION);
mRingerDescription.setListener(mListener);
/*
* ringer enabled
*/
mRingerEnabled = (ToggleButton) view.findViewById(R.id.ringer_enabled);
if (mRinger.containsKey(RingerDatabase.KEY_IS_ENABLED))
mRingerEnabled.setChecked(mRinger.getAsBoolean(RingerDatabase.KEY_IS_ENABLED));
mRingerEnabled.setOnCheckedChangeListener(this);
return view;
}
}

View File

@@ -6,9 +6,6 @@
*/
package com.TwentyCodes.android.LocationRinger.ui.fragments;
import com.TwentyCodes.android.LocationRinger.FeatureRemovedListener;
import com.TwentyCodes.android.LocationRinger.R;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@@ -18,8 +15,12 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.TwentyCodes.android.LocationRinger.FeatureRemovedListener;
import com.TwentyCodes.android.LocationRinger.R;
/**
* This is a simple extention of a fragment that will allow for storage of an id
*
* @author ricky barrette
*/
@SuppressLint("ValidFragment")
@@ -33,24 +34,26 @@ public class BaseFeatureFragment extends Fragment implements OnClickListener{
/**
* Creates a new Feature Fragment
*
* @param id
* @param layout
* @param listener
* @author ricky barrette
*/
public BaseFeatureFragment(int id, int layout, FeatureRemovedListener listener){
public BaseFeatureFragment(final int id, final int layout, final FeatureRemovedListener listener) {
this(id, layout, -1, listener);
}
/**
* Creates a new FeatureFragment
*
* @param id
* @param layout
* @param icon
* @param listener
* @author ricky barrette
*/
public BaseFeatureFragment(int id, int layout, int icon, FeatureRemovedListener listener){
public BaseFeatureFragment(final int id, final int layout, final int icon, final FeatureRemovedListener listener) {
super();
if (listener == null)
throw new NullPointerException();
@@ -69,36 +72,40 @@ public class BaseFeatureFragment extends Fragment implements OnClickListener{
/**
* Called when the user clicks the remove button
*
* @param v
* @author ricky barrette
*/
@Override
public void onClick(View v) {
public void onClick(final View v) {
if (v.getId() == R.id.close)
if(this.mRemovedListener != null)
this.mRemovedListener.onFeatureRemoved(this);
if (mRemovedListener != null)
mRemovedListener.onFeatureRemoved(this);
}
/**
* (non-Javadoc)
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
*
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
* android.view.ViewGroup, android.os.Bundle)
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(mLayout, container, false);
mIcon = (ImageView) view.findViewById(R.id.icon);
view.findViewById(R.id.close).setOnClickListener(this);
if(this.mIconRes != -1)
setIcon(this.mIconRes);
if (mIconRes != -1)
setIcon(mIconRes);
return view;
}
/**
* Sets the icon of this feature fragment
*
* @param icon
* @author ricky barrette
*/
public void setIcon(int icon){
mIcon.setImageDrawable(this.getActivity().getResources().getDrawable(icon));
public void setIcon(final int icon) {
mIcon.setImageDrawable(getActivity().getResources().getDrawable(icon));
}
}

View File

@@ -22,6 +22,7 @@ import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This fragment will be used to display a list of fragments
*
* @author ricky barrette
*/
public abstract class BaseFragmentListFragment extends Fragment {
@@ -33,9 +34,10 @@ public abstract class BaseFragmentListFragment extends Fragment {
/**
* Creates a new Populated BaseFragmentListFragment
*
* @author ricky barrette
*/
public BaseFragmentListFragment(ArrayList<Fragment> fragments, int layout, int container) {
public BaseFragmentListFragment(final ArrayList<Fragment> fragments, final int layout, final int container) {
super();
mFragments = fragments;
mLayout = layout;
@@ -44,11 +46,12 @@ public abstract class BaseFragmentListFragment extends Fragment {
/**
* Creates a new Empty Base Fragment List
*
* @param layout
* @param container
* @author ricky barrette
*/
public BaseFragmentListFragment(int layout, int container) {
public BaseFragmentListFragment(final int layout, final int container) {
mLayout = layout;
mContainer = container;
mFragments = new ArrayList<Fragment>();
@@ -56,58 +59,64 @@ public abstract class BaseFragmentListFragment extends Fragment {
/**
* Adds the fragment to the list
*
* @param fragment
* @author ricky barrette
*/
public void add(final Fragment fragment) {
this.mFragments.add(fragment);
final FragmentTransaction transaction = this.getFragmentManager().beginTransaction();
mFragments.add(fragment);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(mContainer, fragment, fragment.getTag());
transaction.commit();
}
/**
* Adds a collection ofs fragments to the list
*
* @param fragments
* @author ricky barrette
*/
public void addAll(final ArrayList<Fragment> fragments) {
final FragmentTransaction transaction = this.getFragmentManager().beginTransaction();
for(Fragment f : fragments){
this.mFragments.add(f);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
for (final Fragment f : fragments) {
mFragments.add(f);
transaction.add(mContainer, f, f.getTag());
}
transaction.commit();
}
/**
* Adds a collection ofs fragments to the list, but doesn't preform any transactions
* Adds a collection ofs fragments to the list, but doesn't preform any
* transactions
*
* @param fragment
* @author ricky barrette
*/
protected void addAllInit(final ArrayList<Fragment> fragments) {
for(Fragment f : fragments){
this.mFragments.add(f);
}
for (final Fragment f : fragments)
mFragments.add(f);
}
/**
* Loads all the fragments
*
* @author ricky barrette
*/
private void loadFragments() {
final FragmentTransaction transaction = this.getFragmentManager().beginTransaction();
for(Fragment fragment : this.mFragments)
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
for (final Fragment fragment : mFragments)
transaction.add(mContainer, fragment, fragment.getTag());
transaction.commit();
}
/**
* (non-Javadoc)
* @see android.support.v4.app.Fragment#onActivityResult(int, int, android.content.Intent)
*
* @see android.support.v4.app.Fragment#onActivityResult(int, int,
* android.content.Intent)
*/
@Override
public void onActivityResult(int arg0, int arg1, Intent arg2) {
public void onActivityResult(final int arg0, final int arg1, final Intent arg2) {
removeFragments();
loadFragments();
super.onActivityResult(arg0, arg1, arg2);
@@ -115,32 +124,35 @@ public abstract class BaseFragmentListFragment extends Fragment {
/**
* (non-Javadoc)
*
* @see android.support.v4.app.ListFragment#onCreateView(android.view.LayoutInflater,
* android.view.ViewGroup, android.os.Bundle)
*/
@Override
public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle bundle) {
public View onCreateView(final LayoutInflater inflator, final ViewGroup container, final Bundle bundle) {
return inflator.inflate(mLayout, null);
}
/**
* (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onPause()
*/
@Override
public void onPause() {
try {
removeFragments();
} catch(IllegalStateException e){
} catch (final IllegalStateException e) {
e.printStackTrace();
// do nothing
}
Collections.reverse(this.mFragments);
Collections.reverse(mFragments);
super.onPause();
}
/**
* (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onResume()
*/
@Override
@@ -153,26 +165,27 @@ public abstract class BaseFragmentListFragment extends Fragment {
/**
* Removes a fragment from the list
*
* @param fragment
* @author ricky barrette
*/
public void remove(final Fragment fragment) {
this.mFragments.remove(fragment);
final FragmentTransaction transaction = this.getFragmentManager().beginTransaction();
mFragments.remove(fragment);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
/**
* Removes all fragments from the the view
*
* @throws IllegalStateException
* @author ricky barrette
*/
private void removeFragments() throws IllegalStateException {
final FragmentTransaction transaction = this.getFragmentManager().beginTransaction();
for(Fragment fragment : this.mFragments){
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
for (final Fragment fragment : mFragments)
transaction.remove(fragment);
}
transaction.commit();
}
}

View File

@@ -30,6 +30,7 @@ import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
/**
* This fragment will be used to display a list of features
*
* @author ricky
*/
@SuppressLint("ValidFragment")
@@ -45,14 +46,26 @@ public class FeatureListFragment extends BaseFragmentListFragment implements OnC
private final OnContentChangedListener mListener;
private final ArrayList<Integer> mAdded;
/**
* Creates a new empty feature list fragment
*
* @param info
* @param listener
* @author ricky barrette
*/
public FeatureListFragment(final ContentValues info, final OnContentChangedListener listener) {
this(info, listener, new ArrayList<Fragment>(), new ArrayList<Integer>());
}
/**
* Creates a new populated FeatureListFragment
*
* @param info
* @param listener
* @param fragments
* @author ricky barrette
*/
public FeatureListFragment(ContentValues info, OnContentChangedListener listener, ArrayList<Fragment> fragments, ArrayList<Integer> added) {
public FeatureListFragment(final ContentValues info, final OnContentChangedListener listener, final ArrayList<Fragment> fragments, final ArrayList<Integer> added) {
super(R.layout.fragment_list_contianer, R.id.fragment_list_contianer);
if (info == null)
@@ -69,47 +82,38 @@ public class FeatureListFragment extends BaseFragmentListFragment implements OnC
mAdded = added;
}
/**
* Creates a new empty feature list fragment
* @param info
* @param listener
* @author ricky barrette
*/
public FeatureListFragment(ContentValues info, OnContentChangedListener listener){
this(info, listener, new ArrayList<Fragment>(), new ArrayList<Integer>());
}
/**
* Initializes a feature fragment
*
* @param fragmentCode
* @return
* @author ricky barrette
*/
public Fragment initFeatureFragment(int fragmentCode){
public Fragment initFeatureFragment(final int fragmentCode) {
Fragment f = null;
switch (fragmentCode) {
case KEY_ADDED_RINGTONE:
f= new RingtoneFragment(this.mInfo, this.mListener, this, AudioManager.STREAM_RING, KEY_ADDED_RINGTONE);
f = new RingtoneFragment(mInfo, mListener, this, AudioManager.STREAM_RING, KEY_ADDED_RINGTONE);
mAdded.add(KEY_ADDED_RINGTONE);
break;
case KEY_ADDED_NOTIFICATIONTONE:
f = new RingtoneFragment(this.mInfo, this.mListener, this, AudioManager.STREAM_NOTIFICATION, KEY_ADDED_NOTIFICATIONTONE);
f = new RingtoneFragment(mInfo, mListener, this, AudioManager.STREAM_NOTIFICATION, KEY_ADDED_NOTIFICATIONTONE);
mAdded.add(KEY_ADDED_NOTIFICATIONTONE);
break;
case KEY_ADDED_ALARM_VOLUME:
f = new VolumeFragment(this.mInfo, this.getActivity(), this.mListener, this, AudioManager.STREAM_ALARM, KEY_ADDED_ALARM_VOLUME);
f = new VolumeFragment(mInfo, getActivity(), mListener, this, AudioManager.STREAM_ALARM, KEY_ADDED_ALARM_VOLUME);
mAdded.add(KEY_ADDED_ALARM_VOLUME);
break;
case KEY_ADDED_MUSIC_VOLUME:
f = new VolumeFragment(this.mInfo, this.getActivity(), this.mListener, this, AudioManager.STREAM_MUSIC, KEY_ADDED_MUSIC_VOLUME);
f = new VolumeFragment(mInfo, getActivity(), mListener, this, AudioManager.STREAM_MUSIC, KEY_ADDED_MUSIC_VOLUME);
mAdded.add(KEY_ADDED_MUSIC_VOLUME);
break;
case KEY_ADDED_BT:
f = new ToggleButtonFragment(R.drawable.ic_action_bluetooth, this.getString(R.string.bluetooth), RingerDatabase.KEY_BT, this.mInfo, this.mListener, this, KEY_ADDED_BT);
f = new ToggleButtonFragment(R.drawable.ic_action_bluetooth, this.getString(R.string.bluetooth), RingerDatabase.KEY_BT, mInfo, mListener, this, KEY_ADDED_BT);
mAdded.add(KEY_ADDED_BT);
break;
case KEY_ADDED_WIFI:
f = new ToggleButtonFragment(R.drawable.ic_action_wifi, this.getString(R.string.wifi), RingerDatabase.KEY_WIFI, this.mInfo, this.mListener, this, KEY_ADDED_WIFI);
f = new ToggleButtonFragment(R.drawable.ic_action_wifi, this.getString(R.string.wifi), RingerDatabase.KEY_WIFI, mInfo, mListener, this, KEY_ADDED_WIFI);
mAdded.add(KEY_ADDED_WIFI);
break;
@@ -119,64 +123,59 @@ public class FeatureListFragment extends BaseFragmentListFragment implements OnC
/**
* Initializes feature fragments based upon current records
*
* @author ricky barrette
*/
private ArrayList<Fragment> initList() {
ArrayList<Fragment> what = new ArrayList<Fragment>();
final ArrayList<Fragment> what = new ArrayList<Fragment>();
if(this.mInfo.containsKey(RingerDatabase.KEY_RINGTONE_VOLUME)){
if (mInfo.containsKey(RingerDatabase.KEY_RINGTONE_VOLUME))
what.add(initFeatureFragment(KEY_ADDED_RINGTONE));
}
if(this.mInfo.containsKey(RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME)){
if (mInfo.containsKey(RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME))
what.add(initFeatureFragment(KEY_ADDED_NOTIFICATIONTONE));
}
if(this.mInfo.containsKey(RingerDatabase.KEY_ALARM_VOLUME)){
if (mInfo.containsKey(RingerDatabase.KEY_ALARM_VOLUME))
what.add(initFeatureFragment(KEY_ADDED_ALARM_VOLUME));
}
if(this.mInfo.containsKey(RingerDatabase.KEY_MUSIC_VOLUME)){
if (mInfo.containsKey(RingerDatabase.KEY_MUSIC_VOLUME))
what.add(initFeatureFragment(KEY_ADDED_MUSIC_VOLUME));
}
if(this.mInfo.containsKey(RingerDatabase.KEY_BT)){
if (mInfo.containsKey(RingerDatabase.KEY_BT))
what.add(initFeatureFragment(KEY_ADDED_BT));
}
if(this.mInfo.containsKey(RingerDatabase.KEY_WIFI)){
if (mInfo.containsKey(RingerDatabase.KEY_WIFI))
what.add(initFeatureFragment(KEY_ADDED_WIFI));
}
return what;
}
/**
* Called when an item is picked from the add featue list
* (non-Javadoc)
* @see android.content.DialogInterface.OnClickListener#onClick(android.content.DialogInterface, int)
* Called when an item is picked from the add featue list (non-Javadoc)
*
* @see android.content.DialogInterface.OnClickListener#onClick(android.content.DialogInterface,
* int)
*/
@Override
public void onClick(DialogInterface dialog, int which) {
public void onClick(final DialogInterface dialog, final int which) {
final Fragment f = initFeatureFragment(which);
if (f != null)
add(f);
}
/**
* Called when the add feature button is clicked
* (non-Javadoc)
* Called when the add feature button is clicked (non-Javadoc)
*
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
new AlertDialog.Builder(this.getActivity())
.setTitle(R.string.add_feature)
.setAdapter(
new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_list_item_1, this.getResources().getStringArray(R.array.features)){
public void onClick(final View v) {
new AlertDialog.Builder(getActivity()).setTitle(R.string.add_feature)
.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.features)) {
/**
* we override this, because we want to filter which items are enabled
* (non-Javadoc)
* we override this, because we want to filter which items
* are enabled (non-Javadoc)
*
* @see android.widget.BaseAdapter#areAllItemsEnabled()
*/
@Override
@@ -187,10 +186,12 @@ public class FeatureListFragment extends BaseFragmentListFragment implements OnC
/**
* here we want to grey out disabled items in the list
* (non-Javadoc)
* @see android.widget.ArrayAdapter#getView(int, android.view.View, android.view.ViewGroup)
*
* @see android.widget.ArrayAdapter#getView(int,
* android.view.View, android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent){
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View v = super.getView(position, convertView, parent);
v.setEnabled(isEnabled(position));
@@ -203,75 +204,77 @@ public class FeatureListFragment extends BaseFragmentListFragment implements OnC
}
/**
* here we can notify the adaptor if an item should be enabled or not
* (non-Javadoc)
* here we can notify the adaptor if an item should be
* enabled or not (non-Javadoc)
*
* @see android.widget.BaseAdapter#isEnabled(int)
*/
@Override
public boolean isEnabled(int position){
public boolean isEnabled(final int position) {
return !mAdded.contains(position);
}
}, this)
.show();
}, this).show();
}
/**
* Called when the activity is first created
* (non-Javadoc)
* Called when the activity is first created (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle arg0) {
public void onCreate(final Bundle arg0) {
addAllInit(initList());
super.onCreate(arg0);
}
/**
* Called when the view needs to be created
* (non-Javadoc)
* @see com.TwentyCodes.android.LocationRinger.ui.fragments.BaseFragmentListFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
* Called when the view needs to be created (non-Javadoc)
*
* @see com.TwentyCodes.android.LocationRinger.ui.fragments.BaseFragmentListFragment#onCreateView(android.view.LayoutInflater,
* android.view.ViewGroup, android.os.Bundle)
*/
@Override
public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle bundle) {
public View onCreateView(final LayoutInflater inflator, final ViewGroup container, final Bundle bundle) {
final View v = super.onCreateView(inflator, container, bundle);
v.findViewById(R.id.add_feature_button).setOnClickListener(this);
return v;
}
/**
* Called when a fragment needs to be removed
* (non-Javadoc)
* Called when a fragment needs to be removed (non-Javadoc)
*
* @see com.TwentyCodes.android.LocationRinger.FeatureRemovedListener#onFeatureRemoved(android.support.v4.app.Fragment)
*/
@Override
public void onFeatureRemoved(Fragment f) {
this.remove(f);
public void onFeatureRemoved(final Fragment f) {
remove(f);
if (f instanceof BaseFeatureFragment) {
final int id = ((BaseFeatureFragment) f).getFragmentId();
mAdded.remove(Integer.valueOf(id));
/*
* we need to notify our parent activity that the feature have been removed.
* we need to notify our parent activity that the feature have been
* removed.
*/
switch (id) {
case KEY_ADDED_RINGTONE:
this.mListener.onInfoContentRemoved(RingerDatabase.KEY_RINGTONE_URI, RingerDatabase.KEY_RINGTONE_VOLUME);
mListener.onInfoContentRemoved(RingerDatabase.KEY_RINGTONE_URI, RingerDatabase.KEY_RINGTONE_VOLUME);
break;
case KEY_ADDED_NOTIFICATIONTONE:
this.mListener.onInfoContentRemoved(RingerDatabase.KEY_NOTIFICATION_RINGTONE_URI, RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME);
mListener.onInfoContentRemoved(RingerDatabase.KEY_NOTIFICATION_RINGTONE_URI, RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME);
break;
case KEY_ADDED_ALARM_VOLUME:
this.mListener.onInfoContentRemoved(RingerDatabase.KEY_ALARM_VOLUME);
mListener.onInfoContentRemoved(RingerDatabase.KEY_ALARM_VOLUME);
break;
case KEY_ADDED_MUSIC_VOLUME:
this.mListener.onInfoContentRemoved(RingerDatabase.KEY_MUSIC_VOLUME);
mListener.onInfoContentRemoved(RingerDatabase.KEY_MUSIC_VOLUME);
break;
case KEY_ADDED_BT:
this.mListener.onInfoContentRemoved(RingerDatabase.KEY_BT);
mListener.onInfoContentRemoved(RingerDatabase.KEY_BT);
break;
case KEY_ADDED_WIFI:
this.mListener.onInfoContentRemoved(RingerDatabase.KEY_WIFI);
mListener.onInfoContentRemoved(RingerDatabase.KEY_WIFI);
break;
}
}

View File

@@ -36,11 +36,14 @@ import com.TwentyCodes.android.overlays.RadiusOverlay;
import com.google.android.maps.GeoPoint;
/**
* This fragment will be used to display and allow the user to edit the ringers location trigger
* This fragment will be used to display and allow the user to edit the ringers
* location trigger
*
* @author ricky
*/
@SuppressLint("ValidFragment")
public class LocationInfomationFragment extends Fragment implements GeoPointLocationListener, OnClickListener, OnCheckedChangeListener, OnSeekBarChangeListener, OnLocationSelectedListener, SearchRequestedListener {
public class LocationInfomationFragment extends Fragment implements GeoPointLocationListener, OnClickListener, OnCheckedChangeListener, OnSeekBarChangeListener,
OnLocationSelectedListener, SearchRequestedListener {
private static final String TAG = "RingerInformationHowActivity";
private final ContentValues mInfo;
@@ -56,17 +59,19 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
/**
* Creates a new MapFragment
*
* @author ricky barrette
* @param ringerInformationActivity
*/
public LocationInfomationFragment(final ContentValues info, final OnContentChangedListener listener, final EnableScrollingListener enabledListener) {
this.mInfo = info;
this.mListener = listener;
this.mEnableScrollingListener = enabledListener;
mInfo = info;
mListener = listener;
mEnableScrollingListener = enabledListener;
}
/**
* Called when a toggle button's state is changed
*
* @author ricky barrette
*/
@Override
@@ -77,79 +82,77 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
mEnableScrollingListener.setScrollEnabled(!isChecked);
if (isChecked)
this.mSkyHook.getUpdates();
mSkyHook.getUpdates();
else
this.mSkyHook.removeUpdates();
mSkyHook.removeUpdates();
this.mMap.setDoubleTapZoonEnabled(isChecked);
mMap.setDoubleTapZoonEnabled(isChecked);
// buttons
this.mMap.setBuiltInZoomControls(isChecked);
this.mMap.setClickable(isChecked);
this.mRadius.setEnabled(isChecked);
Toast.makeText(this.getActivity(), isChecked ? getString(R.string.map_editing_enabled) : getString(R.string.map_editiing_disabled), Toast.LENGTH_SHORT).show();
mMap.setBuiltInZoomControls(isChecked);
mMap.setClickable(isChecked);
mRadius.setEnabled(isChecked);
Toast.makeText(getActivity(), isChecked ? getString(R.string.map_editing_enabled) : getString(R.string.map_editiing_disabled), Toast.LENGTH_SHORT).show();
}
/**
* Called when a view is clicked
*
* @author ricky barrette
*/
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.mark_my_location:
if(this.mPoint != null)
if (mPoint != null)
onLocationSelected(mPoint);
break;
case R.id.my_location:
if(this.mPoint != null)
this.mMap.setMapCenter(mPoint);
if (mPoint != null)
mMap.setMapCenter(mPoint);
break;
case R.id.map_mode:
this.mMap.setSatellite(mMap.isSatellite() ? false : true);
mMap.setSatellite(mMap.isSatellite() ? false : true);
break;
case R.id.search:
new SearchDialog(this.getActivity(), this).show();
new SearchDialog(getActivity(), this).show();
break;
}
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
view = inflater.inflate(R.layout.map_info_fragment, container, false);
this.mSkyHook = new SkyHook(this.getActivity());
this.mSkyHook.setLocationListener(this);
mSkyHook = new SkyHook(getActivity());
mSkyHook.setLocationListener(this);
this.mMap = (MapFragment) this.getFragmentManager().findFragmentById(R.id.mapview);
this.mRadius = (SeekBar) view.findViewById(R.id.radius);
this.mRadius.setMax(Debug.MAX_RADIUS_IN_METERS);
this.mMap.setClickable(false);
this.mMapEditToggle = (ToggleButton) view.findViewById(R.id.map_edit_toggle);
this.mMapEditToggle.setChecked(false);
this.mMapEditToggle.setOnCheckedChangeListener(this);
this.mRadiusOverlay = new RadiusOverlay();
this.mRadiusOverlay.setLocationSelectedListener(this);
this.mRadius.setOnSeekBarChangeListener(this);
this.mMap.addOverlay(mRadiusOverlay);
this.mRadius.setEnabled(false);
mMap = (MapFragment) getFragmentManager().findFragmentById(R.id.mapview);
mRadius = (SeekBar) view.findViewById(R.id.radius);
mRadius.setMax(Debug.MAX_RADIUS_IN_METERS);
mMap.setClickable(false);
mMapEditToggle = (ToggleButton) view.findViewById(R.id.map_edit_toggle);
mMapEditToggle.setChecked(false);
mMapEditToggle.setOnCheckedChangeListener(this);
mRadiusOverlay = new RadiusOverlay();
mRadiusOverlay.setLocationSelectedListener(this);
mRadius.setOnSeekBarChangeListener(this);
mMap.addOverlay(mRadiusOverlay);
mRadius.setEnabled(false);
if (this.mInfo.get(RingerDatabase.KEY_LOCATION) != null){
final String[] point = this.mInfo.getAsString(RingerDatabase.KEY_LOCATION).split(",");
this.mRadiusOverlay.setLocation(new GeoPoint(Integer.parseInt(point[0]), Integer.parseInt(point[1])));
if (mInfo.get(RingerDatabase.KEY_LOCATION) != null) {
final String[] point = mInfo.getAsString(RingerDatabase.KEY_LOCATION).split(",");
mRadiusOverlay.setLocation(new GeoPoint(Integer.parseInt(point[0]), Integer.parseInt(point[1])));
}
if (this.mInfo.get(RingerDatabase.KEY_RADIUS) != null){
this.mRadius.setProgress(this.mInfo.getAsInteger(RingerDatabase.KEY_RADIUS));
if (mInfo.get(RingerDatabase.KEY_RADIUS) != null)
mRadius.setProgress(mInfo.getAsInteger(RingerDatabase.KEY_RADIUS));
if (mRadiusOverlay.getLocation() != null) {
mMap.setMapCenter(mRadiusOverlay.getLocation());
mMap.setZoom(16);
}
if(this.mRadiusOverlay.getLocation() != null){
this.mMap.setMapCenter(this.mRadiusOverlay.getLocation());
this.mMap.setZoom(16);
}
this.mMap.setDoubleTapZoonEnabled(false);
mMap.setDoubleTapZoonEnabled(false);
view.findViewById(R.id.my_location).setOnClickListener(this);
view.findViewById(R.id.mark_my_location).setOnClickListener(this);
@@ -160,8 +163,8 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
}
/**
* Called when the location is a first fix
* (non-Javadoc)
* Called when the location is a first fix (non-Javadoc)
*
* @see com.TwentyCodes.android.location.GeoPointLocationListener#onFirstFix(boolean)
*/
@Override
@@ -171,34 +174,33 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
else
mMap.disableGPSProgess();
if(mPoint != null){
if (mPoint != null)
/*
* if this is the first fix and the radius overlay does not have a point specified
* then pan the map, and zoom in to the users current location
* if this is the first fix and the radius overlay does not have a
* point specified then pan the map, and zoom in to the users
* current location
*/
if (isFirstFix)
if(this.mRadiusOverlay.getLocation() == null){
if(this.mMap != null){
this.mMap.setMapCenter(mPoint);
this.mMap.setZoom((this.mMap.getMap().getMaxZoomLevel() - 5));
}
}
if (mRadiusOverlay.getLocation() == null)
if (mMap != null) {
mMap.setMapCenter(mPoint);
mMap.setZoom(mMap.getMap().getMaxZoomLevel() - 5);
}
}
/**
* Called when skyhook has a location to report
*
* @author ricky barrette
*/
@Override
public void onLocationChanged(final GeoPoint point, final int accuracy) {
this.mPoint = point;
mPoint = point;
}
/**
* Called when a location has been selected
* (non-Javadoc)
* Called when a location has been selected (non-Javadoc)
*
* @see com.TwentyCodes.android.location.OnLocationSelectedListener#onLocationSelected(com.google.android.maps.GeoPoint)
*/
@Override
@@ -207,16 +209,16 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
if (Debug.DEBUG)
Log.d(TAG, "onLocationSelected() " + point.toString());
if(this.mRadiusOverlay != null)
this.mRadiusOverlay.setLocation(point);
if (mRadiusOverlay != null)
mRadiusOverlay.setLocation(point);
if(this.mMap != null)
this.mMap.setMapCenter(point);
if (mMap != null)
mMap.setMapCenter(point);
if(this.mListener != null){
if (mListener != null) {
final ContentValues info = new ContentValues();
info.put(RingerDatabase.KEY_LOCATION, point.toString());
this.mListener.onInfoContentChanged(info);
mListener.onInfoContentChanged(info);
}
} else if (Debug.DEBUG)
Log.d(TAG, "onLocationSelected() Location was null");
@@ -224,6 +226,7 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
/**
* (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onPause()
*/
@Override
@@ -234,18 +237,19 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
/**
* Called when a seekbar is has its progress changed
*
* @author ricky barrette
*/
@Override
public void onProgressChanged(final SeekBar seekBar, final int progress, final boolean fromUser) {
switch (seekBar.getId()) {
case R.id.radius:
this.mRadiusOverlay.setRadius(progress);
this.mMap.invalidate();
if(this.mListener != null){
mRadiusOverlay.setRadius(progress);
mMap.invalidate();
if (mListener != null) {
final ContentValues info = new ContentValues();
info.put(RingerDatabase.KEY_RADIUS, progress);
this.mListener.onInfoContentChanged(info);
mListener.onInfoContentChanged(info);
}
break;
}
@@ -253,6 +257,7 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
/**
* (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onResume()
*/
@Override
@@ -264,11 +269,12 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
/**
* (non-Javadoc)
*
* @see com.TwentyCodes.android.LocationRinger.SearchRequestedListener#onSearchRequested()
*/
@Override
public boolean onSearchRequested() {
new SearchDialog(this.getActivity(), this).show();
new SearchDialog(getActivity(), this).show();
return true;
}
@@ -276,13 +282,16 @@ public class LocationInfomationFragment extends Fragment implements GeoPointLoca
public void onStartTrackingTouch(final SeekBar seekBar) {
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see com.google.android.maps.MapActivity#onDestroy()
*
* @author ricky barrette
*/
@Override
public void onStop() {
this.mSkyHook.removeUpdates();
mSkyHook.removeUpdates();
super.onDestroy();
}

View File

@@ -24,10 +24,11 @@ public class MapFragment extends BaseMapFragment {
/**
* (non-Javadoc)
*
* @see com.TwentyCodes.android.fragments.BaseMapFragment#onMapViewCreate(com.TwentyCodes.android.location.MapView)
*/
@Override
public void onMapViewCreate(MapView map) {
public void onMapViewCreate(final MapView map) {
// TODO Auto-generated method stub
}

View File

@@ -36,6 +36,7 @@ import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This fragment will be for ringtone settings
*
* @author ricky
*/
@SuppressLint("ValidFragment")
@@ -53,7 +54,8 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
private Uri mRingtoneURI;
private SeekBar mVolume;
public RingtoneFragment(ContentValues info, OnContentChangedListener changedListener, FeatureRemovedListener removedListener, int stream, int id){
public RingtoneFragment(final ContentValues info, final OnContentChangedListener changedListener, final FeatureRemovedListener removedListener, final int stream,
final int id) {
super(id, R.layout.ringtone_fragment, removedListener);
if (info == null)
@@ -61,9 +63,9 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
if (changedListener == null)
throw new NullPointerException();
this.mChangedListener = changedListener;
this.mStream = stream;
this.mInfo = info;
mChangedListener = changedListener;
mStream = stream;
mInfo = info;
switch (stream) {
case AudioManager.STREAM_NOTIFICATION:
@@ -85,8 +87,11 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
/**
* starts the ringtone picker
* @param ringtoneCode RingtoneManager.TYPE_?
* @param uri of current tone
*
* @param ringtoneCode
* RingtoneManager.TYPE_?
* @param uri
* of current tone
* @author ricky barrette
*/
private void getRingtoneURI(final int ringtoneCode, final Uri uri) {
@@ -100,29 +105,33 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
}
/**
* Notifys the listener that the ringtone has changedRingtoneManager.getActualDefaultRingtoneUri(this.getActivity(), mType)
* Notifys the listener that the ringtone has
* changedRingtoneManager.getActualDefaultRingtoneUri(this.getActivity(),
* mType)
*
* @param tone
* @author ricky barrette
*/
private void notifyRingtoneChanged(Uri tone) {
if(this.mChangedListener != null){
ContentValues info = new ContentValues();
info.put(this.mKeyUri, tone != null ? tone.toString() : null);
this.mChangedListener.onInfoContentChanged(info);
private void notifyRingtoneChanged(final Uri tone) {
if (mChangedListener != null) {
final ContentValues info = new ContentValues();
info.put(mKeyUri, tone != null ? tone.toString() : null);
mChangedListener.onInfoContentChanged(info);
}
}
/**
* Notifys the listener that the volume has changed
*
* @param progress
* @author ricky barrette
*/
private void notifyVolumeChanged(int progress) {
private void notifyVolumeChanged(final int progress) {
setIcon(progress == 0 ? R.drawable.ic_action_silent : R.drawable.ic_action_volume);
if(this.mChangedListener != null){
if (mChangedListener != null) {
final ContentValues info = new ContentValues();
info.put(this.mKeyVolume, progress);
this.mChangedListener.onInfoContentChanged(info);
info.put(mKeyVolume, progress);
mChangedListener.onInfoContentChanged(info);
}
}
@@ -130,18 +139,18 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
* Called when the ringtone picker activity returns it's result
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
if (resultCode == Activity.RESULT_OK) {
final Uri tone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (tone == null) {
this.mRingtone.setText(R.string.silent);
mRingtone.setText(R.string.silent);
mVolume.setEnabled(false);
mVolume.setProgress(0);
notifyVolumeChanged(0);
} else {
mVolume.setEnabled(true);
Ringtone ringtone = RingtoneManager.getRingtone(this.getActivity(), Uri.parse(tone.toString()));
this.mRingtone.setText(ringtone.getTitle(this.getActivity()));
final Ringtone ringtone = RingtoneManager.getRingtone(getActivity(), Uri.parse(tone.toString()));
mRingtone.setText(ringtone.getTitle(getActivity()));
}
notifyRingtoneChanged(tone);
@@ -151,13 +160,14 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
/**
* Called when a view is clicked
*
* @author ricky barrette
*/
@Override
public void onClick(View v) {
public void onClick(final View v) {
switch (v.getId()) {
case R.id.ringtone:
getRingtoneURI(this.mType, mRingtoneURI);
getRingtoneURI(mType, mRingtoneURI);
break;
default:
super.onClick(v);
@@ -166,12 +176,12 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
final AudioManager audioManager = (AudioManager) this.getActivity().getSystemService(Context.AUDIO_SERVICE);
final AudioManager audioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
if (Debug.DEBUG)
for(Entry<String,Object> item : this.mInfo.valueSet())
for (final Entry<String, Object> item : mInfo.valueSet())
Log.d(TAG, item.getKey() + " = " + item.getValue());
/*
@@ -182,10 +192,10 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
setIcon(R.drawable.ic_action_volume);
this.mRingtone = (EditText) view.findViewById(R.id.ringtone);
mRingtone = (EditText) view.findViewById(R.id.ringtone);
mVolume = (SeekBar) view.findViewById(R.id.ringtone_volume);
this.mRingtone.setOnClickListener(this);
mRingtone.setOnClickListener(this);
mVolume.setMax(audioManager.getStreamMaxVolume(mStream));
view.findViewById(R.id.close).setOnClickListener(this);
@@ -193,8 +203,8 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
/*
* volume
*/
if(this.mInfo.containsKey(this.mKeyVolume))
mVolume.setProgress(Integer.parseInt(this.mInfo.getAsString(this.mKeyVolume)));
if (mInfo.containsKey(mKeyVolume))
mVolume.setProgress(Integer.parseInt(mInfo.getAsString(mKeyVolume)));
else {
mVolume.setProgress(audioManager.getStreamVolume(mStream));
notifyVolumeChanged(audioManager.getStreamVolume(mStream));
@@ -203,21 +213,21 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
/*
* ringtone & uri
*/
if(this.mInfo.containsKey(this.mKeyUri)){
if (mInfo.containsKey(mKeyUri)) {
try {
this.mRingtoneURI = Uri.parse(this.mInfo.getAsString(this.mKeyUri));
} catch (NullPointerException e){
this.mRingtoneURI = null;
mRingtoneURI = Uri.parse(mInfo.getAsString(mKeyUri));
} catch (final NullPointerException e) {
mRingtoneURI = null;
}
this.mVolume.setEnabled(this.mInfo.getAsString(this.mKeyUri) != null);
mVolume.setEnabled(mInfo.getAsString(mKeyUri) != null);
} else {
this.mRingtoneURI = RingtoneManager.getActualDefaultRingtoneUri(this.getActivity(), mType);
notifyRingtoneChanged(this.mRingtoneURI);
mRingtoneURI = RingtoneManager.getActualDefaultRingtoneUri(getActivity(), mType);
notifyRingtoneChanged(mRingtoneURI);
}
try {
this.mRingtone.setText(RingtoneManager.getRingtone(this.getActivity(), mRingtoneURI).getTitle(this.getActivity()));
} catch (NullPointerException e) {
mRingtone.setText(RingtoneManager.getRingtone(getActivity(), mRingtoneURI).getTitle(getActivity()));
} catch (final NullPointerException e) {
mVolume.setEnabled(false);
mRingtone.setText(R.string.silent);
mVolume.setProgress(0);
@@ -230,17 +240,17 @@ public class RingtoneFragment extends BaseFeatureFragment implements OnClickList
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
public void onProgressChanged(final SeekBar seekBar, final int progress, final boolean fromUser) {
if (fromUser)
notifyVolumeChanged(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
public void onStartTrackingTouch(final SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
public void onStopTrackingTouch(final SeekBar seekBar) {
}
}

View File

@@ -24,6 +24,7 @@ import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
/**
* A simple fragment that displays a toggle button and a title label
*
* @author ricky
*/
@SuppressLint("ValidFragment")
@@ -36,9 +37,11 @@ public class ToggleButtonFragment extends BaseFeatureFragment implements OnCheck
/**
* Creates a new ToggleButtonFtagment
*
* @author ricky barrette
*/
public ToggleButtonFragment(int icon, String title, String key, ContentValues info, OnContentChangedListener changedListener, FeatureRemovedListener removedListener, int id) {
public ToggleButtonFragment(final int icon, final String title, final String key, final ContentValues info, final OnContentChangedListener changedListener,
final FeatureRemovedListener removedListener, final int id) {
super(id, R.layout.toggle_button_fragment, icon, removedListener);
if (info == null)
@@ -50,41 +53,43 @@ public class ToggleButtonFragment extends BaseFeatureFragment implements OnCheck
if (changedListener == null)
throw new NullPointerException();
this.mTitle = title;
this.mKey = key;
this.mInfo = info;
this.mChangedListener = changedListener;
mTitle = title;
mKey = key;
mInfo = info;
mChangedListener = changedListener;
}
/**
* Called when the fragment's view needs to be created
* (non-Javadoc)
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
* Called when the toggle button is clicked (non-Javadoc)
*
* @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton,
* boolean)
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
if (mChangedListener != null) {
final ContentValues info = new ContentValues();
info.put(mKey, isChecked);
mChangedListener.onInfoContentChanged(info);
}
}
/**
* Called when the fragment's view needs to be created (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
* android.view.ViewGroup, android.os.Bundle)
*/
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
final TextView t = (TextView) view.findViewById(R.id.title);
t.setText(this.mTitle);
t.setText(mTitle);
final ToggleButton b = (ToggleButton) view.findViewById(R.id.toggle);
if(this.mInfo.containsKey(this.mKey))
b.setChecked(RingerDatabase.parseBoolean(this.mInfo.getAsString(this.mKey)));
if (mInfo.containsKey(mKey))
b.setChecked(RingerDatabase.parseBoolean(mInfo.getAsString(mKey)));
b.setOnCheckedChangeListener(this);
return view;
}
/**
* Called when the toggle button is clicked
* (non-Javadoc)
* @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean)
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(this.mChangedListener != null){
ContentValues info = new ContentValues();
info.put(this.mKey, isChecked);
this.mChangedListener.onInfoContentChanged(info);
}
}
}

View File

@@ -29,6 +29,7 @@ import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This fragment will represent the volume fragments
*
* @author ricky
*/
@SuppressLint("ValidFragment")
@@ -44,13 +45,15 @@ public class VolumeFragment extends BaseFeatureFragment implements OnSeekBarChan
/**
* Creates a new Volume Fragment
*
* @param info
* @param context
* @param changedListener
* @param stream
* @author ricky barrette
*/
public VolumeFragment(ContentValues info, Context context, OnContentChangedListener changedListener, FeatureRemovedListener removedListener, int stream, int id){
public VolumeFragment(final ContentValues info, final Context context, final OnContentChangedListener changedListener, final FeatureRemovedListener removedListener,
final int stream, final int id) {
super(id, R.layout.volume_fragment, removedListener);
if (info == null)
@@ -60,103 +63,105 @@ public class VolumeFragment extends BaseFeatureFragment implements OnSeekBarChan
if (changedListener == null)
throw new NullPointerException();
this.mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
this.mStream = stream;
this.mChangedListener = changedListener;
this.mInfo = info;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mStream = stream;
mChangedListener = changedListener;
mInfo = info;
switch(this.mStream){
switch (mStream) {
case AudioManager.STREAM_ALARM:
this.mLabel = R.string.alarm_volume;
this.mKey = RingerDatabase.KEY_ALARM_VOLUME;
mLabel = R.string.alarm_volume;
mKey = RingerDatabase.KEY_ALARM_VOLUME;
break;
case AudioManager.STREAM_DTMF:
this.mLabel = R.string.dtmf_volume;
this.mKey = RingerDatabase.KEY_DTMF_VOLUME;
mLabel = R.string.dtmf_volume;
mKey = RingerDatabase.KEY_DTMF_VOLUME;
break;
case AudioManager.STREAM_MUSIC:
this.mLabel = R.string.music_volume;
this.mKey = RingerDatabase.KEY_MUSIC_VOLUME;
mLabel = R.string.music_volume;
mKey = RingerDatabase.KEY_MUSIC_VOLUME;
break;
case AudioManager.STREAM_NOTIFICATION:
this.mLabel = R.string.notification_volume;
this.mKey = RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME;
mLabel = R.string.notification_volume;
mKey = RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME;
break;
case AudioManager.STREAM_RING:
this.mLabel = R.string.ringtone_volume;
this.mKey = RingerDatabase.KEY_RINGTONE_VOLUME;
mLabel = R.string.ringtone_volume;
mKey = RingerDatabase.KEY_RINGTONE_VOLUME;
break;
case AudioManager.STREAM_SYSTEM:
this.mLabel = R.string.system_volume;
this.mKey = RingerDatabase.KEY_SYSTEM_VOLUME;
mLabel = R.string.system_volume;
mKey = RingerDatabase.KEY_SYSTEM_VOLUME;
break;
case AudioManager.STREAM_VOICE_CALL:
this.mLabel = R.string.call_volume;
this.mKey = RingerDatabase.KEY_CALL_VOLUME;
mLabel = R.string.call_volume;
mKey = RingerDatabase.KEY_CALL_VOLUME;
break;
default:
this.mLabel = R.string.volume;
this.mKey = RingerDatabase.KEY_RINGTONE_VOLUME;
mLabel = R.string.volume;
mKey = RingerDatabase.KEY_RINGTONE_VOLUME;
break;
}
}
/**
* Called when the fragment's view needs to be created
* (non-Javadoc)
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
* Notifys the listener of changes made to the volume
*
* @param progress
* @author ricky barrette
*/
private void notifyListener(final int progress) {
if (mChangedListener != null) {
final ContentValues info = new ContentValues();
info.put(mKey, progress);
mChangedListener.onInfoContentChanged(info);
}
}
/**
* Called when the fragment's view needs to be created (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
* android.view.ViewGroup, android.os.Bundle)
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
if (Debug.DEBUG)
for(Entry<String,Object> item : this.mInfo.valueSet())
for (final Entry<String, Object> item : mInfo.valueSet())
Log.d(TAG, item.getKey() + " = " + item.getValue());
final View view = super.onCreateView(inflater, container, savedInstanceState);
final TextView label = (TextView) view.findViewById(R.id.title);
final SeekBar volume = (SeekBar) view.findViewById(R.id.volume);
volume.setMax(this.mAudioManager.getStreamMaxVolume(mStream));
volume.setProgress(this.mAudioManager.getStreamVolume(mStream));
volume.setMax(mAudioManager.getStreamMaxVolume(mStream));
volume.setProgress(mAudioManager.getStreamVolume(mStream));
volume.setOnSeekBarChangeListener(this);
label.setText(mLabel);
if(this.mInfo.containsKey(this.mKey))
volume.setProgress(Integer.parseInt(this.mInfo.getAsString(this.mKey)));
if (mInfo.containsKey(mKey))
volume.setProgress(Integer.parseInt(mInfo.getAsString(mKey)));
else
notifyListener(this.mAudioManager.getStreamVolume(mStream));
notifyListener(mAudioManager.getStreamVolume(mStream));
setIcon(volume.getProgress() == 0 ? R.drawable.ic_action_silent : R.drawable.ic_action_volume);
return view;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
public void onProgressChanged(final SeekBar seekBar, final int progress, final boolean fromUser) {
if (fromUser) {
notifyListener(progress);
setIcon(progress == 0 ? R.drawable.ic_action_silent : R.drawable.ic_action_volume);
}
}
/**
* Notifys the listener of changes made to the volume
* @param progress
* @author ricky barrette
*/
private void notifyListener(final int progress) {
if(this.mChangedListener != null){
final ContentValues info = new ContentValues();
info.put(this.mKey, progress);
this.mChangedListener.onInfoContentChanged(info);
}
@Override
public void onStartTrackingTouch(final SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
public void onStopTrackingTouch(final SeekBar seekBar) {
}
}

View File

@@ -14,32 +14,34 @@ import android.support.v4.app.FragmentPagerAdapter;
/**
* This adaptor maintains the How and What fragments
*
* @author ricky
*/
class FragmentAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> mFragments;
private final ArrayList<Fragment> mFragments;
/**
* Creates a new FragmentAdaptor
*
* @param fm
* @param fragments to be displayed
* @param fragments
* to be displayed
* @author ricky barrette
*/
public FragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
public FragmentAdapter(final FragmentManager fm, final ArrayList<Fragment> fragments) {
super(fm);
this.mFragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.mFragments.get(position);
mFragments = fragments;
}
@Override
public int getCount() {
return this.mFragments.size();
return mFragments.size();
}
@Override
public Fragment getItem(final int position) {
return mFragments.get(position);
}
}

View File

@@ -24,6 +24,27 @@ import android.support.v4.view.ViewPager;
* number and the current visible view.
*/
public interface PageIndicator extends ViewPager.OnPageChangeListener {
/**
* <p>
* Set the current page of both the ViewPager and indicator.
* </p>
*
* <p>
* This <strong>must</strong> be used if you need to set the page before the
* views are drawn on screen (e.g., default start page).
* </p>
*
* @param item
*/
public void setCurrentItem(int item);
/**
* Set a page change listener which will receive forwarded events.
*
* @param listener
*/
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
/**
* Bind the indicator to a ViewPager.
*
@@ -38,21 +59,4 @@ public interface PageIndicator extends ViewPager.OnPageChangeListener {
* @param initialPosition
*/
public void setViewPager(ViewPager view, int initialPosition);
/**
* <p>Set the current page of both the ViewPager and indicator.</p>
*
* <p>This <strong>must</strong> be used if you need to set the page before
* the views are drawn on screen (e.g., default start page).</p>
*
* @param item
*/
public void setCurrentItem(int item);
/**
* Set a page change listener which will receive forwarded events.
*
* @param listener
*/
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
}

View File

@@ -39,31 +39,59 @@ import com.TwentyCodes.android.LocationRinger.R;
/**
* A TitlePageIndicator is a PageIndicator which displays the title of left view
* (if exist), the title of the current select view (centered) and the title of
* the right view (if exist). When the user scrolls the ViewPager then titles are
* also scrolled.
* the right view (if exist). When the user scrolls the ViewPager then titles
* are also scrolled.
*/
public class TitlePageIndicator extends TextView implements PageIndicator, View.OnTouchListener {
private static final float UNDERLINE_FADE_PERCENTAGE = 0.25f;
public enum IndicatorStyle {
None(0), Triangle(1), Underline(2);
public final int value;
private IndicatorStyle(int value) {
this.value = value;
}
public static IndicatorStyle fromValue(int value) {
for (IndicatorStyle style : IndicatorStyle.values()) {
if (style.value == value) {
public static IndicatorStyle fromValue(final int value) {
for (final IndicatorStyle style : IndicatorStyle.values())
if (style.value == value)
return style;
}
}
return null;
}
public final int value;
private IndicatorStyle(final int value) {
this.value = value;
}
}
static class SavedState extends BaseSavedState {
int currentPage;
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(final Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(final int size) {
return new SavedState[size];
}
};
private SavedState(final Parcel in) {
super(in);
currentPage = in.readInt();
}
public SavedState(final Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
}
private static final float UNDERLINE_FADE_PERCENTAGE = 0.25f;
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private TitleProvider mTitleProvider;
@@ -76,23 +104,23 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
private IndicatorStyle mFooterIndicatorStyle;
private final Paint mPaintFooterIndicator;
private float mFooterIndicatorHeight;
private float mFooterIndicatorPadding;
private float mFooterIndicatorUnderlinePadding;
private final float mFooterIndicatorPadding;
private final float mFooterIndicatorUnderlinePadding;
private float mTitlePadding;
/** Left and right side padding for not active view titles. */
private float mClipPadding;
private float mFooterLineHeight;
public TitlePageIndicator(Context context) {
public TitlePageIndicator(final Context context) {
this(context, null);
}
public TitlePageIndicator(Context context, AttributeSet attrs) {
public TitlePageIndicator(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.titlePageIndicatorStyle);
}
public TitlePageIndicator(Context context, AttributeSet attrs, int defStyle) {
public TitlePageIndicator(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
super.setOnTouchListener(this);
mPath = new Path();
@@ -113,7 +141,7 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
final float defaultClipPadding = res.getDimension(R.dimen.default_title_indicator_clip_padding);
// Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitlePageIndicator, defStyle, R.style.Widget_TitlePageIndicator);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitlePageIndicator, defStyle, R.style.Widget_TitlePageIndicator);
// Retrieve the colors to be used for this view and apply them.
mFooterLineHeight = a.getDimension(R.styleable.TitlePageIndicator_footerLineHeight, defaultFooterLineHeight);
@@ -146,95 +174,157 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
a.recycle();
}
/**
* Calculate the bounds for a view's title
*
* @param index
* @param paint
* @return
*/
private Rect calcBounds(final int index, final Paint paint) {
// Calculate the text bounds
final Rect bounds = new Rect();
bounds.right = (int) paint.measureText(mTitleProvider.getTitle(index));
bounds.bottom = (int) (paint.descent() - paint.ascent());
return bounds;
}
/**
* Calculate views bounds and scroll them according to the current index
*
* @param paint
* @param currentIndex
* @return
*/
private ArrayList<Rect> calculateAllBounds(final Paint paint) {
final ArrayList<Rect> list = new ArrayList<Rect>();
// For each views (If no values then add a fake one)
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final int halfWidth = width / 2;
for (int i = 0; i < count; i++) {
final Rect bounds = calcBounds(i, paint);
final int w = bounds.right - bounds.left;
final int h = bounds.bottom - bounds.top;
bounds.left = halfWidth - w / 2 - mCurrentOffset + (i - mCurrentPage) * width;
bounds.right = bounds.left + w;
bounds.top = 0;
bounds.bottom = h;
list.add(bounds);
}
return list;
}
/**
* Set bounds for the left textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheLeft(final Rect curViewBound, final int curViewWidth) {
curViewBound.left = 0 + (int) mClipPadding;
curViewBound.right = curViewWidth;
}
/**
* Set bounds for the right textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheRight(final Rect curViewBound, final int curViewWidth, final int leftPlusWidth) {
curViewBound.right = leftPlusWidth - (int) mClipPadding;
curViewBound.left = curViewBound.right - curViewWidth;
}
public float getClipPadding() {
return mClipPadding;
}
public int getFooterColor() {
return mPaintFooterLine.getColor();
}
public void setFooterColor(int footerColor) {
mPaintFooterLine.setColor(footerColor);
invalidate();
}
public float getFooterLineHeight() {
return mFooterLineHeight;
}
public void setFooterLineHeight(float footerLineHeight) {
mFooterLineHeight = footerLineHeight;
invalidate();
}
public float getFooterIndicatorHeight() {
return mFooterIndicatorHeight;
}
public void setFooterIndicatorHeight(float footerTriangleHeight) {
mFooterIndicatorHeight = footerTriangleHeight;
invalidate();
}
public IndicatorStyle getFooterIndicatorStyle() {
return mFooterIndicatorStyle;
}
public void setFooterIndicatorStyle(IndicatorStyle indicatorStyle) {
mFooterIndicatorStyle = indicatorStyle;
invalidate();
public float getFooterLineHeight() {
return mFooterLineHeight;
}
public int getSelectedColor() {
return mPaintSelected.getColor();
}
public void setSelectedColor(int selectedColor) {
mPaintSelected.setColor(selectedColor);
invalidate();
public int getTextColor() {
return mPaintText.getColor();
}
@Override
public float getTextSize() {
return mPaintText.getTextSize();
}
public float getTitlePadding() {
return mTitlePadding;
}
public boolean isSelectedBold() {
return mPaintSelected.isFakeBoldText();
}
public void setSelectedBold(boolean selectedBold) {
mPaintSelected.setFakeBoldText(selectedBold);
invalidate();
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(final int measureSpec) {
float result = 0;
final int specMode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY)
// We were told how big to be
result = specSize;
else {
// Calculate the text bounds
final Rect bounds = new Rect();
bounds.bottom = (int) (mPaintText.descent() - mPaintText.ascent());
result = bounds.bottom - bounds.top + mFooterLineHeight;
if (mFooterIndicatorStyle != IndicatorStyle.None)
result += mFooterIndicatorHeight + mFooterIndicatorPadding;
}
return (int) result;
}
public int getTextColor() {
return mPaintText.getColor();
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureWidth(final int measureSpec) {
int result = 0;
final int specMode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec);
public void setTextColor(int textColor) {
mPaintText.setColor(textColor);
invalidate();
}
public float getTextSize() {
return mPaintText.getTextSize();
}
public void setTextSize(float textSize) {
mPaintText.setTextSize(textSize);
invalidate();
}
public float getTitlePadding() {
return this.mTitlePadding;
}
public void setTitlePadding(float titlePadding) {
mTitlePadding = titlePadding;
invalidate();
}
public float getClipPadding() {
return this.mClipPadding;
}
public void setClipPadding(float clipPadding) {
mClipPadding = clipPadding;
invalidate();
if (specMode != MeasureSpec.EXACTLY)
throw new IllegalStateException(getClass().getSimpleName() + " can only be used in EXACTLY mode.");
result = specSize;
return result;
}
/*
@@ -243,11 +333,11 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
* @see android.view.View#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
// Calculate views bounds
ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
final ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
final int count = mViewPager.getAdapter().getCount();
final int countMinusOne = count - 1;
@@ -258,70 +348,63 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
final int leftPlusWidth = left + width;
// Verify if the current view must be clipped to the screen
Rect curViewBound = bounds.get(mCurrentPage);
int curViewWidth = curViewBound.right - curViewBound.left;
if (curViewBound.left < 0) {
final Rect curViewBound = bounds.get(mCurrentPage);
final int curViewWidth = curViewBound.right - curViewBound.left;
if (curViewBound.left < 0)
// Try to clip to the screen (left side)
clipViewOnTheLeft(curViewBound, curViewWidth);
}
if (curViewBound.right > leftPlusWidth) {
if (curViewBound.right > leftPlusWidth)
// Try to clip to the screen (right side)
clipViewOnTheRight(curViewBound, curViewWidth, leftPlusWidth);
}
// Left views starting from the current position
if (mCurrentPage > 0) {
if (mCurrentPage > 0)
for (int i = mCurrentPage - 1; i >= 0; i--) {
Rect bound = bounds.get(i);
int w = bound.right - bound.left;
final Rect bound = bounds.get(i);
final int w = bound.right - bound.left;
// Is left side is outside the screen
if (bound.left < 0) {
// Try to clip to the screen (left side)
clipViewOnTheLeft(bound, w);
// Except if there's an intersection with the right view
if (i < countMinusOne && mCurrentPage != i) {
Rect rightBound = bounds.get(i + 1);
final Rect rightBound = bounds.get(i + 1);
// Intersection
if (bound.right + (int)mTitlePadding > rightBound.left) {
if (bound.right + (int) mTitlePadding > rightBound.left)
bound.left = rightBound.left - (w + (int) mTitlePadding);
}
}
}
}
}
// Right views starting from the current position
if (mCurrentPage < countMinusOne) {
if (mCurrentPage < countMinusOne)
for (int i = mCurrentPage + 1; i < count; i++) {
Rect bound = bounds.get(i);
int w = bound.right - bound.left;
final Rect bound = bounds.get(i);
final int w = bound.right - bound.left;
// If right side is outside the screen
if (bound.right > leftPlusWidth) {
// Try to clip to the screen (right side)
clipViewOnTheRight(bound, w, leftPlusWidth);
// Except if there's an intersection with the left view
if (i > 0 && mCurrentPage != i) {
Rect leftBound = bounds.get(i - 1);
final Rect leftBound = bounds.get(i - 1);
// Intersection
if (bound.left - (int)mTitlePadding < leftBound.right) {
if (bound.left - (int) mTitlePadding < leftBound.right)
bound.left = leftBound.right + (int) mTitlePadding;
}
}
}
}
}
// Now draw views
for (int i = 0; i < count; i++) {
// Get the title
Rect bound = bounds.get(i);
final Rect bound = bounds.get(i);
// Only if one side is visible
if ((bound.left > left && bound.left < leftPlusWidth) || (bound.right > left && bound.right < leftPlusWidth)) {
if (bound.left > left && bound.left < leftPlusWidth || bound.right > left && bound.right < leftPlusWidth) {
Paint paint = mPaintText;
// Change the color is the title is closed to the center
int middle = (bound.left + bound.right) / 2;
if (Math.abs(middle - halfWidth) < 20) {
final int middle = (bound.left + bound.right) / 2;
if (Math.abs(middle - halfWidth) < 20)
paint = mPaintSelected;
}
canvas.drawText(mTitleProvider.getTitle(i), bound.left, bound.bottom, paint);
}
}
@@ -345,19 +428,18 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
break;
case Underline:
float deltaPercentage = mCurrentOffset * 1.0f / width;
final float deltaPercentage = mCurrentOffset * 1.0f / width;
int alpha = 0xFF;
int page = mCurrentPage;
if (deltaPercentage <= UNDERLINE_FADE_PERCENTAGE) {
if (deltaPercentage <= UNDERLINE_FADE_PERCENTAGE)
alpha = (int) (0xFF * ((UNDERLINE_FADE_PERCENTAGE - deltaPercentage) / UNDERLINE_FADE_PERCENTAGE));
} else if (deltaPercentage >= (1 - UNDERLINE_FADE_PERCENTAGE)) {
else if (deltaPercentage >= 1 - UNDERLINE_FADE_PERCENTAGE) {
alpha = (int) (0xFF * ((deltaPercentage - (1 - UNDERLINE_FADE_PERCENTAGE)) / UNDERLINE_FADE_PERCENTAGE));
page += 1; // We are coming into the next page
} else if (mCurrentOffset != 0) {
} else if (mCurrentOffset != 0)
break; // Not in underline scope
}
Rect underlineBounds = bounds.get(page);
final Rect underlineBounds = bounds.get(page);
mPath.reset();
mPath.moveTo(underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
mPath.lineTo(underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
@@ -372,219 +454,41 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
}
}
@Override
public final boolean onTouch(View view, MotionEvent event) {
if ((view != this) || (event.getAction() != MotionEvent.ACTION_DOWN)) {
return false;
}
final int count = mViewPager.getAdapter().getCount();
final float halfWidth = getWidth() / 2;
final float sixthWidth = getWidth() / 6;
if ((mCurrentPage > 0) && (event.getX() < halfWidth - sixthWidth)) {
mViewPager.setCurrentItem(mCurrentPage - 1);
return true;
} else if ((mCurrentPage < count - 1) && (event.getX() > halfWidth + sixthWidth)) {
mViewPager.setCurrentItem(mCurrentPage + 1);
return true;
}
return false;
}
@Override
public final void setOnTouchListener(OnTouchListener listener) {
throw new UnsupportedOperationException("This view does not support listening to its touch events.");
}
/**
* Set bounds for the right textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheRight(Rect curViewBound, int curViewWidth, int leftPlusWidth) {
curViewBound.right = leftPlusWidth - (int)mClipPadding;
curViewBound.left = curViewBound.right - curViewWidth;
}
/**
* Set bounds for the left textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheLeft(Rect curViewBound, int curViewWidth) {
curViewBound.left = 0 + (int)mClipPadding;
curViewBound.right = curViewWidth;
}
/**
* Calculate views bounds and scroll them according to the current index
*
* @param paint
* @param currentIndex
* @return
*/
private ArrayList<Rect> calculateAllBounds(Paint paint) {
ArrayList<Rect> list = new ArrayList<Rect>();
//For each views (If no values then add a fake one)
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final int halfWidth = width / 2;
for (int i = 0; i < count; i++) {
Rect bounds = calcBounds(i, paint);
int w = (bounds.right - bounds.left);
int h = (bounds.bottom - bounds.top);
bounds.left = (halfWidth) - (w / 2) - mCurrentOffset + ((i - mCurrentPage) * width);
bounds.right = bounds.left + w;
bounds.top = 0;
bounds.bottom = h;
list.add(bounds);
}
return list;
}
/**
* Calculate the bounds for a view's title
*
* @param index
* @param paint
* @return
*/
private Rect calcBounds(int index, Paint paint) {
//Calculate the text bounds
Rect bounds = new Rect();
bounds.right = (int)paint.measureText(mTitleProvider.getTitle(index));
bounds.bottom = (int)(paint.descent() - paint.ascent());
return bounds;
}
@Override
public void setViewPager(ViewPager view) {
if (view.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
if (!(view.getAdapter() instanceof TitleProvider)) {
throw new IllegalStateException("ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
}
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
mTitleProvider = (TitleProvider)mViewPager.getAdapter();
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mCurrentOffset = positionOffsetPixels;
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
/*
* (non-Javadoc)
*
* @see android.view.View#onMeasure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
mCurrentPage = position;
mCurrentOffset = positionOffsetPixels;
invalidate();
if (specMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(getClass().getSimpleName() + " can only be used in EXACTLY mode.");
}
result = specSize;
return result;
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(int measureSpec) {
float result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
//We were told how big to be
result = specSize;
} else {
//Calculate the text bounds
Rect bounds = new Rect();
bounds.bottom = (int) (mPaintText.descent()-mPaintText.ascent());
result = bounds.bottom - bounds.top + mFooterLineHeight;
if (mFooterIndicatorStyle != IndicatorStyle.None) {
result += mFooterIndicatorHeight + mFooterIndicatorPadding;
}
}
return (int)result;
if (mListener != null)
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
public void onPageScrollStateChanged(final int state) {
if (mListener != null)
mListener.onPageScrollStateChanged(state);
}
@Override
public void onPageSelected(final int position) {
if (mListener != null)
mListener.onPageSelected(position);
}
@Override
public void onRestoreInstanceState(final Parcelable state) {
final SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
@@ -593,40 +497,118 @@ public class TitlePageIndicator extends TextView implements PageIndicator, View.
@Override
public Parcelable onSaveInstanceState() {
setFreezesText(true);
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
final Parcelable superState = super.onSaveInstanceState();
final SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
@Override
public final boolean onTouch(final View view, final MotionEvent event) {
if (view != this || event.getAction() != MotionEvent.ACTION_DOWN)
return false;
public SavedState(Parcelable superState) {
super(superState);
final int count = mViewPager.getAdapter().getCount();
final float halfWidth = getWidth() / 2;
final float sixthWidth = getWidth() / 6;
if (mCurrentPage > 0 && event.getX() < halfWidth - sixthWidth) {
mViewPager.setCurrentItem(mCurrentPage - 1);
return true;
} else if (mCurrentPage < count - 1 && event.getX() > halfWidth + sixthWidth) {
mViewPager.setCurrentItem(mCurrentPage + 1);
return true;
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
return false;
}
public void setClipPadding(final float clipPadding) {
mClipPadding = clipPadding;
invalidate();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
public void setCurrentItem(final int item) {
if (mViewPager == null)
throw new IllegalStateException("ViewPager has not been bound.");
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
public void setFooterColor(final int footerColor) {
mPaintFooterLine.setColor(footerColor);
invalidate();
}
public void setFooterIndicatorHeight(final float footerTriangleHeight) {
mFooterIndicatorHeight = footerTriangleHeight;
invalidate();
}
public void setFooterIndicatorStyle(final IndicatorStyle indicatorStyle) {
mFooterIndicatorStyle = indicatorStyle;
invalidate();
}
public void setFooterLineHeight(final float footerLineHeight) {
mFooterLineHeight = footerLineHeight;
invalidate();
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
public void setOnPageChangeListener(final ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
};
@Override
public final void setOnTouchListener(final OnTouchListener listener) {
throw new UnsupportedOperationException("This view does not support listening to its touch events.");
}
public void setSelectedBold(final boolean selectedBold) {
mPaintSelected.setFakeBoldText(selectedBold);
invalidate();
}
public void setSelectedColor(final int selectedColor) {
mPaintSelected.setColor(selectedColor);
invalidate();
}
@Override
public void setTextColor(final int textColor) {
mPaintText.setColor(textColor);
invalidate();
}
@Override
public void setTextSize(final float textSize) {
mPaintText.setTextSize(textSize);
invalidate();
}
public void setTitlePadding(final float titlePadding) {
mTitlePadding = titlePadding;
invalidate();
}
@Override
public void setViewPager(final ViewPager view) {
if (view.getAdapter() == null)
throw new IllegalStateException("ViewPager does not have adapter instance.");
if (!(view.getAdapter() instanceof TitleProvider))
throw new IllegalStateException("ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
mTitleProvider = (TitleProvider) mViewPager.getAdapter();
invalidate();
}
@Override
public void setViewPager(final ViewPager view, final int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
}

View File

@@ -21,6 +21,7 @@ package com.jakewharton.android.viewpagerindicator;
public interface TitleProvider {
/**
* Returns the title of the view at position
*
* @param position
* @return
*/

View File

@@ -13,26 +13,30 @@ import android.support.v4.app.FragmentManager;
/**
* This adaptor maintains a ViewPager title indicator.
*
* @author ricky
*/
public class TitledFragmentAdapter extends FragmentAdapter implements TitleProvider {
private String[] mTitles;
private final String[] mTitles;
/**
* Creates a new TitleFragmentAdapter
*
* @param fm
* @param fragments to be displayed
* @param titles for the fragments
* @param fragments
* to be displayed
* @param titles
* for the fragments
* @author ricky barrette
*/
public TitledFragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments, String[] titles) {
public TitledFragmentAdapter(final FragmentManager fm, final ArrayList<Fragment> fragments, final String[] titles) {
super(fm, fragments);
this.mTitles = titles;
mTitles = titles;
}
@Override
public String getTitle(int position) {
return this.mTitles[position];
public String getTitle(final int position) {
return mTitles[position];
}
}