1.CaloriesNotifier.java
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 mListeners = new ArrayList();
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);
}
}
};
}
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;
}
}
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);
}
}
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 mListeners = new ArrayList();
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();
}
}
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"));
}
}
}
}
}
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 mStepListeners = new ArrayList();
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
}
}
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 mListeners = new ArrayList();
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");
}
}
}
}
}
package com.tdc.jibuqi;
public interface StepListener {
public void onStep();
public void passValue();
}
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();
}
}
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);
}
}
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;
}
}
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);
}
}
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;
}
}
- @string/extra_high
- @string/very_high
- @string/high
- @string/higher
- @string/medium
- @string/lower
- @string/low
- @string/very_low
- @string/extra_low
- 1.9753
- 2.9630
- 4.4444
- 6.6667
- 10
- 15
- 22.5
- 33.75
- 50.625
- @string/run_in_background
- @string/keep_screen_on
- @string/wake_up
- run_in_background
- keep_screen_on
- wake_up
- @string/units_metric
- @string/units_imperial
- metric
- imperial
- @string/exercise_type_running
- @string/exercise_type_walking
- running
- walking
- @string/maintain_nothing
- @string/maintain_pace
- @string/maintain_speed
- none
- pace
- speed
- @string/interval_15_seconds
- @string/interval_30_seconds
- @string/interval_1_minute
- @string/interval_2_minutes
- @string/interval_5_minutes
- @string/interval_10_minutes
- 0.25
- 0.5
- 1
- 2
- 5
- 10
#333
#000
240px
40sp
40sp
16sp
30sp
18sp
150sp
60sp
30sp
6px
5px
6px
Pedometer
Counting your steps
Pedometer started.
Pedometer stopped.
steps
kilometers
miles
steps / minute
kilometers / hour
miles / hour
calories burned
centimeters
inches
kilograms
pounds
Desired pace:
Desired speed:
Pause
Resume
Reset
Settings
Pedometer Settings
Basic Settings
Sensitivity
Calibrate the step detector
Select sensitivity level
extra high
very high
high
higher
medium
lower
low
very low
extra low
Operational level
Some OS versions prevent using sensors when the screen is off; set the level that works for you
Select operational level
Normal (just try running in background)
Screen on (keep screen dim)
Aggressive (wake up when I turn screen off)
Units
Imperial or metric units
Choose your units
metric (kilometers)
imperial (miles)
Step length
For distance, speed & calorie calculation
Enter your step length
Body weight
For calorie calculation
Enter your body weight
Exercise type
For calorie calculation
Choose exercise type
running
walking
Maintain pace/speed
Maintaining a desired a pace/speed
Maintain:
nothing
pace
speed
Voice
Speak
Enable/disable voice notification
Interval
Voice notification interval
15 seconds
30 seconds
1 minute
2 minutes
5 minutes
10 minutes
What to tell
Steps
Pace
steps / minute
Distance
kilometers or miles
Speed
km/h or mph
Calories burned
Faster/slower
Helps you maintain your desired pace or speed (interval doesn\'t apply)
Incorrect step length format! Go to the Settings to change it!
Quit
计步器
正在计步中
计步器开始
计步器停止
步数
公里
英里
步/分钟
公里/小时
英里/小时
消耗卡路里
厘米
英寸
千克
英镑
设置目标步伐
设置目标速度
暂停
继续
重置
设置
计步器设置
基本设置
灵敏度
校准步骤检测器
选择敏感水平
超高
非常高
很高
比较高
一般
低
比较低
非常低
超低
运行模式
当屏幕关闭的时候,操作系统可能会关闭一些传感器,为了程序正常运行,需要您设置合适的模式
选择运行模式
CPU保持运行,屏幕和按键背光灯关闭
CPU保持运行,屏幕变暗,按键背光灯关闭
CPU保持运行,屏幕变暗,按键背光灯关闭,并立即生效
单位
英制或公制单位
选择你的单位
公里
英寸
步长
用于计算距离
输入您的步长
体重
用于计算热量
输入您的体重
运动方式
用于计算热量
选择运动方式
跑步
走路
目标步伐/速度
设置运动时目标步伐或者目标速度
设置
不设置
步伐
速度
声音
讲话
启用/禁用语音通知
间隔
语音通知间隔时间
15秒
30秒
1分钟
2分钟
5分钟
10分钟
说话内容
步数
步伐
步/分钟
距离
公里或者英里
速度
公里每小时或者米每小时
消耗卡路里
快/慢
有助于你保持所需的步伐或速度(间隔不适用)
不正确的步骤长度格式,请重新设置!
退出