Inital Commit of the framented migration

Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
2012-05-10 13:07:38 -04:00
parent 50f050dd33
commit 69597150ea
64 changed files with 4363 additions and 2178 deletions

View File

@@ -0,0 +1,17 @@
/**
* enableScrollingListener.java
* @date Aug 13, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger;
/**
* A simple listener to allow fragments to set scrolling enabled
* @author ricky
*/
public interface EnableScrollingListener {
public void setScrollEnabled(boolean enabled);
}

View File

@@ -1,18 +0,0 @@
/**
* LocatoinSelectedListener.java
* @date May 9, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger;
import com.google.android.maps.GeoPoint;
/**
* This interface will be used to pass the selected location from the dialogs to the listening instance
* @author ricky barrette
*/
public interface LocationSelectedListener {
public void onLocationSelected(GeoPoint point);
}

View File

@@ -0,0 +1,22 @@
/**
* onContentChangedListener.java
* @date Aug 7, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
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
* @author ricky
*/
public interface OnContentChangedListener {
void onRingerContentChanged(ContentValues ringer);
void onInfoContentChanged(ContentValues info);
}

View File

@@ -41,7 +41,6 @@ public class RingerDatabase {
private Context mContext;
private SQLiteDatabase mDb;
public boolean isUpgrading = false;
private static final String RINGER_INFO_TABLE = "ringer_info";
private DatabaseListener mListener;
/*
@@ -54,6 +53,7 @@ public class RingerDatabase {
*/
private final String DATABASE_NAME = "ringers.db";
private final String RINGER_TABLE = "ringers";
private static final String RINGER_INFO_TABLE = "ringer_info";
/*
* Database keys
@@ -79,6 +79,10 @@ public class RingerDatabase {
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";
/**
@@ -424,6 +428,20 @@ private class OpenHelper extends SQLiteOpenHelper {
return list;
}
/**
* 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() {
List<String> list = new ArrayList<String>();
List<String> ringers = getAllRingerTitles();
for(String ringer: ringers){
list.add(getRingerInfo(ringer).getAsString(KEY_RINGER_DESCRIPTION));
}
return list;
}
/**
* gets a ringer from a row id;
* @param id

View File

@@ -69,7 +69,7 @@ public class LocationService extends SkyHookService {
*/
private void startOnGoingNotification() {
this.mNotificationManager = (NotificationManager) this.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
Notification notifyDetails = new Notification(R.drawable.newstatusbar_icon, this.getString(R.string.app_name), System.currentTimeMillis());
Notification notifyDetails = new Notification(R.drawable.icon, this.getString(R.string.app_name), System.currentTimeMillis());
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(this, LocationRinger.class), android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
notifyDetails.setLatestEventInfo(this, this.getString(R.string.app_name), this.getString(R.string.gathering), intent);
notifyDetails.flags |= Notification.FLAG_ONGOING_EVENT;

View File

@@ -1,375 +0,0 @@
/**
* RingerInformationHowActivity.java
* @date Jul 29, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.TwentyCodes.android.LocationRinger.LocationSelectedListener;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
import com.TwentyCodes.android.SkyHook.SkyHook;
import com.TwentyCodes.android.location.GeoPointLocationListener;
import com.TwentyCodes.android.location.MapView;
import com.google.android.maps.GeoPoint;
/**
* This activity will allow users to pick how a ringer works. Using this activity they will pick triggers for this ringer
* @author ricky
*/
public class HowActivity extends com.google.android.maps.MapActivity implements LocationSelectedListener, GeoPointLocationListener, OnClickListener, OnCheckedChangeListener, OnSeekBarChangeListener {
private static final String TAG = "RingerInformationHowActivity";
private static final int ADD_ID = 1;
private static final int WHAT_REQUEST_CODE = 467468436;
private SeekBar mRadius;
private MapView mMapView;
private ToggleButton mMapEditToggle;
private RadiusOverlay mRadiusOverlay;
private GeoPoint mPoint;
private SkyHook mSkyHook;
private ProgressDialog mGpsProgress;
private boolean isFirstFix;
private ScrollView mScrollView;
@Override
protected boolean isRouteDisplayed() {
//UNUSED
return false;
}
/**
* Called when the HOW activity finishes, this will just pass the results back to the ringer list activity
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
this.setResult(RESULT_OK, data);
this.finish();
}
//don show for default
if(this.getIntent().getBooleanExtra(ListActivity.KEY_IS_DEFAULT, false))
this.finish();
}
/**
* Called when a toggle button's state is changed
* @author ricky barrette
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch(buttonView.getId()){
case R.id.map_edit_toggle:
this.isFirstFix = isChecked;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,
isChecked
? (this.getResources().getDisplayMetrics().heightPixels - findViewById(R.id.map_controls).getHeight())
: (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350, getResources().getDisplayMetrics())));
if(isChecked){
this.mSkyHook.getUpdates();
params.addRule(RelativeLayout.ALIGN_PARENT_TOP );
this.mGpsProgress = ProgressDialog.show(this, "", this.getText(R.string.gps_fix), true, true);
} else {
this.mSkyHook.removeUpdates();
params.addRule(RelativeLayout.BELOW, R.id.info);
params.addRule(RelativeLayout.ALIGN_BOTTOM );
if(this.mGpsProgress != null)
this.mGpsProgress.dismiss();
}
findViewById(R.id.map_info).setLayoutParams(params );
this.mMapView.setDoubleTapZoonEnabled(isChecked);
//buttons
findViewById(R.id.mark_my_location).setVisibility(isChecked ? View.VISIBLE : View.GONE);
findViewById(R.id.my_location).setVisibility(isChecked ? View.VISIBLE : View.GONE);
findViewById(R.id.map_mode).setVisibility(isChecked ? View.VISIBLE : View.GONE);
findViewById(R.id.search).setVisibility(isChecked ? View.VISIBLE : View.GONE);
findViewById(R.id.add_feature_button).setVisibility(isChecked ? View.GONE : View.VISIBLE);
this.mScrollView.invalidate();
this.mScrollView.setScrollEnabled(! isChecked);
this.mMapView.setBuiltInZoomControls(isChecked);
this.mMapView.setClickable(isChecked);
this.mRadius.setEnabled(isChecked);
Toast.makeText(this, isChecked ? getString(R.string.map_editing_enabled) : getString(R.string.map_editiing_disabled), Toast.LENGTH_SHORT).show();
break;
}
}
/**
* Called when a view is clicked
* @author ricky barrette
*/
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.mark_my_location:
if(this.mPoint != null){
this.mRadiusOverlay.setLocation(mPoint);
this.mMapView.getController().setCenter(mPoint);
}
break;
case R.id.my_location:
if(this.mPoint != null)
this.mMapView.getController().setCenter(mPoint);
break;
case R.id.map_mode:
this.mMapView.setSatellite(mMapView.isSatellite() ? false : true);
break;
case R.id.search:
new SearchDialog(this, this).show();
break;
case R.id.add_feature_button:
Toast.makeText(this, "NO TRIGGERS YET", Toast.LENGTH_LONG).show();
break;
case R.id.save_ringer_button:
save();
break;
}
}
/**
* Called when the acivity is first created
* @author ricky barrette
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.how);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
this.mSkyHook = new SkyHook(this);
this.mSkyHook.setLocationListener(this);
this.mScrollView = (ScrollView) findViewById(R.id.scrollview);
this.mMapView = (MapView) findViewById(R.id.mapview);
this.mRadius = (SeekBar) findViewById(R.id.radius);
this.mRadius.setMax(Debug.MAX_RADIUS_IN_METERS);
this.mMapView.setClickable(false);
this.mMapEditToggle = (ToggleButton) findViewById(R.id.map_edit_toggle);
this.mMapEditToggle.setChecked(false);
this.mMapEditToggle.setOnCheckedChangeListener(this);
this.mRadiusOverlay = new RadiusOverlay();
this.mRadius.setOnSeekBarChangeListener(this);
this.mMapView.getOverlays().add(mRadiusOverlay);
this.mRadius.setEnabled(false);
findViewById(R.id.mark_my_location).setOnClickListener(this);
findViewById(R.id.my_location).setOnClickListener(this);
findViewById(R.id.map_mode).setOnClickListener(this);
findViewById(R.id.search).setOnClickListener(this);
findViewById(R.id.save_ringer_button).setOnClickListener(this);
findViewById(R.id.add_feature_button).setOnClickListener(this);
Intent data = this.getIntent();
this.setTitle(getString(R.string.editing)+" "+data.getStringExtra(RingerDatabase.KEY_RINGER_NAME));
if(data.hasExtra(ListActivity.KEY_INFO)){
/*
* We need to null check all the values
*/
ContentValues info = (ContentValues) data.getParcelableExtra(ListActivity.KEY_INFO);
if (info.get(RingerDatabase.KEY_LOCATION_LAT) != null && info.get(RingerDatabase.KEY_LOCATION_LON) != null){
this.mRadiusOverlay.setLocation(new GeoPoint(info.getAsInteger(RingerDatabase.KEY_LOCATION_LAT), info.getAsInteger(RingerDatabase.KEY_LOCATION_LON)));
}
if (info.get(RingerDatabase.KEY_RADIUS) != null){
this.mRadius.setProgress(info.getAsInteger(RingerDatabase.KEY_RADIUS));
}
if(data.getBooleanExtra(ListActivity.KEY_IS_DEFAULT, false)){
this.startActivityForResult(new Intent(this, WhatActivity.class).putExtras(this.getIntent()), WHAT_REQUEST_CODE);
}
} else
this.setTitle(R.string.new_ringer);
if(this.mRadiusOverlay.getLocation() != null){
this.mMapView.getController().setCenter(this.mRadiusOverlay.getLocation());
this.mMapView.getController().setZoom(16);
}
this.mMapView.setDoubleTapZoonEnabled(false);
}
/**
* Creates the main menu that is displayed when the menu button is clicked
* @author ricky barrette
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, ADD_ID, 0, getString(R.string.add_feature)).setIcon(android.R.drawable.ic_menu_add);
return super.onCreateOptionsMenu(menu);
}
/* (non-Javadoc)
* @see com.google.android.maps.MapActivity#onDestroy()
* @author ricky barrette
*/
@Override
protected void onDestroy() {
this.mSkyHook.removeUpdates();
super.onDestroy();
}
/**
* Called when skyhook has a location to report
* @author ricky barrette
*/
@Override
public void onLocationChanged(GeoPoint point, int accuracy) {
this.mPoint = point;
if(point != 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.isFirstFix)
if(this.mRadiusOverlay.getLocation() == null){
if(this.mMapView != null){
this.mMapView.getController().setCenter(point);
this.mMapView.getController().setZoom((this.mMapView.getMaxZoomLevel() - 5));
}
this.isFirstFix = false;
}
/*
* dismiss the acquiring gps dialog
*/
if(this.mGpsProgress != null)
this.mGpsProgress.dismiss();
}
}
/*
*/
@Override
public void onLocationSelected(GeoPoint point) {
if(point != null){
if(Debug.DEBUG)
Log.d(TAG, "onLocationSelected() "+ point.toString());
if(this.mRadiusOverlay != null)
this.mRadiusOverlay.setLocation(point);
if(this.mMapView != null){
this.mMapView.getController().setCenter(point);
this.mMapView.getController().setZoom((this.mMapView.getMaxZoomLevel() - 5));
}
} else if(Debug.DEBUG)
Log.d(TAG, "onLocationSelected() Location was null");
}
/* (non-Javadoc)
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
* @author ricky barrette
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case ADD_ID:
//TODO display triggers
break;
}
return super.onOptionsItemSelected(item);
}
/**
* Called when a seekbar is has its progress changed
* @author ricky barrette
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
switch (seekBar.getId()){
case R.id.radius:
this.mRadiusOverlay.setRadius(progress);
this.mMapView.invalidate();
break;
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//UNUSED
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//UNUSED
}
/**
* 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);
//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();
Intent data = new Intent(HowActivity.this, WhatActivity.class).putExtras(HowActivity.this.getIntent());
GeoPoint point = HowActivity.this.mRadiusOverlay.getLocation();
ContentValues info = data.getParcelableExtra(ListActivity.KEY_INFO);
if(info == null)
info = new ContentValues();
/*
* package the ringer table information
*/
info.put(RingerDatabase.KEY_LOCATION_LAT, point.getLatitudeE6());
info.put(RingerDatabase.KEY_LOCATION_LON, point.getLongitudeE6());
info.put(RingerDatabase.KEY_RADIUS, HowActivity.this.mRadius.getProgress());
//package the intent
data.putExtra(ListActivity.KEY_INFO, info);
progress.dismiss();
HowActivity.this.startActivityForResult(data, WHAT_REQUEST_CODE);
}
}).start();
}
@Override
public void onFirstFix(boolean isFirstFix) {
// TODO Auto-generated method stub
}
}

View File

@@ -100,7 +100,7 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
@Override
public void onClick(View v) {
Intent i = new Intent(this, HowActivity.class);
Intent i = new Intent(this, RingerInformationActivity.class);
startActivityForResult(i, ACTIVITY_CREATE );
}
@@ -227,28 +227,31 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
public void run(){
Looper.prepare();
Intent i = new Intent(ListActivity.this, HowActivity.class)
Intent i = new Intent(ListActivity.this, RingerInformationActivity.class)
.putExtra(KEY_ROWID, id+1);
/*
* get the ringer
*/
Cursor ringer = mDb.getRingerFromId(id+1);
if (ringer.moveToFirst())
i.putExtra(RingerDatabase.KEY_RINGER_NAME, ringer.getString(0))
.putExtra(RingerDatabase.KEY_IS_ENABLED, RingerDatabase.parseBoolean(ringer.getString(1)));
if (ringer.moveToFirst()){
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()) {
ringer.close();
}
if(id == 0)
i.putExtra(KEY_IS_DEFAULT, true);
/*
* get the ringer's info, and parse it into content values
*/
i.putExtra(KEY_INFO, mDb.getRingerInfo(i.getStringExtra(RingerDatabase.KEY_RINGER_NAME)));
if (ringer != null && !ringer.isClosed()) {
ringer.close();
}
if(id == 0)
i.putExtra(KEY_IS_DEFAULT, true);
/*
* get the ringer's info, and parse it into content values
*/
i.putExtra(KEY_INFO, mDb.getRingerInfo(r.getAsString(RingerDatabase.KEY_RINGER_NAME)));
}
progress.dismiss();
@@ -269,7 +272,7 @@ public class ListActivity extends Activity implements OnItemClickListener, OnCli
public boolean onOptionsItemSelected (MenuItem item) {
switch (item.getItemId()){
case NEW_RINGER:
Intent i = new Intent(this, WhatActivity.class);
Intent i = new Intent(this, RingerInformationActivity.class);
startActivityForResult(i, ACTIVITY_CREATE );
return true;

View File

@@ -1,150 +0,0 @@
/**
* @author Twenty Codes
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.RectF;
import com.TwentyCodes.android.location.GeoUtils;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;
/**
* This class will used to draw a radius of a specified size in a specified location, then inserted into
* an overlay list to be displayed a map
* @author ricky barrette
*/
public class RadiusOverlay extends Overlay{
public OverlayItem mOverlayItem;
private GeoPoint mPoint;
private float mRadius = 0;
private int mColor = Color.GREEN;
private GeoPoint mRadiusPoint;
/**
* Creates a new RadiusOverlay
* @author ricky barrette
*/
public RadiusOverlay(){
}
/**
* Creates a new RadiusOverlay object that can be inserted into an overlay list.
* @param point center of radius geopoint
* @param radius radius in meters
* @param color desired color of the radius from Color API
* @author ricky barrette
*/
public RadiusOverlay(GeoPoint point, float radius, int color) {
mPoint = point;
mRadius = radius;
mColor = color;
}
/**
* draws a specific radius on the mapview that is handed to it
* @param canvas canvas to be drawn on
* @param mapView
* @param shadow
* @param when
*/
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow){
if(mPoint != null){
Paint paint = new Paint();
Point center = new Point();
Point left = new Point();
Projection projection = mapView.getProjection();
/*
* Calculate a geopoint that is "radius" meters away from geopoint point and
* convert the given GeoPoint and leftGeo to onscreen pixel coordinates,
* relative to the top-left of the MapView that provided this Projection.
*/
mRadiusPoint = GeoUtils.distanceFrom(mPoint , mRadius);
projection.toPixels(mRadiusPoint, left);
projection.toPixels(mPoint, center);
/*
* get radius of the circle being drawn by
*/
int circleRadius = center.x - left.x;
if(circleRadius <= 0){
circleRadius = left.x - center.x;
}
/*
* paint a circle on the map
*/
paint.setAntiAlias(true);
paint.setStrokeWidth(2.0f);
paint.setColor(mColor);
paint.setStyle(Style.STROKE);
canvas.drawCircle(center.x, center.y, circleRadius, paint);
//draw a dot over the geopoint
RectF oval = new RectF(center.x - 2, center.y - 2, center.x + 2, center.y + 2);
canvas.drawOval(oval, paint);
//fill the radius with a nice green
paint.setAlpha(25);
paint.setStyle(Style.FILL);
canvas.drawCircle(center.x, center.y, circleRadius, paint);
}
}
/**
* @return the selected location
* @author ricky barrette
*/
public GeoPoint getLocation(){
return mPoint;
}
@Override
public boolean onTap(GeoPoint p, MapView mapView) {
mPoint = p;
return super.onTap(p, mapView);
}
/**
* @param color
* @author ricky barrette
*/
public void setColor(int color){
mColor = color;
}
/**
* @param location
* @author ricky barrette
*/
public void setLocation(GeoPoint location){
mPoint = location;
}
/**
* @param radius in meters
* @author ricky barrette
* @param radius
*/
public void setRadius(int radius){
mRadius = radius;
}
public int getZoomLevel() {
// GeoUtils.GeoUtils.distanceFrom(mPoint , mRadius)
return 0;
}
}

View File

@@ -0,0 +1,213 @@
/**
* RingerInformationActivity.java
* @date Aug 6, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui;
import java.util.ArrayList;
import java.util.Map.Entry;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.TwentyCodes.android.LocationRinger.EnableScrollingListener;
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 com.TwentyCodes.android.LocationRinger.ui.fragments.AboutRingerFragment;
import com.TwentyCodes.android.LocationRinger.ui.fragments.FeatureListFragment;
import com.TwentyCodes.android.LocationRinger.ui.fragments.MapFragment;
import com.TwentyCodes.android.LocationRinger.ui.fragments.RingtoneFragment;
import com.TwentyCodes.android.LocationRinger.ui.fragments.ToggleButtonFragment;
import com.TwentyCodes.android.LocationRinger.ui.fragments.VolumeFragment;
import com.jakewharton.android.viewpagerindicator.TitlePageIndicator;
import com.jakewharton.android.viewpagerindicator.TitledFragmentAdapter;
/**
* This activity will handle displaying ringer options
* @author ricky
*/
public class RingerInformationActivity extends FragmentActivity implements OnContentChangedListener, EnableScrollingListener{
private static final int SAVE_ID = 0;
private static final String TAG = "RingerInformationActivity";
private ContentValues mRinger;
private ContentValues mInfo;
private Intent mData;
private ViewPager mPager;
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.ringer_information_activity);
this.mData = new Intent().putExtras(RingerInformationActivity.this.getIntent());
this.mRinger = this.mData.getParcelableExtra(ListActivity.KEY_RINGER);
this.mInfo = this.mData.getParcelableExtra(ListActivity.KEY_INFO);
if(this.mRinger == null)
this.mRinger = new ContentValues();
if(this.mInfo == null)
this.mInfo = new ContentValues();
/*
* set the title
*/
if(this.mRinger.containsKey(RingerDatabase.KEY_RINGER_NAME))
this.setTitle(this.getString(R.string.editing)+" "+this.mRinger.getAsString(RingerDatabase.KEY_RINGER_NAME));
else
this.setTitle(R.string.new_ringer);
/*
* Page titles
*/
String[] titles = new String[]{
this.getString(R.string.about),
this.getString(R.string.location),
this.getString(R.string.what)
};
ArrayList<Fragment> fragments = new ArrayList<Fragment>();
/*
* about page
*/
fragments.add(new AboutRingerFragment(this.mRinger, this.mInfo, this));
/*
* Location page
*/
fragments.add(new MapFragment(this.mInfo, this, this));
/*
* What page
* ONLY Dynamically add the required fragments that have already been added.
*
* TODO
* update interval
*/
ArrayList<Fragment> what = new ArrayList<Fragment>();
// if(this.mInfo.containsKey(RingerDatabase.KEY_RINGTONE) || this.mInfo.containsKey(RingerDatabase.KEY_RINGTONE_IS_SILENT) || this.mInfo.containsKey(RingerDatabase.KEY_RINGTONE_VOLUME))
what.add(new RingtoneFragment(this.mInfo, this, AudioManager.STREAM_RING));
// if(this.mInfo.containsKey(RingerDatabase.KEY_NOTIFICATION_RINGTONE) || this.mInfo.containsKey(RingerDatabase.KEY_NOTIFICATION_IS_SILENT) || this.mInfo.containsKey(RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME))
what.add(new RingtoneFragment(this.mInfo, this, AudioManager.STREAM_NOTIFICATION));
// if(this.mInfo.containsKey(RingerDatabase.KEY_ALARM_VOLUME))
what.add(new VolumeFragment(this.mInfo, this, this, AudioManager.STREAM_ALARM));
// if(this.mInfo.containsKey(RingerDatabase.KEY_MUSIC_VOLUME))
what.add(new VolumeFragment(this.mInfo, this, this, AudioManager.STREAM_MUSIC));
// if(this.mInfo.containsKey(RingerDatabase.KEY_WIFI))
what.add(new ToggleButtonFragment(this.getString(R.string.wifi), RingerDatabase.KEY_WIFI, this.mInfo, this));
// if(this.mInfo.containsKey(RingerDatabase.KEY_BT))
what.add(new ToggleButtonFragment(this.getString(R.string.bluetooth), RingerDatabase.KEY_BT, this.mInfo, this));
fragments.add(new FeatureListFragment(this.mInfo, this, what));
//Populate the pager
this.mPager = (ViewPager)findViewById(R.id.pager);
if(this.mPager != null)
this.mPager.setAdapter(new TitledFragmentAdapter(this.getSupportFragmentManager(), fragments, titles));
//populate the pager's indicator
TitlePageIndicator indicator = (TitlePageIndicator)findViewById(R.id.indicator);
if(indicator != null)
indicator.setViewPager(this.mPager);
/*
* TODO
* button bar
*/
}
/**
* Creates the main menu that is displayed when the menu button is clicked
* @author ricky barrette
*/
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, SAVE_ID, 0, getString(R.string.save_ringer)).setIcon(android.R.drawable.ic_menu_save);
return super.onCreateOptionsMenu(menu);
}
/* (non-Javadoc)
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
* @author ricky barrette
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case SAVE_ID:
save();
break;
}
return super.onOptionsItemSelected(item);
}
/**
* 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);
//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);
progress.dismiss();
RingerInformationActivity.this.finish();
}
}).start();
}
@Override
public void onRingerContentChanged(ContentValues values) {
if(Debug.DEBUG){
Log.v(TAG,"onRingerContentChanged()");
logContentValues(values);
}
this.mRinger.putAll(values);
}
@Override
public void onInfoContentChanged(ContentValues values) {
if(Debug.DEBUG){
Log.v(TAG,"onInfoContentChanged()");
logContentValues(values);
}
this.mInfo.putAll(values);
}
/**
* Logs the content values
* @param values
* @author ricky barrette
*/
private void logContentValues(ContentValues values) {
for(Entry<String,Object> item : values.valueSet())
Log.d(TAG, item.getKey() +" = "+ item.getValue());
}
@Override
public void setScrollEnabled(boolean enabled) {
this.mPager.setScrollEnabled(enabled);
}
}

View File

@@ -31,18 +31,10 @@ public class RingerListAdapter extends BaseAdapter {
private static final String TAG = "RingerListAdapter";
/* (non-Javadoc)
* @see android.widget.BaseAdapter#notifyDataSetChanged()
* @author ricky barrette
*/
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
private RingerDatabase mDb;
private List<String> mList;
private List<String> mTitles;
private LayoutInflater mInflater;
private List<String> mDescriptions;
/**
* Creates a new RingerListAdapter
@@ -56,17 +48,18 @@ public class RingerListAdapter extends BaseAdapter {
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
mDb = db;
mList = db.getAllRingerTitles();
mTitles = db.getAllRingerTitles();
mDescriptions = db.getAllRingerDescriptions();
}
@Override
public int getCount() {
return mList.size();
return mTitles.size();
}
@Override
public String getItem(int position) {
return mList.get(position);
return mTitles.get(position);
}
@Override
@@ -90,7 +83,8 @@ public class RingerListAdapter extends BaseAdapter {
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(android.R.id.text1);
holder.title = (TextView) convertView.findViewById(android.R.id.text1);
holder.description = (TextView) convertView.findViewById(android.R.id.text2);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.ringer_enabled_checkbox);
convertView.setTag(holder);
@@ -109,7 +103,7 @@ public class RingerListAdapter extends BaseAdapter {
if(holder == null)
Log.e(TAG,"holder is null!!!");
if(holder.text == null)
if(holder.title == null)
Log.e(TAG,"holder.text is null!!!");
if(holder.checkbox == null)
@@ -121,7 +115,8 @@ public class RingerListAdapter extends BaseAdapter {
* Remember that you should always call setChecked() after calling setOnCheckedChangedListener.
* This will prevent the list from changing the values on you.
*/
holder.text.setText(getItem(position));
holder.title.setText(getItem(position));
holder.description.setText(mDescriptions.get(position));
holder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@@ -131,15 +126,19 @@ public class RingerListAdapter extends BaseAdapter {
holder.checkbox.setChecked(mDb.isRingerEnabled(position +1));
//Remove the checkbox for the default ringer
if(position == 0)
if(position == 0) {
holder.checkbox.setVisibility(View.INVISIBLE);
if(holder.description.getText().toString() == null)
holder.description.setText(R.string.about_default_ringer);
}
else
holder.checkbox.setVisibility(View.VISIBLE);
return convertView;
}
class ViewHolder {
TextView text;
TextView title;
TextView description;
CheckBox checkbox;
}

View File

@@ -65,4 +65,4 @@ public class ScrollView extends android.widget.ScrollView {
return isEnabled ? super.onTouchEvent(ev) : false;
}
}
}

View File

@@ -24,9 +24,9 @@ import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import com.TwentyCodes.android.LocationRinger.LocationSelectedListener;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
import com.TwentyCodes.android.location.OnLocationSelectedListener;
import com.TwentyCodes.android.location.ReverseGeocoder;
import com.google.android.maps.GeoPoint;
@@ -43,14 +43,14 @@ public class SearchDialog extends Dialog implements android.view.View.OnClickLis
private ProgressBar mProgress;
private Handler mHandler;
private Context mContext;
private LocationSelectedListener mListener;
private OnLocationSelectedListener mListener;
/**
* Creates a new search dialog
* @param context
* @author ricky barrette
*/
public SearchDialog(Context context, LocationSelectedListener listener) {
public SearchDialog(Context context, OnLocationSelectedListener listener) {
super(context);
this.setTitle(R.string.search);
this.setContentView(R.layout.address_dialog);

View File

@@ -1,118 +0,0 @@
/**
* @author Twenty Codes
* @author ricky barrette
* @date June 29, 2011
*/
package com.TwentyCodes.android.LocationRinger.ui;
import com.TwentyCodes.android.LocationRinger.R;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Typeface;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* this class will be a simple preference that contains only a text view that will display the application build information
* @author ricky barrette
*/
public class VersionInformationPreference extends Preference {
private Context mContext;
/**
* creates a preference that is nothing but a text view
* @param context
*/
public VersionInformationPreference(Context context) {
super(context);
mContext = context;
}
/**
* creates a preference that is nothing but a text view
* @param context
* @param attrs
*/
public VersionInformationPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
/**
* creates a preference that is nothing but a text view
* @param context
* @param attrs
* @param defStyle
*/
public VersionInformationPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
}
/**
* 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){
/*
* get the build information, and build the string
*/
PackageManager pm = mContext.getPackageManager();
PackageInfo pi;
try {
pi = pm.getPackageInfo(mContext.getPackageName(), 0);
} catch (NameNotFoundException eNnf) {
//doubt this will ever run since we want info about our own package
pi = new PackageInfo();
pi.versionName = "unknown";
pi.versionCode = 1;
}
/*
* 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);
// params.gravity = Gravity.CENTER;
layout.setPadding(15, 5, 10, 5);
layout.setOrientation(LinearLayout.VERTICAL);
layout.removeAllViews();
/*
* create a textview that will be used to display the application's name and build information
* and add it to the layout
*/
TextView title = new TextView(getContext());
title.setText(mContext.getString(R.string.app_name)+" "+pi.versionName+" bulid "+pi.versionCode);
title.setTextSize(16);
title.setTypeface(Typeface.SANS_SERIF);
title.setGravity(Gravity.LEFT);
title.setLayoutParams(params);
/*
* add the title views to the layout
*/
layout.addView(title);
layout.setId(android.R.id.widget_frame);
return layout;
}
}

View File

@@ -0,0 +1,57 @@
/**
* ViewPager.java
* @date Aug 13, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* @author ricky
*/
public class ViewPager extends android.support.v4.view.ViewPager {
private boolean isEnabled = true;
/**
* @param context
* @param apiKey
* @author ricky barrette
*/
public ViewPager(Context context) {
super(context);
}
/**
* @param context
* @param attrs
* @author ricky barrette
*/
public ViewPager(Context context, 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) {
return isEnabled ? super.onInterceptTouchEvent(ev) : false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return isEnabled ? super.onTouchEvent(ev) : false;
}
}

View File

@@ -1,504 +0,0 @@
/**
* RingeInformationActivity.java
* @date Apr 29, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.ToggleButton;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
/**
* This activity will be used to display what this ringer controls. here the user will be able to add or modify features they wish to control
* @author ricky barrette
*/
public class WhatActivity extends Activity implements OnCheckedChangeListener, OnClickListener {
private static final int SAVE_ID = 0;
//private static final String TAG = "RingerInformationWhatActivity";
private static final int ADD_ID = 1;
private SeekBar mRingtonVolume;
private SeekBar mNotificationRingtoneVolume;
private EditText mNotificationRingtone;
private EditText mRingerName;
private EditText mRingtone;
private ToggleButton mNotificationRingtoneToggle;
private ToggleButton mRingerToggle;
private ToggleButton mRingtoneToggle;
private String mRingtoneURI;
private String mNotificationRingtoneURI;
private ToggleButton mWifiToggle;
private ToggleButton mBTToggle;
private SeekBar mAlarmVolume;
private ProgressBar mMusicVolume;
private void addFeature(int item) {
String feature = this.getResources().getStringArray(R.array.features)[item];
if(feature.equals(this.getString(R.string.ringtone))){
findViewById(R.id.ringtone_info).setVisibility(View.VISIBLE);
}
if(feature.equals(this.getString(R.string.notification_ringtone))){
findViewById(R.id.notification_ringtone_info).setVisibility(View.VISIBLE);
}
if(feature.equals(this.getString(R.string.alarm_volume))){
findViewById(R.id.alarm_volume_info).setVisibility(View.VISIBLE);
}
if(feature.equals(this.getString(R.string.music_volume))){
findViewById(R.id.music_volume_info).setVisibility(View.VISIBLE);
}
if(feature.equals(this.getString(R.string.bluetooth))){
findViewById(R.id.bluetooth_toggle).setVisibility(View.VISIBLE);
}
if(feature.equals(this.getString(R.string.wifi))){
findViewById(R.id.wifi_toggle).setVisibility(View.VISIBLE);
}
if(feature.equals(this.getString(R.string.update_interval))){
findViewById(R.id.update_interval_info).setVisibility(View.VISIBLE);
}
if(this.mBTToggle.isShown() || this.mWifiToggle.isShown())
findViewById(R.id.data_label).setVisibility(View.VISIBLE);
}
/**
* Will display a prompt asking for what feature to add.
* @author ricky
*/
private void displayFeaturesDialog() {
/*
* TODO
* Check to see if wifi is available
* check to see if bluetooth is available,
* remove unavailable options
*/
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(this.getText(R.string.add_feature));
builder.setItems(R.array.features, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
addFeature(item);
}
});
AlertDialog alert = builder.create();
alert.show();
}
/**
* starts the ringtone picker
* @param ringtoneCode RingtoneManager.TYPE_?
* @param uri of current tone
* @author ricky barrette
*/
private void getRingtoneURI(int ringtoneCode, String uri){
Intent intent = new Intent( RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra( RingtoneManager.EXTRA_RINGTONE_TYPE, ringtoneCode);
intent.putExtra( RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone");
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
if( uri == null)
try {
uri = RingtoneManager.getActualDefaultRingtoneUri(this, ringtoneCode).toString();
} catch (NullPointerException e) {
e.printStackTrace();
}
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, uri == null ? null : Uri.parse(uri));
startActivityForResult( intent, ringtoneCode);
}
/**
* Called when the rintone picker activity returns it's result
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RingtoneManager.TYPE_RINGTONE:
this.mRingtoneURI = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI).toString();
Ringtone ringtone = RingtoneManager.getRingtone(this, Uri.parse(this.mRingtoneURI));
this.mRingtone.setText(ringtone == null ? "Silent" : ringtone.getTitle(this));
break;
case RingtoneManager.TYPE_NOTIFICATION:
this.mNotificationRingtoneURI = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI).toString();
Ringtone notificationTone = RingtoneManager.getRingtone(this, Uri.parse(this.mNotificationRingtoneURI));
this.mNotificationRingtone.setText(notificationTone == null ? "Silent" : notificationTone.getTitle(this));
break;
}
}
}
/**
* Called when a toggle button's state is changed
* @author ricky barrette
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch(buttonView.getId()){
case R.id.ringer_toggle:
//TODO disable all the child views, or find xml tag to allow setting of child view enabled via parent
findViewById(R.id.ringtone_info).setEnabled(isChecked);
findViewById(R.id.notification_ringtone_info).setEnabled(isChecked);
findViewById(R.id.alarm_volume_info).setEnabled(isChecked);
findViewById(R.id.music_volume_info).setEnabled(isChecked);
findViewById(R.id.bluetooth_toggle).setEnabled(isChecked);
findViewById(R.id.wifi_toggle).setEnabled(isChecked);
findViewById(R.id.update_interval_info).setEnabled(isChecked);
findViewById(R.id.data_label).setEnabled(isChecked);
break;
case R.id.notification_silent_toggle:
findViewById(R.id.notification_ringtone_button).setEnabled(!isChecked);
this.mNotificationRingtone.setEnabled(!isChecked);
this.mNotificationRingtoneVolume.setEnabled(!isChecked);
break;
case R.id.ringtone_silent_toggle:
this.mRingtone.setEnabled(!isChecked);
findViewById(R.id.ringtone_button).setEnabled(!isChecked);
this.mRingtonVolume.setEnabled(!isChecked);
break;
}
}
/**
* Called when a view is clicked
* @author ricky barrette
*/
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.notification_ringtone_button:
getRingtoneURI(RingtoneManager.TYPE_NOTIFICATION, mNotificationRingtoneURI);
break;
case R.id.ringtone_button:
getRingtoneURI(RingtoneManager.TYPE_RINGTONE, mRingtoneURI);
break;
case R.id.save_ringer_button:
save();
break;
case R.id.add_feature_button:
findViewById(R.id.add_a_feature_label).setVisibility(View.GONE);
displayFeaturesDialog();
break;
}
}
/**
* Called when the acivity is first created
* @author ricky barrette
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.what);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
this.mRingerName = (EditText) findViewById(R.id.ringer_name);
this.mRingerToggle = (ToggleButton) findViewById(R.id.ringer_toggle);
this.mRingerToggle.setChecked(true);
this.mRingerToggle.setOnCheckedChangeListener(this);
this.mRingtone = (EditText) findViewById(R.id.ringtone);
this.mRingtoneToggle = (ToggleButton) findViewById(R.id.ringtone_silent_toggle);
this.mRingtonVolume = (SeekBar) findViewById(R.id.ringtone_volume);
this.mRingtonVolume.setMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_RING));
this.mRingtonVolume.setProgress(mAudioManager.getStreamVolume(AudioManager.STREAM_RING));
this.mRingtoneToggle.setChecked(mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT ? true : false);
this.mRingtoneToggle.setOnCheckedChangeListener(this);
this.mRingtone.setEnabled(! mRingtoneToggle.isChecked());
this.mRingtonVolume.setEnabled(! mRingtoneToggle.isChecked());
this.mRingtone.setClickable(true);
this.mNotificationRingtone = (EditText) findViewById(R.id.notification_ringtone);
this.mNotificationRingtoneVolume = (SeekBar) findViewById(R.id.notification_ringtone_volume);
this.mNotificationRingtoneToggle = (ToggleButton) findViewById(R.id.notification_silent_toggle);
this.mNotificationRingtoneVolume.setMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
this.mNotificationRingtoneVolume.setProgress(mAudioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION));
this.mNotificationRingtoneToggle.setOnCheckedChangeListener(this);
this.mNotificationRingtoneToggle.setChecked(mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT ? true : false);
this.mNotificationRingtone.setEnabled(! mNotificationRingtoneToggle.isChecked());
this.mNotificationRingtoneVolume.setEnabled(! mNotificationRingtoneToggle.isChecked());
this.mNotificationRingtone.setClickable(true);
this.mMusicVolume = (SeekBar) findViewById(R.id.music_volume);
this.mMusicVolume.setMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
this.mMusicVolume.setProgress(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
this.mAlarmVolume = (SeekBar) findViewById(R.id.alarm_volume);
this.mAlarmVolume.setMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM));
this.mAlarmVolume.setProgress(mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM));
this.mWifiToggle = (ToggleButton) findViewById(R.id.wifi_toggle);
this.mBTToggle = (ToggleButton) findViewById(R.id.bluetooth_toggle);
findViewById(R.id.ringtone_button).setOnClickListener(this);
findViewById(R.id.notification_ringtone_button).setOnClickListener(this);
findViewById(R.id.save_ringer_button).setOnClickListener(this);
findViewById(R.id.mark_my_location).setOnClickListener(this);
findViewById(R.id.my_location).setOnClickListener(this);
findViewById(R.id.map_mode).setOnClickListener(this);
findViewById(R.id.search).setOnClickListener(this);
findViewById(R.id.add_feature_button).setOnClickListener(this);
try {
this.mRingtoneURI = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE).toString();
this.mRingtone.setText(RingtoneManager.getRingtone(this, Uri.parse(mRingtoneURI)).getTitle(this));
} catch (NullPointerException e) {
e.printStackTrace();
this.mRingtoneToggle.setChecked(true);
}
try {
this.mNotificationRingtoneURI = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_NOTIFICATION).toString();
this.mNotificationRingtone.setText(RingtoneManager.getRingtone(this, Uri.parse(mNotificationRingtoneURI)).getTitle(this));
} catch (NullPointerException e) {
e.printStackTrace();
this.mNotificationRingtoneToggle.setChecked(true);
}
Intent data = this.getIntent();
if(data.hasExtra(ListActivity.KEY_INFO)){
this.mRingerToggle.setChecked(data.getBooleanExtra(RingerDatabase.KEY_IS_ENABLED, true));
this.mRingerName.setText(data.getStringExtra(RingerDatabase.KEY_RINGER_NAME));
this.setTitle(getString(R.string.editing)+" "+mRingerName.getText().toString());
/*
* if this is the default ringer, then we will display everything
*/
if(data.getBooleanExtra(ListActivity.KEY_IS_DEFAULT, false)){
findViewById(R.id.ringer_options).setVisibility(View.GONE);
findViewById(R.id.notification_ringtone_info).setVisibility(View.VISIBLE);
findViewById(R.id.ringtone_info).setVisibility(View.VISIBLE);
findViewById(R.id.wifi_toggle).setVisibility(View.VISIBLE);
findViewById(R.id.data_label).setVisibility(View.VISIBLE);
findViewById(R.id.bluetooth_toggle).setVisibility(View.VISIBLE);
findViewById(R.id.music_volume_info).setVisibility(View.VISIBLE);
findViewById(R.id.alarm_volume_info).setVisibility(View.VISIBLE);
findViewById(R.id.update_interval_info).setVisibility(View.VISIBLE);
findViewById(R.id.add_feature_button).setVisibility(View.GONE);
}
/*
* We need to null check all the values
*/
ContentValues info = (ContentValues) data.getParcelableExtra(ListActivity.KEY_INFO);
if(RingerDatabase.parseBoolean(info.getAsString(RingerDatabase.KEY_PLUS_BUTTON_HINT)));
findViewById(R.id.add_a_feature_label).setVisibility(View.GONE);
if (info.get(RingerDatabase.KEY_NOTIFICATION_IS_SILENT) != null){
this.mNotificationRingtoneToggle.setChecked(RingerDatabase.parseBoolean(info.getAsString(RingerDatabase.KEY_NOTIFICATION_IS_SILENT)));
findViewById(R.id.notification_ringtone_info).setVisibility(View.VISIBLE);
}
if (info.get(RingerDatabase.KEY_NOTIFICATION_RINGTONE) != null){
this.mNotificationRingtone.setText(info.getAsString(RingerDatabase.KEY_NOTIFICATION_RINGTONE));
findViewById(R.id.notification_ringtone_info).setVisibility(View.VISIBLE);
}
if (info.get(RingerDatabase.KEY_NOTIFICATION_RINGTONE_URI) != null)
this.mNotificationRingtoneURI = info.getAsString(RingerDatabase.KEY_NOTIFICATION_RINGTONE_URI);
if (info.get(RingerDatabase.KEY_RINGTONE) != null){
findViewById(R.id.ringtone_info).setVisibility(View.VISIBLE);
this.mRingtone.setText(info.getAsString(RingerDatabase.KEY_RINGTONE));
}
if (info.get(RingerDatabase.KEY_RINGTONE_IS_SILENT) != null) {
this.mRingtoneToggle.setChecked(RingerDatabase.parseBoolean(info.getAsString(RingerDatabase.KEY_RINGTONE_IS_SILENT)));
findViewById(R.id.ringtone_info).setVisibility(View.VISIBLE);
}
if (info.get(RingerDatabase.KEY_RINGTONE_URI) != null)
this.mRingtoneURI = info.getAsString(RingerDatabase.KEY_RINGTONE_URI);
if (info.get(RingerDatabase.KEY_WIFI) != null){
this.mWifiToggle.setChecked(RingerDatabase.parseBoolean(info.getAsString(RingerDatabase.KEY_WIFI)));
findViewById(R.id.wifi_toggle).setVisibility(View.VISIBLE);
findViewById(R.id.data_label).setVisibility(View.VISIBLE);
}
if (info.get(RingerDatabase.KEY_BT) != null){
this.mBTToggle.setChecked(RingerDatabase.parseBoolean(info.getAsString(RingerDatabase.KEY_BT)));
findViewById(R.id.bluetooth_toggle).setVisibility(View.VISIBLE);
findViewById(R.id.data_label).setVisibility(View.VISIBLE);
}
if (info.get(RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME) != null)
this.mNotificationRingtoneVolume.setProgress(info.getAsInteger(RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME));
if (info.get(RingerDatabase.KEY_RINGTONE_VOLUME) != null)
this.mRingtonVolume.setProgress(info.getAsInteger(RingerDatabase.KEY_RINGTONE_VOLUME));
if (info.get(RingerDatabase.KEY_MUSIC_VOLUME) != null){
this.mMusicVolume.setProgress(info.getAsInteger(RingerDatabase.KEY_MUSIC_VOLUME));
findViewById(R.id.music_volume_info).setVisibility(View.VISIBLE);
}
if (info.get(RingerDatabase.KEY_ALARM_VOLUME) != null){
this.mAlarmVolume.setProgress(info.getAsInteger(RingerDatabase.KEY_ALARM_VOLUME));
findViewById(R.id.alarm_volume_info).setVisibility(View.VISIBLE);
}
if (info.get(RingerDatabase.KEY_UPDATE_INTERVAL) != null){
String ui = info.getAsString(RingerDatabase.KEY_UPDATE_INTERVAL);
findViewById(R.id.update_interval_info).setVisibility(View.VISIBLE);
String[] values = this.getResources().getStringArray(R.array.runtimes);
for(int i = 0; i < values.length; i++)
if(ui.equals(values[i])){
((Spinner) findViewById(R.id.update_interval)).setSelection(i);
break;
}
}
} else
this.setTitle(R.string.new_ringer);
}
/**
* Creates the main menu that is displayed when the menu button is clicked
* @author ricky barrette
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, SAVE_ID, 0, getString(R.string.save_ringer)).setIcon(android.R.drawable.ic_menu_save);
menu.add(0, ADD_ID, 0, getString(R.string.add_feature)).setIcon(android.R.drawable.ic_menu_add);
return super.onCreateOptionsMenu(menu);
}
/* (non-Javadoc)
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
* @author ricky barrette
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case ADD_ID:
displayFeaturesDialog();
break;
case SAVE_ID:
save();
break;
}
return super.onOptionsItemSelected(item);
}
/**
* 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);
//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();
Intent data = new Intent().putExtras(WhatActivity.this.getIntent());
ContentValues ringer = WhatActivity.this.getIntent().getParcelableExtra(ListActivity.KEY_RINGER);
ContentValues info = WhatActivity.this.getIntent().getParcelableExtra(ListActivity.KEY_INFO);
if(ringer == null)
ringer = new ContentValues();
if(info == null)
info = new ContentValues();
/*
* package the ringer table information
*/
ringer.put(RingerDatabase.KEY_RINGER_NAME, WhatActivity.this.mRingerName.getText().toString());
ringer.put(RingerDatabase.KEY_IS_ENABLED, WhatActivity.this.mRingerToggle.isChecked());
/*
* package the ringer_info table information
*/
if(findViewById(R.id.notification_ringtone_info).isShown()){
info.put(RingerDatabase.KEY_NOTIFICATION_IS_SILENT, WhatActivity.this.mNotificationRingtoneToggle.isChecked());
info.put(RingerDatabase.KEY_NOTIFICATION_RINGTONE, WhatActivity.this.mNotificationRingtone.getText().toString());
info.put(RingerDatabase.KEY_NOTIFICATION_RINGTONE_URI, WhatActivity.this.mNotificationRingtoneURI);
info.put(RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME, WhatActivity.this.mNotificationRingtoneVolume.getProgress());
}
if(findViewById(R.id.ringtone_info).isShown()){
info.put(RingerDatabase.KEY_RINGTONE, WhatActivity.this.mRingtone.getText().toString());
info.put(RingerDatabase.KEY_RINGTONE_IS_SILENT, WhatActivity.this.mRingtoneToggle.isChecked());
info.put(RingerDatabase.KEY_RINGTONE_URI, WhatActivity.this.mRingtoneURI);
info.put(RingerDatabase.KEY_RINGTONE_VOLUME, WhatActivity.this.mRingtonVolume.getProgress());
}
if(findViewById(R.id.wifi_toggle).isShown())
info.put(RingerDatabase.KEY_WIFI, WhatActivity.this.mWifiToggle.isChecked());
if(findViewById(R.id.bluetooth_toggle).isShown())
info.put(RingerDatabase.KEY_BT, WhatActivity.this.mBTToggle.isChecked());
if(findViewById(R.id.music_volume_info).isShown())
info.put(RingerDatabase.KEY_MUSIC_VOLUME, WhatActivity.this.mMusicVolume.getProgress());
if(findViewById(R.id.alarm_volume_info).isShown())
info.put(RingerDatabase.KEY_ALARM_VOLUME, WhatActivity.this.mAlarmVolume.getProgress());
if(findViewById(R.id.update_interval_info).isShown())
info.put(RingerDatabase.KEY_UPDATE_INTERVAL,
WhatActivity.this.getResources().getStringArray(R.array.runtimes)[((Spinner) findViewById(R.id.update_interval)).getSelectedItemPosition()]);
info.put(RingerDatabase.KEY_PLUS_BUTTON_HINT, true);
//package the intent
data.putExtra(ListActivity.KEY_RINGER, ringer).putExtra(ListActivity.KEY_INFO, info);
WhatActivity.this.setResult(RESULT_OK, data);
progress.dismiss();
WhatActivity.this.finish();
}
}).start();
}
}

View File

@@ -0,0 +1,180 @@
/**
* AboutRingerFragment.java
* @date Aug 8, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
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.content.ContentValues;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ToggleButton;
/**
* This fragment will used to allow the user to enter/edit ringer information
* @author ricky
*/
public class AboutRingerFragment extends Fragment implements OnCheckedChangeListener {
private static final String TAG = "AboutRingerFragment";
private ListeningEditText mRingerName;
private ListeningEditText mRingerDescription;
private ToggleButton mRingerEnabled;
private OnContentChangedListener mListener;
private ContentValues mInfo;
private ContentValues mRinger;
public AboutRingerFragment(ContentValues ringer, ContentValues info, OnContentChangedListener listener){
this.mInfo = info;
this.mRinger = ringer;
this.mListener = listener;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(RingerDatabase.KEY_IS_ENABLED, isChecked);
this.mListener.onRingerContentChanged(info);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
this.getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
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
* @author ricky barrette
*/
public static class ListeningEditText extends EditText{
private String mKey;
private OnContentChangedListener mListener;
/**
* Creates a new ListeningEditText
* @param context
* @author ricky barrette
*/
public ListeningEditText(Context context) {
super(context);
}
/**
* Creates a new ListeningEditText
* @param context
* @param attrs
* @author ricky barrette
*/
public ListeningEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* Creates a new ListeningEditText
* @param context
* @param attrs
* @param defStyle
* @author ricky barrette
*/
public ListeningEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Called when the edit text is drawn
* @author ricky barrette
*/
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
if(mListener != null){
ContentValues info = new ContentValues();
info.put(this.mKey, this.getText().toString());
if(this.mKey.equals(RingerDatabase.KEY_RINGER_NAME))
this.mListener.onRingerContentChanged(info);
else
this.mListener.onInfoContentChanged(info);
}
}
/**
* Sets the key for this ListeningEditText
* @param key
* @ author ricky barrette
*/
public void setKey(String key){
this.mKey = key;
}
/**
* Sets the listener of this ListeningEditText
* @param listener
* @ author ricky barrette
*/
public void setListener(OnContentChangedListener listener){
this.mListener = listener;
}
}
}

View File

@@ -0,0 +1,92 @@
/**
* FeatureListFragment.java
* @date Aug 7, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui.fragments;
import java.util.ArrayList;
import android.content.ContentValues;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.TwentyCodes.android.LocationRinger.OnContentChangedListener;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This fragment will be used to display a list of fragments
*
* TODO + create button bar that had a plus button and a hint + add/remove
* features
*
* @author ricky
*/
public class FeatureListFragment extends ListFragment {
/**
* (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) {
// TODO Auto-generated method stub
return super.onCreateView(inflator, container, bundle);
}
private static final String TAG = "FeatureListFragment";
private static final int DELETE_ID = 0;
private ArrayList<Fragment> mFeatures;
// private OnContentChangedListener mListener;
// private ContentValues mInfo;
// private int mIndex;
public FeatureListFragment(ContentValues info,
OnContentChangedListener listener, ArrayList<Fragment> fragments) {
super();
this.mFeatures = fragments;
// this.mInfo = info;
// this.mListener = listener;
}
@Override
public void onResume() {
this.setListAdapter(new FragmentListAdaptor(this, mFeatures));
this.getListView().setOnCreateContextMenuListener(this);
if (Debug.DEBUG)
Log.v(TAG, "onResume()");
super.onResume();
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.delete).setIcon(
android.R.drawable.ic_menu_delete);
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case DELETE_ID:
Toast.makeText(this.getActivity(), "deleted! (note really)",
Toast.LENGTH_LONG).show();
return true;
}
return super.onContextItemSelected(item);
}
}

View File

@@ -0,0 +1,154 @@
/**
* FragmentListAdaptor.java
* @date Dec 24, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.LocationRinger.ui.fragments;
import java.util.ArrayList;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.debug.Debug;
/**
* This Adaptor Class will be used to display fragments in a ListFragment.
* TODO
* + Add/Remove fragments on the fly
* @author ricky barrette
*/
public class FragmentListAdaptor extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<Fragment> mFragments;
private FragmentManager mFragmentManager;
private final String TAG = "FragmentListAdaptor";
/**
* Creates a new FragmentListAdaptor
* @param listFragment
* @param fragments
* @author ricky barrette
*/
public FragmentListAdaptor(ListFragment listFragment, ArrayList<Fragment> fragments) {
if(Debug.DEBUG)
Log.v(TAG, "FragmentListAdaptor()");
mInflater = LayoutInflater.from(listFragment.getActivity());
mFragments = fragments;
mFragmentManager = listFragment.getFragmentManager();
}
/**
* Returns the number of Fragments to display
* (non-Javadoc)
* @see android.widget.Adapter#getCount()
*/
@Override
public int getCount() {
if(Debug.DEBUG)
Log.v(TAG, "getCount() :"+ mFragments.size());
return mFragments.size();
}
/**
* Returns the fragment to display
* (non-Javadoc)
* @see android.widget.Adapter#getItem(int)
*/
@Override
public Fragment getItem(int position) {
if(Debug.DEBUG)
Log.v(TAG, "getItem("+position+")");
return mFragments.get(position);
}
/**
* Returns the id of the fragment being displayed
* (non-Javadoc)
* @see android.widget.Adapter#getItemId(int)
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* (non-Javadoc)
* @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(Debug.DEBUG)
Log.v(TAG, "getView("+position+")");
FragmentTransaction transaction = mFragmentManager.beginTransaction();
// A Holder keeps references to children views to avoid unnecessary calls to findViewById() on each row.
Holder 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
* by ListView is null.
*/
if (convertView == null) {
convertView = mInflater.inflate(R.layout.fragment_container, null);
/*
* Creates a ViewHolder and store references
* that we want to bind data to.
*/
holder = new Holder();
holder.view = (View) convertView.findViewById(R.id.fragment_container);
holder.view.setId(position+1);
holder.tag = createTag(position);
convertView.setTag(holder);
//add the fragment to the new view
transaction.add(holder.view.getId(), getItem(position), holder.tag);
} else {
// Get the ViewHolder back to get fast access to the Old Views
holder = (Holder) convertView.getTag();
Fragment shown = mFragmentManager.findFragmentByTag(holder.tag);
//replace the old fragment with a new one
holder.tag = createTag(position);
if(shown != null)
transaction.remove(shown);
transaction.add(holder.view.getId(), getItem(position), holder.tag);
transaction.addToBackStack(null);
}
transaction.commit();
return convertView;
}
/**
* @param position
* @return a unique tag to be used for identifying fragments
* @author ricky barrette
*/
private String createTag(int position){
return "andorid:FragmentList:tag:"+position;
}
/**
* Simple Holder class
* @author ricky barrette
*/
class Holder{
public String tag;
public View view;
}
}

View File

@@ -0,0 +1,295 @@
/**
* MapFragment.java
* @date Aug 8, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui.fragments;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.TwentyCodes.android.LocationRinger.EnableScrollingListener;
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;
import com.TwentyCodes.android.LocationRinger.ui.SearchDialog;
import com.TwentyCodes.android.SkyHook.SkyHook;
import com.TwentyCodes.android.fragments.SkyHoookUserOverlayMapFragment;
import com.TwentyCodes.android.location.GeoPointLocationListener;
import com.TwentyCodes.android.location.OnLocationSelectedListener;
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
* @author ricky
*/
public class MapFragment extends Fragment implements GeoPointLocationListener, OnClickListener, OnCheckedChangeListener, OnSeekBarChangeListener, OnLocationSelectedListener {
private ContentValues mInfo;
private OnContentChangedListener mListener;
private static final String TAG = "RingerInformationHowActivity";
private SeekBar mRadius;
private SkyHoookUserOverlayMapFragment mMapView;
private ToggleButton mMapEditToggle;
private RadiusOverlay mRadiusOverlay;
private GeoPoint mPoint;
private SkyHook mSkyHook;
private ProgressDialog mGpsProgress;
private boolean isFirstFix;
private View view;
private EnableScrollingListener mEnableScrollingListener;
/**
* Creates a new MapFragment
* @author ricky barrette
* @param ringerInformationActivity
*/
public MapFragment(ContentValues info, OnContentChangedListener listener, EnableScrollingListener enabledListener) {
this.mInfo = info;
this.mListener = listener;
this.mEnableScrollingListener = enabledListener;
}
/**
* Called when a toggle button's state is changed
* @author ricky barrette
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
this.isFirstFix = isChecked;
view.findViewById(R.id.buttons).setVisibility(isChecked ? View.VISIBLE : View.GONE);
if(mEnableScrollingListener != null)
mEnableScrollingListener.setScrollEnabled(!isChecked);
if(isChecked){
this.mSkyHook.getUpdates();
this.mGpsProgress = ProgressDialog.show(this.getActivity(), "", this.getText(R.string.gps_fix), true, true);
} else {
this.mSkyHook.removeUpdates();
if(this.mGpsProgress != null)
this.mGpsProgress.dismiss();
}
this.mMapView.setDoubleTapZoonEnabled(isChecked);
//buttons
this.mMapView.setBuiltInZoomControls(isChecked);
this.mMapView.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();
}
/**
* Called when a view is clicked
* @author ricky barrette
*/
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.mark_my_location:
if(this.mPoint != null){
this.mRadiusOverlay.setLocation(mPoint);
this.mMapView.setMapCenter(mPoint);
}
break;
case R.id.my_location:
if(this.mPoint != null)
this.mMapView.setMapCenter(mPoint);
break;
case R.id.map_mode:
this.mMapView.setSatellite(mMapView.isSatellite() ? false : true);
break;
case R.id.search:
new SearchDialog(this.getActivity(), this).show();
break;
}
}
/* (non-Javadoc)
* @see com.google.android.maps.MapActivity#onDestroy()
* @author ricky barrette
*/
@Override
public void onStop() {
this.mSkyHook.removeUpdates();
super.onDestroy();
}
/**
* Called when skyhook has a location to report
* @author ricky barrette
*/
@Override
public void onLocationChanged(GeoPoint point, int accuracy) {
this.mPoint = point;
if(point != 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.isFirstFix)
if(this.mRadiusOverlay.getLocation() == null){
if(this.mMapView != null){
this.mMapView.setMapCenter(point);
this.mMapView.setZoom((this.mMapView.getMap().getMaxZoomLevel() - 5));
}
this.isFirstFix = false;
}
/*
* dismiss the acquiring gps dialog
*/
if(this.mGpsProgress != null)
this.mGpsProgress.dismiss();
}
}
/*
*/
@Override
public void onLocationSelected(GeoPoint point) {
if(point != null){
if(Debug.DEBUG)
Log.d(TAG, "onLocationSelected() "+ point.toString());
if(this.mRadiusOverlay != null)
this.mRadiusOverlay.setLocation(point);
if(this.mMapView != null){
this.mMapView.setMapCenter(point);
this.mMapView.setZoom((this.mMapView.getMap().getMaxZoomLevel() - 5));
}
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(RingerDatabase.KEY_LOCATION_LAT, point.getLatitudeE6());
info.put(RingerDatabase.KEY_LOCATION_LON, point.getLongitudeE6());
this.mListener.onInfoContentChanged(info);
}
} else if(Debug.DEBUG)
Log.d(TAG, "onLocationSelected() Location was null");
}
/**
* Called when a seekbar is has its progress changed
* @author ricky barrette
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
switch (seekBar.getId()){
case R.id.radius:
this.mRadiusOverlay.setRadius(progress);
this.mMapView.invalidate();
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(RingerDatabase.KEY_RADIUS, progress);
this.mListener.onInfoContentChanged(info);
}
break;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.map_info_fragment, container, false);
this.mSkyHook = new SkyHook(this.getActivity());
this.mSkyHook.setLocationListener(this);
this.mMapView = (SkyHoookUserOverlayMapFragment) this.getFragmentManager().findFragmentById(R.id.mapview);
this.mRadius = (SeekBar) view.findViewById(R.id.radius);
this.mRadius.setMax(Debug.MAX_RADIUS_IN_METERS);
this.mMapView.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.mMapView.addOverlay(mRadiusOverlay);
this.mRadius.setEnabled(false);
if (this.mInfo.get(RingerDatabase.KEY_LOCATION_LAT) != null && this.mInfo.get(RingerDatabase.KEY_LOCATION_LON) != null){
this.mRadiusOverlay.setLocation(new GeoPoint(this.mInfo.getAsInteger(RingerDatabase.KEY_LOCATION_LAT), this.mInfo.getAsInteger(RingerDatabase.KEY_LOCATION_LON)));
}
if (this.mInfo.get(RingerDatabase.KEY_RADIUS) != null){
this.mRadius.setProgress(this.mInfo.getAsInteger(RingerDatabase.KEY_RADIUS));
}
if(this.mRadiusOverlay.getLocation() != null){
this.mMapView.setMapCenter(this.mRadiusOverlay.getLocation());
this.mMapView.setZoom(16);
}
this.mMapView.setDoubleTapZoonEnabled(false);
view.findViewById(R.id.my_location).setOnClickListener(this);
view.findViewById(R.id.mark_my_location).setOnClickListener(this);
view.findViewById(R.id.search).setOnClickListener(this);
view.findViewById(R.id.map_mode).setOnClickListener(this);
return view;
}
/**
* (non-Javadoc)
* @see android.support.v4.app.Fragment#onPause()
*/
@Override
public void onPause() {
mSkyHook.removeUpdates();
super.onPause();
}
/**
* (non-Javadoc)
* @see android.support.v4.app.Fragment#onResume()
*/
@Override
public void onResume() {
if(mMapEditToggle.isChecked())
mSkyHook.getUpdates();
super.onResume();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onFirstFix(boolean isFirstFix) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,244 @@
/**
* RingtoneFragment.java
* @date Aug 6, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui.fragments;
import java.util.Map.Entry;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.ToggleButton;
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;
/**
* This fragment will be for ringtone settings
* @author ricky
*/
public class RingtoneFragment extends Fragment implements OnClickListener, OnCheckedChangeListener, OnSeekBarChangeListener {
private static final String TAG = "RingtoneFragment";
private ToggleButton mRingtoneToggle;
private String mRingtoneURI;
private EditText mRingtone;
private SeekBar mRingtonVolume;
private Button mRingtoneButton;
private int mStream;
private int mType;
private OnContentChangedListener mListener;
private String mKeyEnabled;
private String mKeyUri;
private String mKeyRingtone;
private String mKeyVolume;
private ContentValues mInfo;
public RingtoneFragment(ContentValues info, OnContentChangedListener listener, int stream){
super();
this.mListener = listener;
this.mStream = stream;
this.mInfo = info;
switch(stream){
case AudioManager.STREAM_RING:
mKeyEnabled = RingerDatabase.KEY_RINGTONE_IS_SILENT;
mKeyUri = RingerDatabase.KEY_RINGTONE_URI;
mKeyRingtone = RingerDatabase.KEY_RINGTONE;
mKeyVolume = RingerDatabase.KEY_RINGTONE_VOLUME;
break;
case AudioManager.STREAM_NOTIFICATION:
mKeyEnabled = RingerDatabase.KEY_NOTIFICATION_IS_SILENT;
mKeyUri = RingerDatabase.KEY_NOTIFICATION_RINGTONE_URI;
mKeyRingtone = RingerDatabase.KEY_NOTIFICATION_RINGTONE;
mKeyVolume = RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME;
break;
}
}
/**
* starts the ringtone picker
* @param ringtoneCode RingtoneManager.TYPE_?
* @param uri of current tone
* @author ricky barrette
*/
private void getRingtoneURI(int ringtoneCode, String uri){
Intent intent = new Intent( RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra( RingtoneManager.EXTRA_RINGTONE_TYPE, ringtoneCode);
intent.putExtra( RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone");
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
if( uri == null)
try {
uri = RingtoneManager.getActualDefaultRingtoneUri(this.getActivity(), ringtoneCode).toString();
} catch (NullPointerException e) {
e.printStackTrace();
}
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, uri == null ? null : Uri.parse(uri));
startActivityForResult( intent, ringtoneCode);
}
/**
* Called when the ringtone picker activity returns it's result
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
Uri tone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if(tone == null){
this.mRingtone.setText(R.string.silent);
} else {
Ringtone ringtone = RingtoneManager.getRingtone(this.getActivity(), Uri.parse(tone.toString()));
this.mRingtone.setText(ringtone.getTitle(this.getActivity()));
}
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(this.mKeyRingtone, this.mRingtone.getText().toString());
info.put(this.mKeyUri, tone != null ? tone.toString() : null);
this.mListener.onInfoContentChanged(info);
}
}
}
/**
* Called when a toggle button's state is changed
* @author ricky barrette
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
this.mRingtone.setEnabled(!isChecked);
this.mRingtoneButton.setEnabled(!isChecked);
this.mRingtonVolume.setEnabled(!isChecked);
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(this.mKeyEnabled, isChecked);
this.mListener.onInfoContentChanged(info);
}
}
/**
* Called when a view is clicked
* @author ricky barrette
*/
@Override
public void onClick(View v) {
getRingtoneURI(this.mType, mRingtoneURI);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.ringtone_fragment, container, false);
AudioManager mAudioManager = (AudioManager) this.getActivity().getSystemService(Context.AUDIO_SERVICE);
if(Debug.DEBUG)
for(Entry<String,Object> item : this.mInfo.valueSet())
Log.d(TAG, item.getKey() +" = "+ item.getValue());
/*
* initialize the views
*/
TextView label = (TextView) view.findViewById(R.id.label);
this.mRingtone = (EditText) view.findViewById(R.id.ringtone);
this.mRingtoneToggle = (ToggleButton) view.findViewById(R.id.ringtone_silent_toggle);
this.mRingtonVolume = (SeekBar) view.findViewById(R.id.ringtone_volume);
this.mRingtoneButton = (Button) view.findViewById(R.id.ringtone_button);
this.mRingtoneButton.setOnClickListener(this);
this.mRingtonVolume.setMax(mAudioManager.getStreamMaxVolume(mStream));
switch(this.mStream){
case AudioManager.STREAM_RING:
label.setText(R.string.ringtone);
mType = RingtoneManager.TYPE_RINGTONE;
break;
case AudioManager.STREAM_NOTIFICATION:
label.setText(R.string.notification_ringtone);
mType = RingtoneManager.TYPE_NOTIFICATION;
break;
}
/*
* ringtone & uri
*/
if(this.mInfo.containsKey(this.mKeyUri) && this.mInfo.containsKey(this.mKeyRingtone)){
this.mRingtone.setText(this.mInfo.getAsString(this.mKeyRingtone));
this.mRingtoneURI = this.mInfo.getAsString(this.mKeyUri);
} else
try {
this.mRingtoneURI = RingtoneManager.getActualDefaultRingtoneUri(this.getActivity(), mType).toString();
this.mRingtone.setText(RingtoneManager.getRingtone(this.getActivity(), Uri.parse(mRingtoneURI)).getTitle(this.getActivity()));
} catch (NullPointerException e) {
e.printStackTrace();
this.mRingtoneToggle.setChecked(true);
}
/*
* volume
*/
if(this.mInfo.containsKey(this.mKeyVolume))
this.mRingtonVolume.setProgress(Integer.parseInt(this.mInfo.getAsString(this.mKeyVolume)));
else
this.mRingtonVolume.setProgress(mAudioManager.getStreamVolume(mStream));
/*
* silent toggle
*/
if(this.mInfo.containsKey(this.mKeyEnabled))
this.mRingtoneToggle.setChecked(!this.mInfo.getAsBoolean(this.mKeyEnabled));
else
this.mRingtoneToggle.setChecked(mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT ? true : false);
/*
* disable views if need be
*/
this.mRingtoneToggle.setOnCheckedChangeListener(this);
this.mRingtone.setEnabled(! mRingtoneToggle.isChecked());
this.mRingtonVolume.setEnabled(! mRingtoneToggle.isChecked());
this.mRingtonVolume.setOnSeekBarChangeListener(this);
return view;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser)
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(this.mKeyVolume, progress);
this.mListener.onInfoContentChanged(info);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}

View File

@@ -0,0 +1,69 @@
/**
* ToggleButtonFragment.java
* @date Aug 13, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui.fragments;
import com.TwentyCodes.android.LocationRinger.R;
import com.TwentyCodes.android.LocationRinger.OnContentChangedListener;
import com.TwentyCodes.android.LocationRinger.db.RingerDatabase;
import android.content.ContentValues;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.ToggleButton;
/**
* A simple fragment that displays a toggle button and a title label
* @author ricky
*/
public class ToggleButtonFragment extends Fragment implements OnCheckedChangeListener {
private String mTitle;
private String mKey;
private ContentValues mInfo;
private OnContentChangedListener mListener;
/**
* Creates a new ToggleButtonFtagment
* @author ricky barrette
*/
public ToggleButtonFragment(String title, String key, ContentValues info, OnContentChangedListener listener) {
super();
this.mTitle = title;
this.mKey = key;
this.mInfo = info;
this.mListener = listener;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) {
View view = inflater.inflate(R.layout.toggle_button_fragment, container, false);
TextView t = (TextView) view.findViewById(R.id.label);
t.setText(this.mTitle);
ToggleButton b = (ToggleButton) view.findViewById(R.id.toggle);
if(this.mInfo.containsKey(this.mKey))
b.setChecked(RingerDatabase.parseBoolean(this.mInfo.getAsString(this.mKey)));
b.setOnCheckedChangeListener(this);
return view;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(this.mKey, isChecked);
this.mListener.onInfoContentChanged(info);
}
}
}

View File

@@ -0,0 +1,123 @@
/**
* AlarmVolumeFragment.java
* @date Aug 7, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.TwentyCodes.android.LocationRinger.ui.fragments;
import java.util.Map.Entry;
import android.content.ContentValues;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
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;
/**
* This fragment will represent the volume fragments
* @author ricky
*/
public class VolumeFragment extends Fragment implements OnSeekBarChangeListener {
private static final String TAG = "VolumeFragment";
private AudioManager mAudioManager;
private int mStream;
private OnContentChangedListener mListener;
private String mKey;
private ContentValues mInfo;
public VolumeFragment(ContentValues info, Context context, OnContentChangedListener listener, int stream){
super();
this.mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
this.mStream = stream;
this.mListener = listener;
this.mInfo = info;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(Debug.DEBUG)
for(Entry<String,Object> item : this.mInfo.valueSet())
Log.d(TAG, item.getKey() +" = "+ item.getValue());
View view = inflater.inflate(R.layout.volume_fragment, container, false);
TextView label = (TextView) view.findViewById(R.id.volume_label);
SeekBar volume = (SeekBar) view.findViewById(R.id.volume);
volume.setMax(this.mAudioManager.getStreamMaxVolume(mStream));
volume.setProgress(this.mAudioManager.getStreamVolume(mStream));
volume.setOnSeekBarChangeListener(this);
switch(this.mStream){
case AudioManager.STREAM_ALARM:
label.setText(R.string.alarm_volume);
this.mKey = RingerDatabase.KEY_ALARM_VOLUME;
break;
case AudioManager.STREAM_DTMF:
label.setText(R.string.dtmf_volume);
this.mKey = RingerDatabase.KEY_DTMF_VOLUME;
break;
case AudioManager.STREAM_MUSIC:
label.setText(R.string.music_volume);
this.mKey = RingerDatabase.KEY_MUSIC_VOLUME;
break;
case AudioManager.STREAM_NOTIFICATION:
label.setText(R.string.notification_volume);
this.mKey = RingerDatabase.KEY_NOTIFICATION_RINGTONE_VOLUME;
break;
case AudioManager.STREAM_RING:
label.setText(R.string.ringtone_volume);
this.mKey = RingerDatabase.KEY_RINGTONE_VOLUME;
break;
case AudioManager.STREAM_SYSTEM:
label.setText(R.string.system_volume);
this.mKey = RingerDatabase.KEY_SYSTEM_VOLUME;
break;
case AudioManager.STREAM_VOICE_CALL:
label.setText(R.string.call_volume);
this.mKey = RingerDatabase.KEY_CALL_VOLUME;
break;
}
if(this.mInfo.containsKey(this.mKey))
volume.setProgress(Integer.parseInt(this.mInfo.getAsString(this.mKey)));
return view;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser)
if(this.mListener != null){
ContentValues info = new ContentValues();
info.put(this.mKey, progress);
this.mListener.onInfoContentChanged(info);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,45 @@
/**
* FragmentAdapter.java
* @date Aug 6, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.jakewharton.android.viewpagerindicator;
import java.util.ArrayList;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
/**
* This adaptor maintains the How and What fragments
* @author ricky
*/
class FragmentAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> mFragments;
/**
* Creates a new FragmentAdaptor
* @param fm
* @param fragments to be displayed
* @author ricky barrette
*/
public FragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
this.mFragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.mFragments.get(position);
}
@Override
public int getCount() {
return this.mFragments.size();
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jakewharton.android.viewpagerindicator;
import android.support.v4.view.ViewPager;
/**
* A PageIndicator is responsible to show an visual indicator on the total views
* number and the current visible view.
*/
public interface PageIndicator extends ViewPager.OnPageChangeListener {
/**
* Bind the indicator to a ViewPager.
*
* @param view
*/
public void setViewPager(ViewPager view);
/**
* Bind the indicator to a ViewPager.
*
* @param view
* @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

@@ -0,0 +1,630 @@
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Francisco Figueiredo Jr.
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jakewharton.android.viewpagerindicator;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
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.
*/
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) {
return style;
}
}
return null;
}
}
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private TitleProvider mTitleProvider;
private int mCurrentPage;
private int mCurrentOffset;
private final Paint mPaintText;
private final Paint mPaintSelected;
private Path mPath;
private final Paint mPaintFooterLine;
private IndicatorStyle mFooterIndicatorStyle;
private final Paint mPaintFooterIndicator;
private float mFooterIndicatorHeight;
private float mFooterIndicatorPadding;
private 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) {
this(context, null);
}
public TitlePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.titlePageIndicatorStyle);
}
public TitlePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
super.setOnTouchListener(this);
//Load defaults from resources
final Resources res = getResources();
final int defaultFooterColor = res.getColor(R.color.default_title_indicator_footer_color);
final float defaultFooterLineHeight = res.getDimension(R.dimen.default_title_indicator_footer_line_height);
final int defaultFooterIndicatorStyle = res.getInteger(R.integer.default_title_indicator_footer_indicator_style);
final float defaultFooterIndicatorHeight = res.getDimension(R.dimen.default_title_indicator_footer_indicator_height);
final float defaultFooterIndicatorPadding = res.getDimension(R.dimen.default_title_indicator_footer_indicator_padding);
final float defaultFooterIndicatorUnderlinePadding = res.getDimension(R.dimen.default_title_indicator_footer_indicator_underline_padding);
final int defaultSelectedColor = res.getColor(R.color.default_title_indicator_selected_color);
final boolean defaultSelectedBold = res.getBoolean(R.bool.default_title_indicator_selected_bold);
final int defaultTextColor = res.getColor(R.color.default_title_indicator_text_color);
final float defaultTextSize = res.getDimension(R.dimen.default_title_indicator_text_size);
final float defaultTitlePadding = res.getDimension(R.dimen.default_title_indicator_title_padding);
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);
//Retrieve the colors to be used for this view and apply them.
mFooterLineHeight = a.getDimension(R.styleable.TitlePageIndicator_footerLineHeight, defaultFooterLineHeight);
mFooterIndicatorStyle = IndicatorStyle.fromValue(a.getInteger(R.styleable.TitlePageIndicator_footerIndicatorStyle, defaultFooterIndicatorStyle));
mFooterIndicatorHeight = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorHeight, defaultFooterIndicatorHeight);
mFooterIndicatorPadding = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorPadding, defaultFooterIndicatorPadding);
mFooterIndicatorUnderlinePadding = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorUnderlinePadding, defaultFooterIndicatorUnderlinePadding);
mTitlePadding = a.getDimension(R.styleable.TitlePageIndicator_titlePadding, defaultTitlePadding);
mClipPadding = a.getDimension(R.styleable.TitlePageIndicator_clipPadding, defaultClipPadding);
final float textSize = a.getDimension(R.styleable.TitlePageIndicator_textSize, defaultTextSize);
final int footerColor = a.getColor(R.styleable.TitlePageIndicator_footerColor, defaultFooterColor);
mPaintText = new Paint();
mPaintText.setColor(a.getColor(R.styleable.TitlePageIndicator_textColor, defaultTextColor));
mPaintText.setTextSize(textSize);
mPaintText.setAntiAlias(true);
mPaintSelected = new Paint();
mPaintSelected.setColor(a.getColor(R.styleable.TitlePageIndicator_selectedColor, defaultSelectedColor));
mPaintSelected.setTextSize(textSize);
mPaintSelected.setFakeBoldText(a.getBoolean(R.styleable.TitlePageIndicator_selectedBold, defaultSelectedBold));
mPaintSelected.setAntiAlias(true);
mPaintFooterLine = new Paint();
mPaintFooterLine.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
mPaintFooterLine.setColor(footerColor);
mPaintFooterIndicator = new Paint();
mPaintFooterIndicator.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterIndicator.setColor(footerColor);
a.recycle();
}
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 int getSelectedColor() {
return mPaintSelected.getColor();
}
public void setSelectedColor(int selectedColor) {
mPaintSelected.setColor(selectedColor);
invalidate();
}
public boolean isSelectedBold() {
return mPaintSelected.isFakeBoldText();
}
public void setSelectedBold(boolean selectedBold) {
mPaintSelected.setFakeBoldText(selectedBold);
invalidate();
}
public int getTextColor() {
return mPaintText.getColor();
}
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();
}
/*
* (non-Javadoc)
*
* @see android.view.View#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Calculate views bounds
ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
final int count = mViewPager.getAdapter().getCount();
final int countMinusOne = count - 1;
final int halfWidth = getWidth() / 2;
final int left = getLeft();
final int width = getWidth();
final int height = getHeight();
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) {
//Try to clip to the screen (left side)
clipViewOnTheLeft(curViewBound, curViewWidth);
}
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) {
for (int i = mCurrentPage - 1; i >= 0; i--) {
Rect bound = bounds.get(i);
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);
//Intersection
if (bound.right + (int)mTitlePadding > rightBound.left) {
bound.left = rightBound.left - (w + (int)mTitlePadding);
}
}
}
}
}
//Right views starting from the current position
if (mCurrentPage < countMinusOne) {
for (int i = mCurrentPage + 1 ; i < count; i++) {
Rect bound = bounds.get(i);
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);
//Intersection
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);
//Only if one side is visible
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) {
paint = mPaintSelected;
}
canvas.drawText(mTitleProvider.getTitle(i), bound.left, bound.bottom, paint);
}
}
//Draw the footer line
mPath = new Path();
mPath.moveTo(0, height - mFooterLineHeight);
mPath.lineTo(width, height - mFooterLineHeight);
mPath.close();
canvas.drawPath(mPath, mPaintFooterLine);
switch (mFooterIndicatorStyle) {
case Triangle:
mPath = new Path();
mPath.moveTo(halfWidth, height - mFooterLineHeight - mFooterIndicatorHeight);
mPath.lineTo(halfWidth + mFooterIndicatorHeight, height - mFooterLineHeight);
mPath.lineTo(halfWidth - mFooterIndicatorHeight, height - mFooterLineHeight);
mPath.close();
canvas.drawPath(mPath, mPaintFooterIndicator);
break;
case Underline:
float deltaPercentage = mCurrentOffset * 1.0f / width;
int alpha = 0xFF;
int page = mCurrentPage;
if (deltaPercentage <= UNDERLINE_FADE_PERCENTAGE) {
alpha = (int)(0xFF * ((UNDERLINE_FADE_PERCENTAGE - deltaPercentage) / 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) {
break; //Not in underline scope
}
Rect underlineBounds = bounds.get(page);
mPath = new Path();
mPath.moveTo(underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
mPath.lineTo(underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
mPath.lineTo(underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight);
mPath.lineTo(underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight);
mPath.close();
mPaintFooterIndicator.setAlpha(alpha);
canvas.drawPath(mPath, mPaintFooterIndicator);
mPaintFooterIndicator.setAlpha(0xFF);
break;
}
}
@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) {
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);
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;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
setFreezesText(true);
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2011 Patrik Akerfeldt
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jakewharton.android.viewpagerindicator;
/**
* A TitleProvider provides the title to display according to a view.
*/
public interface TitleProvider {
/**
* Returns the title of the view at position
* @param position
* @return
*/
public String getTitle(int position);
}

View File

@@ -0,0 +1,38 @@
/**
* TitleFragmentAdapter.java
* @date Aug 6, 2011
* @author Twenty Codes, LLC
* @author ricky barrette
*/
package com.jakewharton.android.viewpagerindicator;
import java.util.ArrayList;
import android.support.v4.app.Fragment;
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;
/**
* Creates a new TitleFragmentAdapter
* @param fm
* @param fragments to be displayed
* @param titles for the fragments
* @author ricky barrette
*/
public TitledFragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments, String[] titles) {
super(fm, fragments);
this.mTitles = titles;
}
@Override
public String getTitle(int position) {
return this.mTitles[position];
}
}