计步器
2015-06-09 15:09
471 查看
1.CaloriesNotifier.java
5.PedometerSettings.java
6.Settings.java
7.SpeakingTimer
8.SpeedNotifier.java
9.StepBuzzer
11.StepDisplayer
12.StepListener
13.StepService
14.Utils
15.com.tdc.jibuqi.preferences.BodyWeightPreference
16.com.tdc.jibuqi.preferences.EditMeasurementPreference
17.com.tdc.jibuqi.preferences.StepLengthPreference
18.layout/main.xml
19.arrays.xml
20.colors.xml
21.dimens.xml
22.strings.xml
23.styles.xml
24.中文strings.xml
package com.tdc.jibuqi; import java.util.Locale; /** * Calculates and displays the approximate calories. */ public class CaloriesNotifier implements StepListener, SpeakingTimer.Listener { public interface Listener { public void valueChanged(float value); public void passValue(); } private Listener mListener; private static double METRIC_RUNNING_FACTOR = 1.02784823; private static double IMPERIAL_RUNNING_FACTOR = 0.75031498; private static double METRIC_WALKING_FACTOR = 0.708; private static double IMPERIAL_WALKING_FACTOR = 0.517; private double mCalories = 0; PedometerSettings mSettings; Utils mUtils; boolean mIsMetric; boolean mIsRunning; float mStepLength; float mBodyWeight; public CaloriesNotifier(Listener listener, PedometerSettings settings, Utils utils) { mListener = listener; mUtils = utils; mSettings = settings; reloadSettings(); } public void setCalories(float calories) { mCalories = calories; notifyListener(); } public void reloadSettings() { mIsMetric = mSettings.isMetric(); mIsRunning = mSettings.isRunning(); mStepLength = mSettings.getStepLength(); mBodyWeight = mSettings.getBodyWeight(); notifyListener(); } public void resetValues() { mCalories = 0; } public void isMetric(boolean isMetric) { mIsMetric = isMetric; } public void setStepLength(float stepLength) { mStepLength = stepLength; } public void onStep() { if (mIsMetric) { mCalories += (mBodyWeight * (mIsRunning ? METRIC_RUNNING_FACTOR : METRIC_WALKING_FACTOR)) // Distance: * mStepLength // centimeters / 100000.0; // centimeters/kilometer } else { mCalories += (mBodyWeight * (mIsRunning ? IMPERIAL_RUNNING_FACTOR : IMPERIAL_WALKING_FACTOR)) // Distance: * mStepLength // inches / 63360.0; // inches/mile } notifyListener(); } private void notifyListener() { mListener.valueChanged((float)mCalories); } public void passValue() { } public void speak() { if (mSettings.shouldTellCalories()) { if (mCalories > 0) { if(Locale.getDefault().getLanguage().equals("zh")&& Locale.getDefault().getCountry().equals("CN")){ mUtils.say("当前消耗" + (int)mCalories + "卡路里"); }else{ mUtils.say("" + (int)mCalories + " calories burned"); } } } } }2.DistanceNotifier.java
package com.tdc.jibuqi; import java.util.Locale; /** * Calculates and displays the distance walked. * @author Levente Bagi */ public class DistanceNotifier implements StepListener, SpeakingTimer.Listener { public interface Listener { public void valueChanged(float value); public void passValue(); } private Listener mListener; float mDistance = 0; PedometerSettings mSettings; Utils mUtils; boolean mIsMetric; float mStepLength; public DistanceNotifier(Listener listener, PedometerSettings settings, Utils utils) { mListener = listener; mUtils = utils; mSettings = settings; reloadSettings(); } public void setDistance(float distance) { mDistance = distance; notifyListener(); } public void reloadSettings() { mIsMetric = mSettings.isMetric(); mStepLength = mSettings.getStepLength(); notifyListener(); } public void onStep() { //判断步长的距离 if (mIsMetric) {//厘米转换为千米 mDistance += (float)(// kilometers mStepLength // centimeters / 100000.0); // centimeters/kilometer } else {//英寸转换为英里 mDistance += (float)(// miles mStepLength // inches / 63360.0); // inches/mile } notifyListener(); } private void notifyListener() { mListener.valueChanged(mDistance); } public void passValue() { // Callback of StepListener - Not implemented } public void speak() { if (mSettings.shouldTellDistance()) { if (mDistance >= .001f) { if(Locale.getDefault().getLanguage().equals("zh")&&Locale.getDefault().getCountry().equals("CN")){ mUtils.say("当前距离"+("" + (mDistance + 0.000001f)).substring(0, 5) + (mIsMetric ? "公里," : "英里,")); }else{ mUtils.say(("" + (mDistance + 0.000001f)).substring(0, 5) + (mIsMetric ? " kilometers" : " miles")); } } } } }3.PaceNotifier.java
package com.tdc.jibuqi; import java.util.ArrayList; import java.util.Locale; public class PaceNotifier implements StepListener, SpeakingTimer.Listener { public interface Listener { public void paceChanged(int value); public void passValue(); } private ArrayList<Listener> mListeners = new ArrayList<Listener>(); int mCounter = 0; private long mLastStepTime = 0; private long[] mLastStepDeltas = {-1, -1, -1, -1}; private int mLastStepDeltasIndex = 0; private long mPace = 0; PedometerSettings mSettings; Utils mUtils; /** Desired pace, adjusted by the user */ int mDesiredPace; /** Should we speak? */ boolean mShouldTellFasterslower; /** When did the TTS speak last time */ private long mSpokenAt = 0; public PaceNotifier(PedometerSettings settings, Utils utils) { mUtils = utils; mSettings = settings; mDesiredPace = mSettings.getDesiredPace(); reloadSettings(); } public void setPace(int pace) { mPace = pace; int avg = (int)(60*1000.0 / mPace); for (int i = 0; i < mLastStepDeltas.length; i++) { mLastStepDeltas[i] = avg; } notifyListener(); } public void reloadSettings() { mShouldTellFasterslower = mSettings.shouldTellFasterslower() && mSettings.getMaintainOption() == PedometerSettings.M_PACE; notifyListener(); } public void addListener(Listener l) { mListeners.add(l); } public void setDesiredPace(int desiredPace) { mDesiredPace = desiredPace; } public void onStep() { long thisStepTime = System.currentTimeMillis(); mCounter ++; // Calculate pace based on last x steps if (mLastStepTime > 0) { long delta = thisStepTime - mLastStepTime; mLastStepDeltas[mLastStepDeltasIndex] = delta; mLastStepDeltasIndex = (mLastStepDeltasIndex + 1) % mLastStepDeltas.length; long sum = 0; boolean isMeaningfull = true; for (int i = 0; i < mLastStepDeltas.length; i++) { if (mLastStepDeltas[i] < 0) { isMeaningfull = false; break; } sum += mLastStepDeltas[i]; } if (isMeaningfull && sum > 0) { long avg = sum / mLastStepDeltas.length; mPace = 60*1000 / avg; // TODO: remove duplication. This also exists in SpeedNotifier if (mShouldTellFasterslower && mUtils.isSpeakingEnabled()) { if (thisStepTime - mSpokenAt > 3000 && !mUtils.isSpeakingNow()) { float little = 0.10f; float normal = 0.30f; float much = 0.50f; boolean spoken = true; if(Locale.getDefault().getLanguage().equals("zh")&&Locale.getDefault().getCountry().equals("CN")){ if (mPace < mDesiredPace * (1 - much)) { mUtils.say("您的步调很慢!"); } else if (mPace > mDesiredPace * (1 + much)) { mUtils.say("您的步调很快!"); } else if (mPace < mDesiredPace * (1 - normal)) { mUtils.say("您的步调有点慢!"); } else if (mPace > mDesiredPace * (1 + normal)) { mUtils.say("您的步调有点快!"); } else if (mPace < mDesiredPace * (1 - little)) { mUtils.say("您的步调慢!"); } else if (mPace > mDesiredPace * (1 + little)) { mUtils.say("您的步调快!"); }else { spoken = false; } }else{ if (mPace < mDesiredPace * (1 - much)) { mUtils.say("much faster!"); } else if (mPace > mDesiredPace * (1 + much)) { mUtils.say("much slower!"); } else if (mPace < mDesiredPace * (1 - normal)) { mUtils.say("faster!"); } else if (mPace > mDesiredPace * (1 + normal)) { mUtils.say("slower!"); } else if (mPace < mDesiredPace * (1 - little)) { mUtils.say("a little faster!"); } else if (mPace > mDesiredPace * (1 + little)) { mUtils.say("a little slower!"); }else { spoken = false; } } if (spoken) { mSpokenAt = thisStepTime; } } } } else { mPace = -1; } } mLastStepTime = thisStepTime; notifyListener(); } private void notifyListener() { for (Listener listener : mListeners) { listener.paceChanged((int)mPace); } } public void passValue() { // Not used } //----------------------------------------------------- // Speaking public void speak() { if (mSettings.shouldTellPace()) { if (mPace > 0) { if(Locale.getDefault().getLanguage().equals("zh")&&Locale.getDefault().getCountry().equals("CN")){ mUtils.say("当前步速"+mPace + "步每分钟,"); }else{ mUtils.say(mPace + " steps per minute"); } } } } }4.Pedometer.java
package com.tdc.jibuqi; import com.tdc.jibuqi.R; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.preference.PreferenceManager; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; //主Activity public class Pedometer extends Activity { private static final String TAG = "Pedometer"; private SharedPreferences mSettings; private PedometerSettings mPedometerSettings; private Utils mUtils; private TextView mStepValueView; private TextView mPaceValueView; private TextView mDistanceValueView; private TextView mSpeedValueView; private TextView mCaloriesValueView; TextView mDesiredPaceView; private int mStepValue; private int mPaceValue; private float mDistanceValue; private float mSpeedValue; private int mCaloriesValue; private float mDesiredPaceOrSpeed; private int mMaintain; private boolean mIsMetric; private float mMaintainInc; private boolean mQuitting = false; // Set when user selected Quit from menu, can be used by onPause, onStop, onDestroy /** * True, when service is running. */ private boolean mIsRunning; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "[ACTIVITY] onCreate"); super.onCreate(savedInstanceState); mStepValue = 0;//步数 mPaceValue = 0;//步速 setContentView(R.layout.main);//绑定视图 mUtils = Utils.getInstance();//获取Utils这个类 } @Override protected void onStart() { Log.i(TAG, "[ACTIVITY] onStart"); super.onStart(); } @Override protected void onResume() { Log.i(TAG, "[ACTIVITY] onResume"); super.onResume(); //获取配置 mSettings = PreferenceManager.getDefaultSharedPreferences(this); mPedometerSettings = new PedometerSettings(mSettings); mUtils.setSpeak(mSettings.getBoolean("speak", false)); // Read from preferences if the service was running on the last onPause mIsRunning = mPedometerSettings.isServiceRunning(); // Start the service if this is considered to be an application start (last onPause was long ago) if (!mIsRunning && mPedometerSettings.isNewStart()) { startStepService(); bindStepService(); } else if (mIsRunning) { bindStepService(); } mPedometerSettings.clearServiceRunning(); mStepValueView = (TextView) findViewById(R.id.step_value); mPaceValueView = (TextView) findViewById(R.id.pace_value); mDistanceValueView = (TextView) findViewById(R.id.distance_value); mSpeedValueView = (TextView) findViewById(R.id.speed_value); mCaloriesValueView = (TextView) findViewById(R.id.calories_value); mDesiredPaceView = (TextView) findViewById(R.id.desired_pace_value); mIsMetric = mPedometerSettings.isMetric(); ((TextView) findViewById(R.id.distance_units)).setText(getString( mIsMetric ? R.string.kilometers : R.string.miles )); ((TextView) findViewById(R.id.speed_units)).setText(getString( mIsMetric ? R.string.kilometers_per_hour : R.string.miles_per_hour )); mMaintain = mPedometerSettings.getMaintainOption(); ((LinearLayout) this.findViewById(R.id.desired_pace_control)).setVisibility( mMaintain != PedometerSettings.M_NONE ? View.VISIBLE : View.GONE ); if (mMaintain == PedometerSettings.M_PACE) { mMaintainInc = 5f; mDesiredPaceOrSpeed = (float)mPedometerSettings.getDesiredPace(); }else if (mMaintain == PedometerSettings.M_SPEED) { mDesiredPaceOrSpeed = mPedometerSettings.getDesiredSpeed(); mMaintainInc = 0.1f; } Button button1 = (Button) findViewById(R.id.button_desired_pace_lower); button1.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { mDesiredPaceOrSpeed -= mMaintainInc; mDesiredPaceOrSpeed = Math.round(mDesiredPaceOrSpeed * 10) / 10f; displayDesiredPaceOrSpeed(); setDesiredPaceOrSpeed(mDesiredPaceOrSpeed); } }); Button button2 = (Button) findViewById(R.id.button_desired_pace_raise); button2.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { mDesiredPaceOrSpeed += mMaintainInc; mDesiredPaceOrSpeed = Math.round(mDesiredPaceOrSpeed * 10) / 10f; displayDesiredPaceOrSpeed(); setDesiredPaceOrSpeed(mDesiredPaceOrSpeed); } }); if (mMaintain != PedometerSettings.M_NONE) { ((TextView) findViewById(R.id.desired_pace_label)).setText( mMaintain == PedometerSettings.M_PACE ? R.string.desired_pace : R.string.desired_speed ); } displayDesiredPaceOrSpeed(); } private void displayDesiredPaceOrSpeed() { if (mMaintain == PedometerSettings.M_PACE) { mDesiredPaceView.setText("" + (int)mDesiredPaceOrSpeed); } else { mDesiredPaceView.setText("" + mDesiredPaceOrSpeed); } } @Override protected void onPause() { Log.i(TAG, "[ACTIVITY] onPause"); if (mIsRunning) { unbindStepService(); } if (mQuitting) { mPedometerSettings.saveServiceRunningWithNullTimestamp(mIsRunning); } else { mPedometerSettings.saveServiceRunningWithTimestamp(mIsRunning); } super.onPause(); savePaceSetting(); } @Override protected void onStop() { Log.i(TAG, "[ACTIVITY] onStop"); super.onStop(); } protected void onDestroy() { Log.i(TAG, "[ACTIVITY] onDestroy"); super.onDestroy(); } protected void onRestart() { Log.i(TAG, "[ACTIVITY] onRestart"); super.onDestroy(); } private void setDesiredPaceOrSpeed(float desiredPaceOrSpeed) { if (mService != null) { if (mMaintain == PedometerSettings.M_PACE) { mService.setDesiredPace((int)desiredPaceOrSpeed); } else if (mMaintain == PedometerSettings.M_SPEED) { mService.setDesiredSpeed(desiredPaceOrSpeed); } } } private void savePaceSetting() { mPedometerSettings.savePaceOrSpeedSetting(mMaintain, mDesiredPaceOrSpeed); } private StepService mService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mService = ((StepService.StepBinder)service).getService(); mService.registerCallback(mCallback); mService.reloadSettings(); } public void onServiceDisconnected(ComponentName className) { mService = null; } }; private void startStepService() { if (! mIsRunning) { Log.i(TAG, "[SERVICE] Start"); mIsRunning = true; startService(new Intent(Pedometer.this, StepService.class)); } } private void bindStepService() { Log.i(TAG, "[SERVICE] Bind"); bindService(new Intent(Pedometer.this, StepService.class), mConnection, Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND); } private void unbindStepService() { Log.i(TAG, "[SERVICE] Unbind"); unbindService(mConnection); } private void stopStepService() { Log.i(TAG, "[SERVICE] Stop"); if (mService != null) { Log.i(TAG, "[SERVICE] stopService"); stopService(new Intent(Pedometer.this, StepService.class)); } mIsRunning = false; } private void resetValues(boolean updateDisplay) { if (mService != null && mIsRunning) { mService.resetValues(); } else { mStepValueView.setText("0"); mPaceValueView.setText("0"); mDistanceValueView.setText("0"); mSpeedValueView.setText("0"); mCaloriesValueView.setText("0"); SharedPreferences state = getSharedPreferences("state", 0); SharedPreferences.Editor stateEditor = state.edit(); if (updateDisplay) { stateEditor.putInt("steps", 0); stateEditor.putInt("pace", 0); stateEditor.putFloat("distance", 0); stateEditor.putFloat("speed", 0); stateEditor.putFloat("calories", 0); stateEditor.commit(); } } } private static final int MENU_SETTINGS = 8; private static final int MENU_QUIT = 9; private static final int MENU_PAUSE = 1; private static final int MENU_RESUME = 2; private static final int MENU_RESET = 3; /* Creates the menu items */ /*创建menu*/ public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); if (mIsRunning) {//判断程序是否在运行 menu.add(0, MENU_PAUSE, 0, R.string.pause) .setIcon(android.R.drawable.ic_media_pause) .setShortcut('1', 'p'); } else { menu.add(0, MENU_RESUME, 0, R.string.resume) .setIcon(android.R.drawable.ic_media_play) .setShortcut('1', 'p'); } menu.add(0, MENU_RESET, 0, R.string.reset) .setIcon(android.R.drawable.ic_menu_close_clear_cancel) .setShortcut('2', 'r'); menu.add(0, MENU_SETTINGS, 0, R.string.settings) .setIcon(android.R.drawable.ic_menu_preferences) .setShortcut('8', 's') .setIntent(new Intent(this, Settings.class)); menu.add(0, MENU_QUIT, 0, R.string.quit) .setIcon(android.R.drawable.ic_lock_power_off) .setShortcut('9', 'q'); return true; } /* Handles item selections */ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_PAUSE: unbindStepService(); stopStepService(); return true; case MENU_RESUME: startStepService(); bindStepService(); return true; case MENU_RESET: resetValues(true); return true; case MENU_QUIT: resetValues(false); unbindStepService(); stopStepService(); mQuitting = true; finish(); return true; } return false; } // TODO: unite all into 1 type of message private StepService.ICallback mCallback = new StepService.ICallback() { public void stepsChanged(int value) { mHandler.sendMessage(mHandler.obtainMessage(STEPS_MSG, value, 0)); } public void paceChanged(int value) { mHandler.sendMessage(mHandler.obtainMessage(PACE_MSG, value, 0)); } public void distanceChanged(float value) { mHandler.sendMessage(mHandler.obtainMessage(DISTANCE_MSG, (int)(value*1000), 0)); } public void speedChanged(float value) { mHandler.sendMessage(mHandler.obtainMessage(SPEED_MSG, (int)(value*1000), 0)); } public void caloriesChanged(float value) { mHandler.sendMessage(mHandler.obtainMessage(CALORIES_MSG, (int)(value), 0)); } }; private static final int STEPS_MSG = 1; private static final int PACE_MSG = 2; private static final int DISTANCE_MSG = 3; private static final int SPEED_MSG = 4; private static final int CALORIES_MSG = 5; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case STEPS_MSG: mStepValue = (int)msg.arg1; mStepValueView.setText("" + mStepValue); break; case PACE_MSG: mPaceValue = msg.arg1; if (mPaceValue <= 0) { mPaceValueView.setText("0"); } else { mPaceValueView.setText("" + (int)mPaceValue); } break; case DISTANCE_MSG: mDistanceValue = ((int)msg.arg1)/1000f; if (mDistanceValue <= 0) { mDistanceValueView.setText("0"); } else { mDistanceValueView.setText( ("" + (mDistanceValue + 0.000001f)).substring(0, 5) ); } break; case SPEED_MSG: mSpeedValue = ((int)msg.arg1)/1000f; if (mSpeedValue <= 0) { mSpeedValueView.setText("0"); } else { mSpeedValueView.setText( ("" + (mSpeedValue + 0.000001f)).substring(0, 4) ); } break; case CALORIES_MSG: mCaloriesValue = msg.arg1; if (mCaloriesValue <= 0) { mCaloriesValueView.setText("0"); } else { mCaloriesValueView.setText("" + (int)mCaloriesValue); } break; default: super.handleMessage(msg); } } }; }
5.PedometerSettings.java
package com.tdc.jibuqi; import android.content.SharedPreferences; public class PedometerSettings { SharedPreferences mSettings; public static int M_NONE = 1; public static int M_PACE = 2; public static int M_SPEED = 3; public PedometerSettings(SharedPreferences settings) { mSettings = settings; } public boolean isMetric() {//判断距离的单位 return mSettings.getString("units", "metric").equals("metric");//是千米/还是英寸 } public float getStepLength() {//获取步长 try { return Float.valueOf(mSettings.getString("step_length", "70").trim()); } catch (NumberFormatException e) { // TODO: reset value, & notify user somehow return 0f; } } public float getBodyWeight() {//获取体重 try { return Float.valueOf(mSettings.getString("body_weight", "50").trim()); } catch (NumberFormatException e) { // TODO: reset value, & notify user somehow return 0f; } } public boolean isRunning() {//获取运动类型 return mSettings.getString("exercise_type", "running").equals("running"); } //是否设置目标步伐或者速度 public int getMaintainOption() { String p = mSettings.getString("maintain", "none"); return p.equals("none") ? M_NONE : ( p.equals("pace") ? M_PACE : ( p.equals("speed") ? M_SPEED : ( 0))); } //------------------------------------------------------------------- // Desired pace & speed: // these can not be set in the preference activity, only on the main // screen if "maintain" is set to "pace" or "speed" public int getDesiredPace() { return mSettings.getInt("desired_pace", 180); // steps/minute } public float getDesiredSpeed() { return mSettings.getFloat("desired_speed", 4f); // km/h or mph } public void savePaceOrSpeedSetting(int maintain, float desiredPaceOrSpeed) { SharedPreferences.Editor editor = mSettings.edit(); if (maintain == M_PACE) { editor.putInt("desired_pace", (int)desiredPaceOrSpeed); } else if (maintain == M_SPEED) { editor.putFloat("desired_speed", desiredPaceOrSpeed); } editor.commit(); } //------------------------------------------------------------------- // Speaking: public boolean shouldSpeak() { return mSettings.getBoolean("speak", false); } public float getSpeakingInterval() { try { return Float.valueOf(mSettings.getString("speaking_interval", "1")); } catch (NumberFormatException e) { // This could not happen as the value is selected from a list. return 1; } } public boolean shouldTellSteps() { return mSettings.getBoolean("speak", false) && mSettings.getBoolean("tell_steps", false); } public boolean shouldTellPace() { return mSettings.getBoolean("speak", false) && mSettings.getBoolean("tell_pace", false); } public boolean shouldTellDistance() { return mSettings.getBoolean("speak", false) && mSettings.getBoolean("tell_distance", false); } public boolean shouldTellSpeed() { return mSettings.getBoolean("speak", false) && mSettings.getBoolean("tell_speed", false); } public boolean shouldTellCalories() { return mSettings.getBoolean("speak", false) && mSettings.getBoolean("tell_calories", false); } public boolean shouldTellFasterslower() { return mSettings.getBoolean("speak", false) && mSettings.getBoolean("tell_fasterslower", false); } public boolean wakeAggressively() { return mSettings.getString("operation_level", "run_in_background").equals("wake_up"); } public boolean keepScreenOn() { return mSettings.getString("operation_level", "run_in_background").equals("keep_screen_on"); } // // Internal public void saveServiceRunningWithTimestamp(boolean running) { SharedPreferences.Editor editor = mSettings.edit(); editor.putBoolean("service_running", running); editor.putLong("last_seen", Utils.currentTimeInMillis()); editor.commit(); } public void saveServiceRunningWithNullTimestamp(boolean running) { SharedPreferences.Editor editor = mSettings.edit(); editor.putBoolean("service_running", running); editor.putLong("last_seen", 0); editor.commit(); } public void clearServiceRunning() { SharedPreferences.Editor editor = mSettings.edit(); editor.putBoolean("service_running", false); editor.putLong("last_seen", 0); editor.commit(); } public boolean isServiceRunning() { return mSettings.getBoolean("service_running", false); } public boolean isNewStart() { // activity last paused more than 10 minutes ago return mSettings.getLong("last_seen", 0) < Utils.currentTimeInMillis() - 1000*60*10; } }
6.Settings.java
package com.tdc.jibuqi; import com.tdc.jibuqi.R; import android.os.Bundle; import android.preference.PreferenceActivity; public class Settings extends PreferenceActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } }
7.SpeakingTimer
package com.tdc.jibuqi; import java.util.ArrayList; public class SpeakingTimer implements StepListener { PedometerSettings mSettings; Utils mUtils; boolean mShouldSpeak; float mInterval; long mLastSpeakTime; public SpeakingTimer(PedometerSettings settings, Utils utils) { mLastSpeakTime = System.currentTimeMillis(); mSettings = settings; mUtils = utils; reloadSettings(); } public void reloadSettings() { mShouldSpeak = mSettings.shouldSpeak(); mInterval = mSettings.getSpeakingInterval(); } public void onStep() { long now = System.currentTimeMillis(); long delta = now - mLastSpeakTime; if (delta / 60000.0 >= mInterval) { mLastSpeakTime = now; notifyListeners(); } } public void passValue() { // not used } //----------------------------------------------------- // Listener public interface Listener { public void speak(); } private ArrayList<Listener> mListeners = new ArrayList<Listener>(); public void addListener(Listener l) { mListeners.add(l); } public void notifyListeners() { mUtils.ding(); for (Listener listener : mListeners) { listener.speak(); } } //----------------------------------------------------- // Speaking public boolean isSpeaking() { return mUtils.isSpeakingNow(); } }
8.SpeedNotifier.java
package com.tdc.jibuqi; import java.util.Locale; public class SpeedNotifier implements PaceNotifier.Listener, SpeakingTimer.Listener { public interface Listener { public void valueChanged(float value); public void passValue(); } private Listener mListener; int mCounter = 0; float mSpeed = 0; boolean mIsMetric; float mStepLength; PedometerSettings mSettings; Utils mUtils; /** Desired speed, adjusted by the user */ float mDesiredSpeed; /** Should we speak? */ boolean mShouldTellFasterslower; boolean mShouldTellSpeed; /** When did the TTS speak last time */ private long mSpokenAt = 0; public SpeedNotifier(Listener listener, PedometerSettings settings, Utils utils) { mListener = listener; mUtils = utils; mSettings = settings; mDesiredSpeed = mSettings.getDesiredSpeed(); reloadSettings(); } public void setSpeed(float speed) { mSpeed = speed; notifyListener(); } public void reloadSettings() { mIsMetric = mSettings.isMetric(); mStepLength = mSettings.getStepLength(); mShouldTellSpeed = mSettings.shouldTellSpeed(); mShouldTellFasterslower = mSettings.shouldTellFasterslower() && mSettings.getMaintainOption() == PedometerSettings.M_SPEED; notifyListener(); } public void setDesiredSpeed(float desiredSpeed) { mDesiredSpeed = desiredSpeed; } private void notifyListener() { mListener.valueChanged(mSpeed); } public void paceChanged(int value) { if (mIsMetric) { mSpeed = // kilometers / hour value * mStepLength // centimeters / minute / 100000f * 60f; // centimeters/kilometer } else { mSpeed = // miles / hour value * mStepLength // inches / minute / 63360f * 60f; // inches/mile } tellFasterSlower(); notifyListener(); } /** * Say slower/faster, if needed. */ private void tellFasterSlower() { if (mShouldTellFasterslower && mUtils.isSpeakingEnabled()) { long now = System.currentTimeMillis(); if (now - mSpokenAt > 3000 && !mUtils.isSpeakingNow()) { float little = 0.10f; float normal = 0.30f; float much = 0.50f; boolean spoken = true; if(Locale.getDefault().getLanguage().equals("zh")&&Locale.getDefault().getCountry().equals("CN")){ if (mSpeed < mDesiredSpeed * (1 - much)) { mUtils.say("您的速度离您的目标值还很远!"); } else if (mSpeed > mDesiredSpeed * (1 + much)) { mUtils.say("您的速度远远超过了目标速度!"); } else if (mSpeed < mDesiredSpeed * (1 - normal)) { mUtils.say("您的速度离您的目标值还有点远!"); } else if (mSpeed > mDesiredSpeed * (1 + normal)) { mUtils.say("您的速度已经超过了目标速度"); } else if (mSpeed < mDesiredSpeed * (1 - little)) { mUtils.say("您的速度离您的目标值还差一点点!"); } else if (mSpeed > mDesiredSpeed * (1 + little)) { mUtils.say("您的速度刚刚超过了目标速度!"); } else { spoken = false; } }else{ if (mSpeed < mDesiredSpeed * (1 - much)) { mUtils.say("much faster!"); } else if (mSpeed > mDesiredSpeed * (1 + much)) { mUtils.say("much slower!"); } else if (mSpeed < mDesiredSpeed * (1 - normal)) { mUtils.say("faster!"); } else if (mSpeed > mDesiredSpeed * (1 + normal)) { mUtils.say("slower!"); } else if (mSpeed < mDesiredSpeed * (1 - little)) { mUtils.say("a little faster!"); } else if (mSpeed > mDesiredSpeed * (1 + little)) { mUtils.say("a little slower!"); } else { spoken = false; } } if (spoken) { mSpokenAt = now; } } } } public void passValue() { // Not used } public void speak() { if (mSettings.shouldTellSpeed()) { if (mSpeed >= .01f) { if(Locale.getDefault().getLanguage().equals("zh")&&Locale.getDefault().getCountry().equals("CN")){ mUtils.say("当前速度"+("" + (mSpeed + 0.000001f)).substring(0, 4) + (mIsMetric ? "公里每小时" : "英里每小时")); }else{ mUtils.say(("" + (mSpeed + 0.000001f)).substring(0, 4) + (mIsMetric ? " kilometers per hour" : " miles per hour")); } } } } }
9.StepBuzzer
package com.tdc.jibuqi; import android.content.Context; import android.os.Vibrator; public class StepBuzzer implements StepListener { private Context mContext; private Vibrator mVibrator; public StepBuzzer(Context context) { mContext = context; mVibrator = (Vibrator)mContext.getSystemService(Context.VIBRATOR_SERVICE); } public void onStep() { buzz(); } public void passValue() { } private void buzz() { mVibrator.vibrate(50); } }10.StepDetector
package com.tdc.jibuqi; import java.util.ArrayList; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; public class StepDetector implements SensorEventListener { private final static String TAG = "StepDetector"; private float mLimit = 10; private float mLastValues[] = new float[3*2]; private float mScale[] = new float[2]; private float mYOffset; private float mLastDirections[] = new float[3*2]; private float mLastExtremes[][] = { new float[3*2], new float[3*2] }; private float mLastDiff[] = new float[3*2]; private int mLastMatch = -1; private long start,end; private ArrayList<StepListener> mStepListeners = new ArrayList<StepListener>(); public StepDetector() { int h = 480; // TODO: remove this constant mYOffset = h * 0.5f; mScale[0] = - (h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2))); mScale[1] = - (h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX))); } public void setSensitivity(float sensitivity) { mLimit = sensitivity; // 1.97 2.96 4.44 6.66 10.00 15.00 22.50 33.75 50.62 } public void addStepListener(StepListener sl) { mStepListeners.add(sl); } //public void onSensorChanged(int sensor, float[] values) { public void onSensorChanged(SensorEvent event) { Sensor sensor = event.sensor; synchronized (this) { if (sensor.getType() == Sensor.TYPE_ORIENTATION) { } else { int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0; if (j == 1) { float vSum = 0; //System.out.println("x="+event.values[0]+",y="+event.values[1]+",z="+event.values[2]); for (int i=0 ; i<3 ; i++) { final float v = mYOffset + event.values[i] * mScale[j]; vSum += v; } int k = 0; float v = vSum / 3; float direction = (v > mLastValues[k] ? 1 : (v < mLastValues[k] ? -1 : 0)); //System.out.println("direction="+direction+",mLastValues[k]="+mLastValues[k]+", mLastDirections[k]="+mLastDirections[k]); if (direction == - mLastDirections[k]) { // Direction changed int extType = (direction > 0 ? 0 : 1); // minumum or maximum? mLastExtremes[extType][k] = mLastValues[k]; float diff = Math.abs(mLastExtremes[extType][k] - mLastExtremes[1 - extType][k]); //System.out.println("mLimit="+ mLimit+",diff="+diff); if (diff > mLimit) { boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k]*2/3); boolean isPreviousLargeEnough = mLastDiff[k] > (diff/3); boolean isNotContra = (mLastMatch != 1 - extType); if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) { end=System.currentTimeMillis(); //Log.i(TAG, "step"); if(end-start>500){ for (StepListener stepListener : mStepListeners) { stepListener.onStep(); } start=end; mLastMatch = extType; } } else { mLastMatch = -1; } } mLastDiff[k] = diff; } mLastDirections[k] = direction; mLastValues[k] = v; } } } } public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } }
11.StepDisplayer
package com.tdc.jibuqi; import java.util.ArrayList; import java.util.Locale; public class StepDisplayer implements StepListener, SpeakingTimer.Listener { private int mCount = 0; PedometerSettings mSettings; Utils mUtils; public StepDisplayer(PedometerSettings settings, Utils utils) { mUtils = utils; mSettings = settings; notifyListener(); } public void setUtils(Utils utils) { mUtils = utils; } public void setSteps(int steps) { mCount = steps; notifyListener(); } public void onStep() { mCount ++; notifyListener(); } public void reloadSettings() { notifyListener(); } public void passValue() { } //----------------------------------------------------- // Listener public interface Listener { public void stepsChanged(int value); public void passValue(); } private ArrayList<Listener> mListeners = new ArrayList<Listener>(); public void addListener(Listener l) { mListeners.add(l); } public void notifyListener() { for (Listener listener : mListeners) { listener.stepsChanged((int)mCount); } } //----------------------------------------------------- // Speaking public void speak() { if (mSettings.shouldTellSteps()) { if (mCount > 0) { if(Locale.getDefault().getLanguage().equals("zh")&&Locale.getDefault().getCountry().equals("CN")){ mUtils.say("您走了" + mCount + "步"); }else{ mUtils.say("" + mCount + " steps"); } } } } }
12.StepListener
package com.tdc.jibuqi; public interface StepListener { public void onStep(); public void passValue(); }
13.StepService
package com.tdc.jibuqi; import com.tdc.jibuqi.R; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.hardware.Sensor; import android.hardware.SensorManager; import android.os.Binder; import android.os.IBinder; import android.os.PowerManager; import android.preference.PreferenceManager; import android.util.Log; import android.widget.Toast; public class StepService extends Service { private static final String TAG = "name.bagi.levente.pedometer.StepService"; private SharedPreferences mSettings; private PedometerSettings mPedometerSettings; private SharedPreferences mState; private SharedPreferences.Editor mStateEditor; private Utils mUtils; private SensorManager mSensorManager; private Sensor mSensor; private StepDetector mStepDetector; // private StepBuzzer mStepBuzzer; // used for debugging private StepDisplayer mStepDisplayer; private PaceNotifier mPaceNotifier; private DistanceNotifier mDistanceNotifier; private SpeedNotifier mSpeedNotifier; private CaloriesNotifier mCaloriesNotifier; private SpeakingTimer mSpeakingTimer; private PowerManager.WakeLock wakeLock; private NotificationManager mNM; private int mSteps; private int mPace; private float mDistance; private float mSpeed; private float mCalories; /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class StepBinder extends Binder { StepService getService() { return StepService.this; } } @Override public void onCreate() { Log.i(TAG, "[SERVICE] onCreate"); super.onCreate(); mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); showNotification(); // Load settings mSettings = PreferenceManager.getDefaultSharedPreferences(this); mPedometerSettings = new PedometerSettings(mSettings); mState = getSharedPreferences("state", 0); mUtils = Utils.getInstance(); mUtils.setService(this); mUtils.initTTS(); acquireWakeLock(); // Start detecting mStepDetector = new StepDetector(); mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); registerDetector(); // Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver // code be called whenever the phone enters standby mode. IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); registerReceiver(mReceiver, filter); mStepDisplayer = new StepDisplayer(mPedometerSettings, mUtils); mStepDisplayer.setSteps(mSteps = mState.getInt("steps", 0)); mStepDisplayer.addListener(mStepListener); mStepDetector.addStepListener(mStepDisplayer); mPaceNotifier = new PaceNotifier(mPedometerSettings, mUtils); mPaceNotifier.setPace(mPace = mState.getInt("pace", 0)); mPaceNotifier.addListener(mPaceListener); mStepDetector.addStepListener(mPaceNotifier); mDistanceNotifier = new DistanceNotifier(mDistanceListener, mPedometerSettings, mUtils); mDistanceNotifier.setDistance(mDistance = mState.getFloat("distance", 0)); mStepDetector.addStepListener(mDistanceNotifier); mSpeedNotifier = new SpeedNotifier(mSpeedListener, mPedometerSettings, mUtils); mSpeedNotifier.setSpeed(mSpeed = mState.getFloat("speed", 0)); mPaceNotifier.addListener(mSpeedNotifier); mCaloriesNotifier = new CaloriesNotifier(mCaloriesListener, mPedometerSettings, mUtils); mCaloriesNotifier.setCalories(mCalories = mState.getFloat("calories", 0)); mStepDetector.addStepListener(mCaloriesNotifier); mSpeakingTimer = new SpeakingTimer(mPedometerSettings, mUtils); mSpeakingTimer.addListener(mStepDisplayer); mSpeakingTimer.addListener(mPaceNotifier); mSpeakingTimer.addListener(mDistanceNotifier); mSpeakingTimer.addListener(mSpeedNotifier); mSpeakingTimer.addListener(mCaloriesNotifier); mStepDetector.addStepListener(mSpeakingTimer); // Used when debugging: // mStepBuzzer = new StepBuzzer(this); // mStepDetector.addStepListener(mStepBuzzer); // Start voice reloadSettings(); // Tell the user we started. Toast.makeText(this, getText(R.string.started), Toast.LENGTH_SHORT).show(); } @Override public void onStart(Intent intent, int startId) { Log.i(TAG, "[SERVICE] onStart"); super.onStart(intent, startId); } @Override public void onDestroy() { Log.i(TAG, "[SERVICE] onDestroy"); mUtils.shutdownTTS(); // Unregister our receiver. unregisterReceiver(mReceiver); unregisterDetector(); mStateEditor = mState.edit(); mStateEditor.putInt("steps", mSteps); mStateEditor.putInt("pace", mPace); mStateEditor.putFloat("distance", mDistance); mStateEditor.putFloat("speed", mSpeed); mStateEditor.putFloat("calories", mCalories); mStateEditor.commit(); mNM.cancel(R.string.app_name); wakeLock.release(); super.onDestroy(); // Stop detecting mSensorManager.unregisterListener(mStepDetector); // Tell the user we stopped. Toast.makeText(this, getText(R.string.stopped), Toast.LENGTH_SHORT).show(); } private void registerDetector() { mSensor = mSensorManager.getDefaultSensor( Sensor.TYPE_ACCELEROMETER /*| Sensor.TYPE_MAGNETIC_FIELD | Sensor.TYPE_ORIENTATION*/); mSensorManager.registerListener(mStepDetector, mSensor, SensorManager.SENSOR_DELAY_FASTEST); } private void unregisterDetector() { mSensorManager.unregisterListener(mStepDetector); } @Override public IBinder onBind(Intent intent) { Log.i(TAG, "[SERVICE] onBind"); return mBinder; } /** * Receives messages from activity. */ private final IBinder mBinder = new StepBinder(); public interface ICallback { public void stepsChanged(int value); public void paceChanged(int value); public void distanceChanged(float value); public void speedChanged(float value); public void caloriesChanged(float value); } private ICallback mCallback; public void registerCallback(ICallback cb) { mCallback = cb; //mStepDisplayer.passValue(); //mPaceListener.passValue(); } private int mDesiredPace; private float mDesiredSpeed; /** * Called by activity to pass the desired pace value, * whenever it is modified by the user. * @param desiredPace */ public void setDesiredPace(int desiredPace) { mDesiredPace = desiredPace; if (mPaceNotifier != null) { mPaceNotifier.setDesiredPace(mDesiredPace); } } /** * Called by activity to pass the desired speed value, * whenever it is modified by the user. * @param desiredSpeed */ public void setDesiredSpeed(float desiredSpeed) { mDesiredSpeed = desiredSpeed; if (mSpeedNotifier != null) { mSpeedNotifier.setDesiredSpeed(mDesiredSpeed); } } public void reloadSettings() { mSettings = PreferenceManager.getDefaultSharedPreferences(this); if (mStepDetector != null) { mStepDetector.setSensitivity( Float.valueOf(mSettings.getString("sensitivity", "10")) ); } if (mStepDisplayer != null) mStepDisplayer.reloadSettings(); if (mPaceNotifier != null) mPaceNotifier.reloadSettings(); if (mDistanceNotifier != null) mDistanceNotifier.reloadSettings(); if (mSpeedNotifier != null) mSpeedNotifier.reloadSettings(); if (mCaloriesNotifier != null) mCaloriesNotifier.reloadSettings(); if (mSpeakingTimer != null) mSpeakingTimer.reloadSettings(); } public void resetValues() { mStepDisplayer.setSteps(0); mPaceNotifier.setPace(0); mDistanceNotifier.setDistance(0); mSpeedNotifier.setSpeed(0); mCaloriesNotifier.setCalories(0); } /** * Forwards pace values from PaceNotifier to the activity. */ private StepDisplayer.Listener mStepListener = new StepDisplayer.Listener() { public void stepsChanged(int value) { mSteps = value; passValue(); } public void passValue() { if (mCallback != null) { mCallback.stepsChanged(mSteps); } } }; /** * Forwards pace values from PaceNotifier to the activity. */ private PaceNotifier.Listener mPaceListener = new PaceNotifier.Listener() { public void paceChanged(int value) { mPace = value; passValue(); } public void passValue() { if (mCallback != null) { mCallback.paceChanged(mPace); } } }; /** * Forwards distance values from DistanceNotifier to the activity. */ private DistanceNotifier.Listener mDistanceListener = new DistanceNotifier.Listener() { public void valueChanged(float value) { mDistance = value; passValue(); } public void passValue() { if (mCallback != null) { mCallback.distanceChanged(mDistance); } } }; /** * Forwards speed values from SpeedNotifier to the activity. */ private SpeedNotifier.Listener mSpeedListener = new SpeedNotifier.Listener() { public void valueChanged(float value) { mSpeed = value; passValue(); } public void passValue() { if (mCallback != null) { mCallback.speedChanged(mSpeed); } } }; /** * Forwards calories values from CaloriesNotifier to the activity. */ private CaloriesNotifier.Listener mCaloriesListener = new CaloriesNotifier.Listener() { public void valueChanged(float value) { mCalories = value; passValue(); } public void passValue() { if (mCallback != null) { mCallback.caloriesChanged(mCalories); } } }; /** * Show a notification while this service is running. */ private void showNotification() { CharSequence text = getText(R.string.app_name); Notification notification = new Notification(R.drawable.ic_notification, null, System.currentTimeMillis()); notification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; Intent pedometerIntent = new Intent(); pedometerIntent.setComponent(new ComponentName(this, Pedometer.class)); pedometerIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, pedometerIntent, 0); notification.setLatestEventInfo(this, text, getText(R.string.notification_subtitle), contentIntent); mNM.notify(R.string.app_name, notification); } // BroadcastReceiver for handling ACTION_SCREEN_OFF. private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Check action just to be on the safe side. if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { // Unregisters the listener and registers it again. StepService.this.unregisterDetector(); StepService.this.registerDetector(); if (mPedometerSettings.wakeAggressively()) { wakeLock.release(); acquireWakeLock(); } } } }; private void acquireWakeLock() { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); int wakeFlags; if (mPedometerSettings.wakeAggressively()) { wakeFlags = PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP; } else if (mPedometerSettings.keepScreenOn()) { wakeFlags = PowerManager.SCREEN_DIM_WAKE_LOCK; } else { wakeFlags = PowerManager.PARTIAL_WAKE_LOCK; } wakeLock = pm.newWakeLock(wakeFlags, TAG); wakeLock.acquire(); } }
14.Utils
package com.tdc.jibuqi; import java.util.Locale; import android.app.Service; import android.speech.tts.TextToSpeech; import android.text.format.Time; import android.util.Log; public class Utils implements TextToSpeech.OnInitListener { private static final String TAG = "Utils"; private Service mService; private static Utils instance = null; private Utils() { } public static Utils getInstance() { if (instance == null) { instance = new Utils(); } return instance; } public void setService(Service service) { mService = service; } /********** SPEAKING **********/ private TextToSpeech mTts; private boolean mSpeak = false; private boolean mSpeakingEngineAvailable = false; public void initTTS() { // Initialize text-to-speech. This is an asynchronous operation. // The OnInitListener (second argument) is called after initialization completes. Log.i(TAG, "Initializing TextToSpeech..."); mTts = new TextToSpeech(mService,this); } public void shutdownTTS() { Log.i(TAG, "Shutting Down TextToSpeech..."); mSpeakingEngineAvailable = false; mTts.shutdown(); Log.i(TAG, "TextToSpeech Shut Down."); } public void say(String text) { if (mSpeak && mSpeakingEngineAvailable) { mTts.speak(text, TextToSpeech.QUEUE_ADD, // Drop all pending entries in the playback queue. null); } } // Implements TextToSpeech.OnInitListener. public void onInit(int status) { // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR. if (status == TextToSpeech.SUCCESS) { int result; if(Locale.getDefault().getLanguage().equals("zh")&& Locale.getDefault().getCountry().equals("CN")){ result = mTts.setLanguage(Locale.CHINESE); }else{ result = mTts.setLanguage(Locale.US); } if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { // Language data is missing or the language is not supported. Log.e(TAG, "Language is not available."); } else { Log.i(TAG, "TextToSpeech Initialized."); mSpeakingEngineAvailable = true; } } else { // Initialization failed. Log.e(TAG, "Could not initialize TextToSpeech."); } } public void setSpeak(boolean speak) { mSpeak = speak; } public boolean isSpeakingEnabled() { return mSpeak; } public boolean isSpeakingNow() { return mTts.isSpeaking(); } public void ding() { } /********** Time **********/ public static long currentTimeInMillis() { Time time = new Time(); time.setToNow(); return time.toMillis(false); } }
15.com.tdc.jibuqi.preferences.BodyWeightPreference
package com.tdc.jibuqi.preferences; import com.tdc.jibuqi.R; import android.content.Context; import android.preference.EditTextPreference; import android.util.AttributeSet; public class BodyWeightPreference extends EditMeasurementPreference { public BodyWeightPreference(Context context) { super(context); } public BodyWeightPreference(Context context, AttributeSet attr) { super(context, attr); } public BodyWeightPreference(Context context, AttributeSet attr, int defStyle) { super(context, attr, defStyle); } protected void initPreferenceDetails() { mTitleResource = R.string.body_weight_setting_title; mMetricUnitsResource = R.string.kilograms; mImperialUnitsResource = R.string.pounds; } }
16.com.tdc.jibuqi.preferences.EditMeasurementPreference
package com.tdc.jibuqi.preferences; import android.content.Context; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.PreferenceManager; import android.text.InputType; import android.util.AttributeSet; import android.view.View; import android.widget.EditText; abstract public class EditMeasurementPreference extends EditTextPreference { boolean mIsMetric; protected int mTitleResource; protected int mMetricUnitsResource; protected int mImperialUnitsResource; public EditMeasurementPreference(Context context) { super(context); initPreferenceDetails(); } public EditMeasurementPreference(Context context, AttributeSet attr) { super(context, attr); initPreferenceDetails(); } public EditMeasurementPreference(Context context, AttributeSet attr, int defStyle) { super(context, attr, defStyle); initPreferenceDetails(); } abstract protected void initPreferenceDetails(); protected void showDialog(Bundle state) { mIsMetric = PreferenceManager.getDefaultSharedPreferences(getContext()).getString("units", "metric").equals("metric"); setDialogTitle( getContext().getString(mTitleResource) + " (" + getContext().getString( mIsMetric ? mMetricUnitsResource : mImperialUnitsResource) + ")" ); try { Float.valueOf(getText()); } catch (Exception e) { setText("70"); } super.showDialog(state); } protected void onAddEditTextToDialogView (View dialogView, EditText editText) { editText.setRawInputType( InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); super.onAddEditTextToDialogView(dialogView, editText); } public void onDialogClosed(boolean positiveResult) { if (positiveResult) { try { Float.valueOf(((CharSequence)(getEditText().getText())).toString()); } catch (NumberFormatException e) { this.showDialog(null); return; } } super.onDialogClosed(positiveResult); } }
17.com.tdc.jibuqi.preferences.StepLengthPreference
package com.tdc.jibuqi.preferences; import com.tdc.jibuqi.R; import android.content.Context; import android.preference.EditTextPreference; import android.util.AttributeSet; public class StepLengthPreference extends EditMeasurementPreference { public StepLengthPreference(Context context) { super(context); } public StepLengthPreference(Context context, AttributeSet attr) { super(context, attr); } public StepLengthPreference(Context context, AttributeSet attr, int defStyle) { super(context, attr, defStyle); } protected void initPreferenceDetails() { mTitleResource = R.string.step_length_setting_title; mMetricUnitsResource = R.string.centimeters; mImperialUnitsResource = R.string.inches; } }
18.layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="@dimen/margin" android:background="@color/screen_background"> <LinearLayout android:id="@+id/row_1" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="@dimen/row_spacing"> <LinearLayout android:id="@+id/box_steps" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:paddingRight="@dimen/margin" android:layout_weight="1"> <TextView android:id="@+id/step_value" android:textSize="@dimen/value" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:background="@color/display_background" android:paddingLeft="@dimen/padding" android:paddingRight="@dimen/padding" android:paddingTop="@dimen/padding" android:text=""/> <TextView android:id="@+id/step_units" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="@dimen/units" android:text="@string/steps" android:background="@color/display_background" android:paddingBottom="@dimen/padding"/> </LinearLayout> <LinearLayout android:id="@+id/box_distance" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:layout_weight="1"> <TextView android:id="@+id/distance_value" android:textSize="@dimen/value" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:background="@color/display_background" android:paddingTop="@dimen/padding" android:paddingRight="@dimen/padding" android:paddingLeft="@dimen/padding" android:text=""/> <TextView android:id="@+id/distance_units" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="@dimen/units" android:text="@string/kilometers" android:background="@color/display_background" android:paddingBottom="@dimen/padding"/> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/row_2" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="@dimen/row_spacing"> <LinearLayout android:id="@+id/box_pace" android:orientation="vertical" android:layout_height="wrap_content" android:paddingRight="@dimen/margin" android:layout_width="fill_parent" android:layout_weight="1"> <TextView android:id="@+id/pace_value" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/display_background" android:textSize="@dimen/small_value" android:paddingLeft="@dimen/padding" android:paddingRight="@dimen/padding" android:paddingTop="@dimen/padding" android:text=""/> <TextView android:id="@+id/pace_units" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="@dimen/units" android:text="@string/steps_per_minute" android:paddingBottom="@dimen/padding" android:background="@color/display_background"/> </LinearLayout> <LinearLayout android:id="@+id/box_speed" android:orientation="vertical" android:paddingRight="@dimen/margin" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1"> <TextView android:id="@+id/speed_value" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/display_background" android:textSize="@dimen/small_value" android:paddingLeft="@dimen/padding" android:paddingRight="@dimen/padding" android:paddingTop="@dimen/padding" android:text=""/> <TextView android:id="@+id/speed_units" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="@dimen/units" android:text="@string/kilometers_per_hour" android:paddingBottom="@dimen/padding" android:background="@color/display_background"/> </LinearLayout> <LinearLayout android:id="@+id/box_calories" android:orientation="vertical" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1"> <TextView android:id="@+id/calories_value" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/display_background" android:textSize="@dimen/small_value" android:paddingLeft="@dimen/padding" android:paddingRight="@dimen/padding" android:paddingTop="@dimen/padding" android:text=""/> <TextView android:id="@+id/calories_units" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="@dimen/units" android:text="@string/calories_burned" android:paddingBottom="@dimen/padding" android:background="@color/display_background"/> </LinearLayout> </LinearLayout> <!-- Desired pace/speed row --> <LinearLayout android:id="@+id/desired_pace_control" android:paddingTop="@dimen/row_spacing" android:gravity="center_horizontal" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"> <!-- Button "-", for decrementing desired pace/speed --> <Button android:id="@+id/button_desired_pace_lower" android:text="-" android:textSize="@dimen/button_sign" android:layout_width="@dimen/button" android:layout_height="@dimen/button"/> <!-- Container for desired pace/speed --> <LinearLayout android:gravity="center_horizontal" android:orientation="vertical" android:layout_width="@dimen/desired_pace_width" android:layout_height="wrap_content"> <TextView android:id="@+id/desired_pace_label" android:gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/desired_pace" android:textSize="@dimen/desired_pace_label"/> <!-- Current desired pace/speed --> <TextView android:id="@+id/desired_pace_value" android:gravity="center_horizontal" android:textSize="@dimen/desired_pace" android:layout_width="@dimen/desired_pace_width" android:layout_height="wrap_content"/> </LinearLayout> <!-- Button "+", for incrementing desired pace/speed --> <Button android:id="@+id/button_desired_pace_raise" android:text="+" android:textSize="@dimen/button_sign" android:layout_width="@dimen/button" android:layout_height="@dimen/button"/> </LinearLayout> </LinearLayout>
19.arrays.xml
<resources> <string-array name="sensitivity_preference"> <item>@string/extra_high</item> <item>@string/very_high</item> <item>@string/high</item> <item>@string/higher</item> <item>@string/medium</item> <item>@string/lower</item> <item>@string/low</item> <item>@string/very_low</item> <item>@string/extra_low</item> </string-array> <string-array name="sensitivity_preference_values"> <item>1.9753</item> <item>2.9630</item> <item>4.4444</item><!-- 10 * 1.5^(-2) --> <item>6.6667</item><!-- 10 * 1.5^(-1) --> <item>10</item> <item>15</item><!-- 10 * 1.5 --> <item>22.5</item><!-- 10 * 1.5^2 --> <item>33.75</item> <item>50.625</item> </string-array> <string-array name="operation_level_preference"> <item>@string/run_in_background</item> <item>@string/keep_screen_on</item> <item>@string/wake_up</item> </string-array> <string-array name="operation_level_preference_values"> <item>run_in_background</item> <item>keep_screen_on</item> <item>wake_up</item> </string-array> <string-array name="units_preference"> <item>@string/units_metric</item> <item>@string/units_imperial</item> </string-array> <string-array name="units_preference_values"> <item>metric</item> <item>imperial</item> </string-array> <string-array name="exercise_type_preference"> <item>@string/exercise_type_running</item> <item>@string/exercise_type_walking</item> </string-array> <string-array name="exercise_type_preference_values"> <item>running</item> <item>walking</item> </string-array> <string-array name="maintain_preference"> <item>@string/maintain_nothing</item> <item>@string/maintain_pace</item> <item>@string/maintain_speed</item> </string-array> <string-array name="maintain_preference_values"> <item>none</item> <item>pace</item> <item>speed</item> </string-array> <string-array name="speaking_interval_preference"> <item>@string/interval_15_seconds</item> <item>@string/interval_30_seconds</item> <item>@string/interval_1_minute</item> <item>@string/interval_2_minutes</item> <item>@string/interval_5_minutes</item> <item>@string/interval_10_minutes</item> </string-array> <string-array name="speaking_interval_preference_values"> <item>0.25</item> <item>0.5</item> <item>1</item> <item>2</item> <item>5</item> <item>10</item> </string-array> </resources>
20.colors.xml
<resources> <color name="screen_background">#333</color> <color name="display_background">#000</color> </resources>
21.dimens.xml
<resources> <dimen name="large_half">240px</dimen> <dimen name="value">40sp</dimen> <dimen name="small_value">40sp</dimen> <!-- <dimen name="step_count">30sp</dimen> --> <dimen name="units">16sp</dimen> <dimen name="desired_pace">30sp</dimen> <dimen name="desired_pace_label">18sp</dimen> <dimen name="desired_pace_width">150sp</dimen> <dimen name="button">60sp</dimen> <dimen name="button_sign">30sp</dimen> <dimen name="margin">6px</dimen> <dimen name="padding">5px</dimen> <dimen name="row_spacing">6px</dimen> </resources>
22.strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Pedometer</string> <string name="notification_subtitle">Counting your steps</string> <string name="started">Pedometer started.</string> <string name="stopped">Pedometer stopped.</string> <string name="steps">steps</string> <string name="kilometers">kilometers</string> <string name="miles">miles</string> <string name="steps_per_minute">steps / minute</string> <string name="kilometers_per_hour">kilometers / hour</string> <string name="miles_per_hour">miles / hour</string> <string name="calories_burned">calories burned</string> <string name="centimeters">centimeters</string> <string name="inches">inches</string> <string name="kilograms">kilograms</string> <string name="pounds">pounds</string> <string name="desired_pace">Desired pace:</string> <string name="desired_speed">Desired speed:</string> <string name="pause">Pause</string> <string name="resume">Resume</string> <string name="reset">Reset</string> <!-- Settings --> <string name="settings">Settings</string> <string name="activity_settings">Pedometer Settings</string> <string name="steps_settings_title">Basic Settings</string> <string name="sensitivity_setting">Sensitivity</string> <string name="sensitivity_setting_details">Calibrate the step detector</string> <string name="sensitivity_setting_title">Select sensitivity level</string> <string name="extra_high">extra high</string> <string name="very_high">very high</string> <string name="high">high</string> <string name="higher">higher</string> <string name="medium">medium</string> <string name="lower">lower</string> <string name="low">low</string> <string name="very_low">very low</string> <string name="extra_low">extra low</string> <string name="operation_level_setting">Operational level</string> <string name="operation_level_setting_details">Some OS versions prevent using sensors when the screen is off; set the level that works for you</string> <string name="operation_level_setting_title">Select operational level</string> <string name="run_in_background">Normal (just try running in background)</string> <string name="keep_screen_on">Screen on (keep screen dim)</string> <string name="wake_up">Aggressive (wake up when I turn screen off)</string> <string name="units_setting">Units</string> <string name="units_setting_details">Imperial or metric units</string> <string name="units_setting_title">Choose your units</string> <string name="units_metric">metric (kilometers)</string> <string name="units_imperial">imperial (miles)</string> <string name="step_length_setting">Step length</string> <string name="step_length_setting_details">For distance, speed & calorie calculation</string> <string name="step_length_setting_title">Enter your step length</string> <string name="body_weight_setting">Body weight</string> <string name="body_weight_setting_details">For calorie calculation</string> <string name="body_weight_setting_title">Enter your body weight</string> <string name="exercise_type_setting">Exercise type</string> <string name="exercise_type_setting_details">For calorie calculation</string> <string name="exercise_type_setting_title">Choose exercise type</string> <string name="exercise_type_running">running</string> <string name="exercise_type_walking">walking</string> <string name="maintain_setting">Maintain pace/speed</string> <string name="maintain_setting_details">Maintaining a desired a pace/speed</string> <string name="maintain_setting_title">Maintain:</string> <string name="maintain_nothing">nothing</string> <string name="maintain_pace">pace</string> <string name="maintain_speed">speed</string> <string name="voice_settings_title">Voice</string> <string name="voice_setting">Speak</string> <string name="voice_setting_details">Enable/disable voice notification</string> <string name="speaking_interval_setting">Interval</string> <string name="speaking_interval_setting_details">Voice notification interval</string> <string name="interval_15_seconds">15 seconds</string> <string name="interval_30_seconds">30 seconds</string> <string name="interval_1_minute">1 minute</string> <string name="interval_2_minutes">2 minutes</string> <string name="interval_5_minutes">5 minutes</string> <string name="interval_10_minutes">10 minutes</string> <string name="tell_what">What to tell</string> <string name="tell_steps_setting">Steps</string> <string name="tell_steps_setting_details"></string> <string name="tell_pace_setting">Pace</string> <string name="tell_pace_setting_details">steps / minute</string> <string name="tell_distance_setting">Distance</string> <string name="tell_distance_setting_details">kilometers or miles</string> <string name="tell_speed_setting">Speed</string> <string name="tell_speed_setting_details">km/h or mph</string> <string name="tell_calories_setting">Calories burned</string> <string name="tell_calories_setting_details"></string> <string name="tell_fasterslower_setting">Faster/slower</string> <string name="tell_fasterslower_setting_details">Helps you maintain your desired pace or speed (interval doesn\'t apply)</string> <string name="incorrect_step_length">Incorrect step length format! Go to the Settings to change it!</string> <string name="quit">Quit</string> </resources>
23.styles.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="MyStyle" parent="android:Theme.Holo"> <item name="android:windowFullscreen">true</item> <item name="android:windowNoTitle">false</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowShowWallpaper">false</item> </style> </resources>
24.中文strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">计步器</string> <string name="notification_subtitle">正在计步中</string> <string name="started">计步器开始</string> <string name="stopped">计步器停止</string> <string name="steps">步数</string> <string name="kilometers">公里</string> <string name="miles">英里</string> <string name="steps_per_minute">步/分钟</string> <string name="kilometers_per_hour">公里/小时</string> <string name="miles_per_hour">英里/小时</string> <string name="calories_burned">消耗卡路里</string> <string name="centimeters">厘米</string> <string name="inches">英寸</string> <string name="kilograms">千克</string> <string name="pounds">英镑</string> <string name="desired_pace">设置目标步伐</string> <string name="desired_speed">设置目标速度</string> <string name="pause">暂停</string> <string name="resume">继续</string> <string name="reset">重置</string> <!-- Settings --> <string name="settings">设置</string> <string name="activity_settings">计步器设置</string> <string name="steps_settings_title">基本设置</string> <string name="sensitivity_setting">灵敏度</string> <string name="sensitivity_setting_details">校准步骤检测器</string> <string name="sensitivity_setting_title">选择敏感水平</string> <string name="extra_high">超高</string> <string name="very_high">非常高</string> <string name="high">很高</string> <string name="higher">比较高</string> <string name="medium">一般</string> <string name="lower">低</string> <string name="low">比较低</string> <string name="very_low">非常低</string> <string name="extra_low">超低</string> <string name="operation_level_setting">运行模式</string> <string name="operation_level_setting_details">当屏幕关闭的时候,操作系统可能会关闭一些传感器,为了程序正常运行,需要您设置合适的模式</string> <string name="operation_level_setting_title">选择运行模式</string> <string name="run_in_background">CPU保持运行,屏幕和按键背光灯关闭</string> <string name="keep_screen_on">CPU保持运行,屏幕变暗,按键背光灯关闭</string> <string name="wake_up">CPU保持运行,屏幕变暗,按键背光灯关闭,并立即生效</string> <string name="units_setting">单位</string> <string name="units_setting_details">英制或公制单位</string> <string name="units_setting_title">选择你的单位</string> <string name="units_metric">公里</string> <string name="units_imperial">英寸</string> <string name="step_length_setting">步长</string> <string name="step_length_setting_details">用于计算距离</string> <string name="step_length_setting_title">输入您的步长</string> <string name="body_weight_setting">体重</string> <string name="body_weight_setting_details">用于计算热量</string> <string name="body_weight_setting_title">输入您的体重</string> <string name="exercise_type_setting">运动方式</string> <string name="exercise_type_setting_details">用于计算热量</string> <string name="exercise_type_setting_title">选择运动方式</string> <string name="exercise_type_running">跑步</string> <string name="exercise_type_walking">走路</string> <string name="maintain_setting">目标步伐/速度</string> <string name="maintain_setting_details">设置运动时目标步伐或者目标速度</string> <string name="maintain_setting_title">设置</string> <string name="maintain_nothing">不设置</string> <string name="maintain_pace">步伐</string> <string name="maintain_speed">速度</string> <string name="voice_settings_title">声音</string> <string name="voice_setting">讲话</string> <string name="voice_setting_details">启用/禁用语音通知</string> <string name="speaking_interval_setting">间隔</string> <string name="speaking_interval_setting_details">语音通知间隔时间</string> <string name="interval_15_seconds">15秒</string> <string name="interval_30_seconds">30秒</string> <string name="interval_1_minute">1分钟</string> <string name="interval_2_minutes">2分钟</string> <string name="interval_5_minutes">5分钟</string> <string name="interval_10_minutes">10分钟</string> <string name="tell_what">说话内容</string> <string name="tell_steps_setting">步数</string> <string name="tell_steps_setting_details"></string> <string name="tell_pace_setting">步伐</string> <string name="tell_pace_setting_details">步/分钟</string> <string name="tell_distance_setting">距离</string> <string name="tell_distance_setting_details">公里或者英里</string> <string name="tell_speed_setting">速度</string> <string name="tell_speed_setting_details">公里每小时或者米每小时</string> <string name="tell_calories_setting">消耗卡路里</string> <string name="tell_calories_setting_details"></string> <string name="tell_fasterslower_setting">快/慢</string> <string name="tell_fasterslower_setting_details">有助于你保持所需的步伐或速度(间隔不适用)</string> <string name="incorrect_step_length">不正确的步骤长度格式,请重新设置!</string> <string name="quit">退出</string> </resources>
相关文章推荐
- web前端讲解,jQuery之jQuery过滤器(二)内容过滤器
- 简述 synchronized 和 java.util.concurrent.locks.Lock 的异同 ?
- 使用block的一些注意点
- 在Ubuntu 12.04LTS系统中安装jdk和配置tomcat服务器
- 合并表格(Table)单元格
- 从通讯聊计算机
- 自定导航控制器
- 统计字符串的某一子串在字符串中的出现次数(C语言实现)
- 2015年16个最佳的免费响应式HTML5框架
- 测试keepalived备备模式的主从切换过程
- 张德芬《遇见未知的自己》--书评加读书笔记
- html jquery 相册资源搜集
- iOS代码适配(2)
- 被hao123恶意绑定了主页解决办法
- 用mac自带的safari浏览器下载excel文件后面自带了.exe后缀
- http状态码
- GRE写作满分:模仿范文
- python win7(64位)环境配置以及相关工具包的安装
- PCAP文件格式分析(做抓包软件之必备)
- Java SSH 集成框架开发中的错误解决