Android传感器计步器

利用加速度传感器计算步长——个人猜想        前几天写了一篇关于如何记步的博客之后,我就在思考怎么样利用手机的传感器来计算步长呢?和记步不一样,步长是一个相对比较精确的值,通过手机端那个不靠谱的加速度传感器真的有办法计算步长吗?        看了几篇利用GPS计算步长方法,大概就是现在我们用的一些运动软件的算法了,先利用不太精确的GPS画出运动轨迹,计算出轨迹的长度,再除上运动步数,就是步长了。当然其中会运用到很多辅助算法来... 阅读详情

暑假里做了一个安卓计步器,不依靠GPS,也不用联网,只依靠重力加速度传感器和三轴磁力传感器,就可以实现记录步数和记录行走轨迹。我还加入了摇一摇切歌的功能,享受运动的乐趣~~

发布的apk可以在这里下载:pan.baidu.com/s/1i3gw3sh (打算以后完备了再发布到应用市场,所以欢迎大家吐槽评论)

这个项目只用了三天时间(作为自己的第一个安卓作品,我觉得还是很快的~~),当时完全是被deadline给逼出来的。老师对这个项目赞不绝口,觉得我一个正在上预科的孩子,学校里C语言还没有开课,就能自己做得这么好,于是果断给99分,哈哈~~不过,我觉得这个项目有很多地方可以改进和完善,因此在这里把这个项目总结一下,以备查询,也欢迎大家给出意见。以后有时间,再推出2.0、3.0等版本咯咯~~

计步器的原理是基本的物理知识,不再赘述,以后有时间可以单独写一篇,说明我是如何推导的。下面是所有代码:

第一部分:manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.pedometre"
    android:versionCode="1"
    android:versionName="1.0" >
    
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:theme="@style/myTheme"
            android:name=".MainActivity"
            android:label="@string/app_name" >
        </activity>
        <activity 
            android:theme="@android:style/Theme.NoTitleBar"
            android:name="com.example.pedometre.splash">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.example.pedometre.aide"
                  android:theme="@style/myTheme">
             <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
        <activity android:name="com.example.pedometre.carteDraw"
                  android:theme="@style/myTheme">
             <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
        <service android:name="com.example.pedometre.StepCounterService"></service>
        <activity android:name="com.example.pedometre.mPlayer"
                  android:theme="@style/myTheme">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
        <service android:name="com.example.pedometre.mPlayerService"></service>
    </application>

</manifest>
第二部分:mainActivity

package com.example.pedometre;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList;

import com.example.pedometre.StepDetector;
import com.example.pedometre.StepCounterService;

import android.support.v4.widget.DrawerLayout;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
	private DrawerLayout mDrawerLayout = null;
	private ListView mylistview;
	private ArrayList<String> list = new ArrayList<String>();
	private TextView tv_step;
	private TextView sy_dis;
	private TextView sy_cal;
	private TextView sy_vit;
	private Button btn_start;
	private Button btn_stop;
	private Thread mThread;
	private Chronometer timer;
	public static int total_step = 0;
	private int total_step1=0;
	private float pep_weight=60;
	private float per_step=0.5f;
	private float last_time=0;
	private float kaluli=0;
	private float x=0;
	private float st_x=0;
	private float st_y=0;
	private String inputName="";
	private SensorManager sm1;
	private SensorManager sm2;
	

	float[] accelerometerValues = new float[3];
	float[] magneticFieldValues = new float[3];
	
	public static float[]da_st=new float[10000];
	public static float max_width=0f,max_height=0f;

	
    @SuppressLint("HandlerLeak") Handler mHandler = new Handler(){
		@Override
		public void handleMessage(android.os.Message msg) {
			super.handleMessage(msg);
			if(msg.what == 0x00){
				countStep();
				tv_step.setText(total_step+"");
				last_time=last_time/1000/3600;
				kaluli=pep_weight*last_time*30/(last_time/per_step/total_step*400*60);
				DecimalFormat decimalFormat=new DecimalFormat("0.00");
				sy_cal.setText(decimalFormat.format(kaluli)+"kcal");
				
				 float[] values = new float[3];
			     float[] R = new float[9];
			     SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticFieldValues);	      
			     SensorManager.getOrientation(R, values);
			     da_st[total_step]=values[0];
			     
			   /* st_x=(float) (st_x+Math.cos(values[0]));
					st_y=(float) (st_y+Math.sin(values[0]));
					if (Math.abs(st_x)>max_height){
						max_height=Math.abs(st_x);
					}
					if (Math.abs(st_y)>max_width){
						max_width=Math.abs(st_y);
					}
			   */
				sy_dis.setText(decimalFormat.format(total_step*per_step/1000)+"km");
				
				sy_vit.setText(decimalFormat.format(total_step*per_step/1000/last_time)+"km/h");
			}
		}
	};
	
	private void countStep() {
		if(StepDetector.CURRENT_SETP % 2 == 0){
			total_step = StepDetector.CURRENT_SETP;
		}else{
			total_step = StepDetector.CURRENT_SETP + 1;
		}
		Log.i("total_step", StepDetector.CURRENT_SETP+"");
		total_step = StepDetector.CURRENT_SETP;
	};
	
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        sm1 = (SensorManager) getSystemService(SENSOR_SERVICE);
        sm2 = (SensorManager) getSystemService(SENSOR_SERVICE);
      
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        forceShowOverflowMenu();
        tv_step = (TextView) findViewById(R.id.tv_step);
        sy_dis = (TextView) findViewById(R.id.sy_distance);
        sy_cal = (TextView) findViewById(R.id.sy_caluli);
        sy_vit = (TextView) findViewById(R.id.sy_vitesse);
		btn_start = (Button) findViewById(R.id.btn_start);
		btn_stop = (Button) findViewById(R.id.btn_stop);
		timer = (Chronometer) findViewById(R.id.chronometer);
		mylistview = (ListView)findViewById(R.id.left_drawer);
		list.add("Poids(kg):                                    (60kg par défaut)");
		list.add("Longueur de chaque étape(cm):                 (50cm par défaut)");
		list.add("La sensibilité du capteur:                    (3 par défaut)");
		list.add("Intervalle temporel entre deux étapes(ms):    (500 par défaut)");
		ArrayAdapter<String> myArrayAdapter = new ArrayAdapter<String>
		(this,android.R.layout.simple_list_item_1,list);
		mylistview.setAdapter(myArrayAdapter);
		mylistview.setOnItemClickListener(new OnItemClickListener(){
			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
				if(list.get(arg2).contains("Poids")){
					inputTitleDialog();
					int t=0;
					try{
						t=Integer.parseInt(inputName);
					}catch(Exception e){}
					if (t>0){
					    list.set(arg2,"Poids(kg):                                    ("+inputName+"kg par défaut)");
					    pep_weight=t;
					}
				}
				if(list.get(arg2).contains("Longueur")){
					inputTitleDialog();
					int t=0;
					try{
						t=Integer.parseInt(inputName);
					}catch(Exception e){}
					if (t>0){
					    list.set(arg2,"Longueur de chaque étape(cm):                 ("+inputName+"cm par défaut)");
					    per_step=(float) (t*1.0/100);
					}
				}
				if(list.get(arg2).contains("sensibilité")){
					inputTitleDialog();
					int t=0;
					try{
						t=Integer.parseInt(inputName);
					}catch(Exception e){}
					if (t>0){
					    list.set(arg2,"La sensibilité du capteur:                    ("+inputName+" par défaut)");
					    StepDetector.SENSITIVITY=t;
					}
				}
				if(list.get(arg2).contains("Intervalle")){
					inputTitleDialog();
					int t=0;
					try{
						t=Integer.parseInt(inputName);
					}catch(Exception e){}
					if (t>0){
					    list.set(arg2,"Intervalle temporel entre deux étapes(ms):    ("+inputName+" par défaut)");
					    StepDetector.time_jg=t;
					}
				}
			}
		});
    }
    
    @Override
	protected void onResume(){
		super.onResume();
		if (sm1 != null) {
			sm1.registerListener(sev1,sm1.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
					SensorManager.SENSOR_DELAY_NORMAL);
		}
		if (sm2 != null) {
			sm2.registerListener(sev2,sm2.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
					SensorManager.SENSOR_DELAY_NORMAL);
		}
	}
    
    private SensorEventListener sev1 = new SensorEventListener() {
		 @Override
		 public void onSensorChanged(SensorEvent event) {
			 accelerometerValues = event.values;
		 }
		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}
	 };
	 
	 private SensorEventListener sev2 = new SensorEventListener() {
		 @Override
		 public void onSensorChanged(SensorEvent event) {
			 magneticFieldValues = event.values;
		 }
		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}
	 };
    
    private void inputTitleDialog() {
    	 final EditText inputServer = new EditText(this);
    	 inputServer.setFocusable(true);
    	 AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	 builder.setTitle("Réglages(Nombre entier naturel)").setIcon(R.drawable.ic_launcher).
    	 setView(inputServer).setNegativeButton("Annuler",null);
    	 builder.setPositiveButton("OK",new DialogInterface.OnClickListener(){
    		 public void onClick(DialogInterface dialog, int which) {
    			 inputName=inputServer.getText().toString();
    		 }
    	 });
    	 builder.show();
	}
    
    public void btnClick(View view){
		Intent service = new Intent(this, StepCounterService.class);
		switch (view.getId()) {
		case R.id.btn_music:
			turnAround2();
			break;
		case R.id.btn_map:
			turnAround1();
			break;
		case R.id.btn_start:
			timer.setBase(SystemClock.elapsedRealtime()); 
			timer.start();
			startService(service);
			btn_start.setEnabled(false);
			btn_stop.setEnabled(true);
			if(mThread == null){
				mThread = new Thread(){
					@Override
					public void run() {
						// TODO Auto-generated method stub
						super.run();
						int temp = 0;
						while (true) {
							try {
								sleep(300);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							if(StepCounterService.FLAG){
								Log.i("istrue", "true");
								if (temp != StepDetector.CURRENT_SETP) {
									temp = StepDetector.CURRENT_SETP;
								}
								last_time=SystemClock.elapsedRealtime()-timer.getBase();
								mHandler.sendEmptyMessage(0x00);
							}
						}
					}
				};
				mThread.start();
			}
			break;
		case R.id.btn_stop:
			timer.stop();
			stopService(service);
			btn_start.setEnabled(true);
			btn_stop.setEnabled(false);
			StepDetector.CURRENT_SETP = 0;
			mHandler.removeCallbacks(mThread);
			break;
		default:
			break;
		}
	}


	private void turnAround1() {
		Intent intent = new Intent();                   
        intent.setClass(MainActivity.this, carteDraw.class);
        startActivity(intent); 
	}

	private void turnAround2() {
		Intent intent = new Intent();                   
        intent.setClass(MainActivity.this, mPlayer.class);
        startActivity(intent); 
	}

	private void forceShowOverflowMenu() {
		try {
			ViewConfiguration config = ViewConfiguration.get(this);
			Field menuKeyField = ViewConfiguration.class
					.getDeclaredField("sHasPermanentMenuKey");
			if (menuKeyField != null) {
				menuKeyField.setAccessible(true);
				menuKeyField.setBoolean(config, false);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
        case R.id.help:
        	turnAround();
            return true;
        case R.id.setting:
        	mDrawerLayout.openDrawer(Gravity.LEFT);
			return true;
        case R.id.exit:
        	 new AlertDialog.Builder(MainActivity.this).setTitle("Confirmation")
			 .setMessage("Vous êtes sûr de me quitter?\n(⊙ ︿ ⊙)")
			 .setPositiveButton("Oui",new DialogInterface.OnClickListener(){
				 @Override
				 public void onClick(DialogInterface dialog, int which) {
					 finish();
				 }
			 }).setNegativeButton("Non",new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
				}
			 }).show();
        	return true;
        default:
        	return super.onOptionsItemSelected(item);
        }
    }

	@Override
	public boolean onMenuOpened(int featureId, Menu menu) {
		setOverflowIconVisible(featureId, menu);
		return super.onMenuOpened(featureId, menu);
	}
    
	private void setOverflowIconVisible(int featureId, Menu menu) {
		if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
			if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
				try {
					Method m = menu.getClass().getDeclaredMethod(
							"setOptionalIconsVisible", Boolean.TYPE);
					m.setAccessible(true);
					m.invoke(menu, true);
				} catch (Exception e) {
					Log.d("OverflowIconVisible", e.getMessage());
				}
			}
		}
	}

	private void turnAround() {
		Intent intent = new Intent();                   
        intent.setClass(MainActivity.this, aide.class);
        startActivity(intent); 
	}
}
主界面效果图

设置界面效果图:



第三部分:splash Avtivity(启动画面)

package com.example.pedometre;

import android.os.*;
import android.content.Intent;
import android.app.*;
import android.view.*;

public class splash extends Activity{
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
        setContentView(R.layout.splash);
        new CountDownTimer(2000,100) {
        	 @Override
        	   public void onTick(long millisUntilFinished) {
        	   }
        	         @Override
        	         public void onFinish() {   
        	          Intent intent = new Intent();                   
        	          intent.setClass(splash.this, MainActivity.class);
        	          startActivity(intent); 
        	          finish();                  
        	         }
        	              }.start();
        	 
        }
}
效果图


第四部分:carteDraw(绘制轨迹路线)

package com.example.pedometre;

import com.example.pedometre.MainActivity;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;

public class carteDraw extends Activity{

	 @Override
	 protected void onCreate(Bundle savedInstanceState) {
	      super.onCreate(savedInstanceState);
	      
	      ActionBar actionBar = getActionBar();
	      actionBar.setDisplayHomeAsUpEnabled(true);
	      
	      MyView myView = new MyView(this);
	      setContentView(myView);
	    }
	 
	 private class MyView extends View{
		 public MyView(Context context)
		    {
		      super(context);
		    }
		 
		 @SuppressLint("DrawAllocation") @Override
		    public void onDraw(Canvas canvas){
			  super.onDraw(canvas);
			 
			  Paint paint = new Paint();
		      paint.setAntiAlias(true);
		      paint.setColor(Color.YELLOW);
		      paint.setStyle(Paint.Style.FILL);
		      paint.setStrokeWidth(3);
		      
		      int r_w=canvas.getWidth();
		      int r_h=canvas.getHeight();
		     int f_w=(int) (MainActivity.max_width*2);
		      int f_h=(int) (MainActivity.max_height*2);
		      float rate=3;
		      if (MainActivity.total_step<=20){
		    	  rate=25;
		      }
		      else
		    	  if (MainActivity.total_step<=100){
		    		  rate=10; 
		    	  }
		    	  else
		    		  if (MainActivity.total_step<=400){
		    			  rate=5;
		    		  }
		    		  else
		    		  { rate=3;}
		    	  
		    
		      float x=r_w/2;float y=r_h/2;
		      for (int i=1;i<=MainActivity.total_step;i++){
		    	  canvas.drawLine(x, y, (float) (x+rate*Math.sin(MainActivity.da_st[i])), (float) (y+rate*Math.cos(MainActivity.da_st[i])), paint);
		    	  x=(float) (x+rate*Math.sin(MainActivity.da_st[i]));
		    	  y=(float) (y+rate*Math.cos(MainActivity.da_st[i]));
		      }
		 }
	 }
	 
	 @Override
	    public boolean onOptionsItemSelected(MenuItem item) {
	        switch (item.getItemId()){
	        case android.R.id.home:
	        	finish();
	        	return true;
	        default:
	        	return super.onOptionsItemSelected(item);
	        }
	 }
}
效果图:


第五部分:记录步数

package com.example.pedometre;

import android.content.Context;
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 {
	public static int CURRENT_SETP = 0;
	public static float SENSITIVITY = 3;
	public static float time_jg=500;
	public static float step_long=0.5f;
	
	private float mLastValues[] = new float[3 * 2];
	private float mScale[] = new float[2];
	private float mYOffset;
	private static long end = 0;
	private static long start = 0;

	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;
	
	public StepDetector(Context context){
		int h = 480;
		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)));
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onSensorChanged(SensorEvent event) {
		Sensor mSensor = event.sensor;
		synchronized (this) {
			if (mSensor.getType() == Sensor.TYPE_ORIENTATION) {
			} else {
				int j = (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0;
				if (j == 1) {
					float vSum = 0;
					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));
					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]);

						if (diff > SENSITIVITY) {
							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();
								if (end - start > time_jg) {
									Log.i("StepDetector", "CURRENT_SETP:"
											+ CURRENT_SETP);
									CURRENT_SETP++;
									mLastMatch = extType;
									start = end;
								}
							} else {
								mLastMatch = -1;
							}
						}
						mLastDiff[k] = diff;
					}
					mLastDirections[k] = direction;
					mLastValues[k] = v;
				}
			}
		}
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {}
}
package com.example.pedometre;

import com.example.pedometre.StepDetector;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;

public class StepCounterService extends Service {

	public static boolean FLAG = false;
	private SensorManager mSensorManager;
	private StepDetector mStepDetector;
	private PowerManager mPowerManager;
	private WakeLock mWakeLock;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@SuppressWarnings("deprecation")
	@Override
	public void onCreate() {
		super.onCreate();
		FLAG = true;
		mStepDetector = new StepDetector(this);
		mSensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
		mSensorManager.registerListener(mStepDetector, 
				mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
				SensorManager.SENSOR_DELAY_FASTEST);
		
		mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
		mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ACQUIRE_CAUSES_WAKEUP, 
				"s");
		mWakeLock.acquire();
	}
	
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		FLAG = false;
		if(mStepDetector != null){
			mSensorManager.unregisterListener(mStepDetector);
		}
		if(mWakeLock != null){
			mWakeLock.release();
		}
	}
}
第六部分:摇一摇切歌

package com.example.pedometre;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

public class mPlayer extends Activity{
	private int questop=0;
	private int it=0;
	private Button but_stop;
	private SensorManager sensorManager;
	private static final int SENSOR_SHAKE = 10;

	@Override
	 protected void onCreate(Bundle savedInstanceState) {
	      super.onCreate(savedInstanceState);
	      setContentView(R.layout.musicplay);
	      but_stop=(Button)findViewById(R.id.mus_stop);
	      ActionBar actionBar = getActionBar();
	      actionBar.setDisplayHomeAsUpEnabled(true);
	      sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
	    }
	
	@Override
	protected void onResume(){
		super.onResume();
		if (sensorManager != null) {
			sensorManager.registerListener(sensorEventListener,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
					SensorManager.SENSOR_DELAY_GAME);
		}
	}
	
	@Override
	protected void onDestroy(){
		super.onStop();
	}
	
	 @Override
	    public boolean onOptionsItemSelected(MenuItem item) {
	        switch (item.getItemId()){
	        case android.R.id.home:
	        	finish();
	        	return true;
	        default:
	        	return super.onOptionsItemSelected(item);
	        }
	 }
	 
	 private SensorEventListener sensorEventListener = new SensorEventListener() {
		 @Override
		 public void onSensorChanged(SensorEvent event) {
			 float[] values = event.values;
			 float x = values[0];
			 float y = values[1];
			 float z = values[2]; 
			 int medumValue = 17;
			 if (Math.abs(x) > medumValue || Math.abs(y) > medumValue || Math.abs(z) > medumValue) {
				 Message msg = new Message();
				 msg.what = SENSOR_SHAKE;
				 handler.sendMessage(msg);
			 }
		 }

		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}
	 };
	 
	 @SuppressLint("HandlerLeak") Handler handler = new Handler() {
		 @Override
		 public void handleMessage(Message msg){
			 super.handleMessage(msg);
			 switch (msg.what) {
			 case SENSOR_SHAKE:
				 if (questop==1){
					 it++;
					 if (it>9){
						 it=1;
					 }
					 onPlay(it);
				 }
				 break;
			 }
		 }
	 };
	
	 public void onClick_exit(View v){
		 Intent intent=new Intent(mPlayer.this,mPlayerService.class);
		 intent.putExtra("playing", 10);
		 startService(intent); 
		 finish();
	 }
	 
	 public void onClick_stop(View v){
		 if (questop==0){
			 Intent intent=new Intent(mPlayer.this,mPlayerService.class);
			 intent.putExtra("playing", 11);
			 startService(intent);
			 but_stop.setText("Arrêter");
			 questop=1;
		 }
		 else{
			 Intent intent=new Intent(mPlayer.this,mPlayerService.class);
			 intent.putExtra("playing", 10);
			 startService(intent);
			 but_stop.setText("Continuer");
			 questop=0;
		 }
	 }
	 
	 private void onPlay(int i) {
		 Intent intent=new Intent(mPlayer.this,mPlayerService.class);
		 intent.putExtra("playing", i);
		 but_stop.setText("Arrêter");
		 questop=1;it=i;
		 startService(intent); 
	}
	
	 public void onClick(View v){
		onPlay(1);
	}
	 
	 public void onClick1(View v){
		onPlay(2);
	}
	 
	 public void onClick2(View v){
		 onPlay(3);
	}
	 
	 public void onClick3(View v){
		 onPlay(4);
	}
	 
	 public void onClick4(View v){
		 onPlay(5);
	}
	 
	 public void onClick5(View v){
		 onPlay(6);
	}
	 
	 public void onClick6(View v){
		 onPlay(7);
	}
	 
	 public void onClick7(View v){
		 onPlay(8);
	}
	 
	 public void onClick8(View v){
		 onPlay(9);
	}
}
<pre name="code" class="java">package com.example.pedometre;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;

public class mPlayerService extends Service{
	private MediaPlayer mp;
	
	@Override
	public void onCreate(){
		super.onCreate();
		mp=MediaPlayer.create(this,R.raw.music1);
	}
	
	@Override
	public void onDestroy(){
		super.onDestroy();
		mp.release();
		stopSelf();
	}
	 
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		int playing = intent.getIntExtra("playing", 0);
		switch(playing){
		case 1:
			mp.release();
			mp=MediaPlayer.create(this,R.raw.music1);
			mp.setLooping(true);
			mp.start();
			break;
		case 2:
			mp.release();mp=MediaPlayer.create(this,R.raw.music2);
			mp.setLooping(true);
			mp.start();
			break;
		case 3:
			mp.release();mp=MediaPlayer.create(this,R.raw.music3);
			mp.setLooping(true);
			mp.start();
			break;
		case 4:
			mp.release();mp=MediaPlayer.create(this,R.raw.music4);
			mp.setLooping(true);
			mp.start();
			break;
		case 5:
			mp.release();mp=MediaPlayer.create(this,R.raw.music5);
			mp.setLooping(true);
			mp.start();
			break;
		case 6:
			mp.release();mp=MediaPlayer.create(this,R.raw.music6);
			mp.setLooping(true);
			mp.start();
			break;
		case 7:
			mp.release();mp=MediaPlayer.create(this,R.raw.music7);
			mp.setLooping(true);
			mp.start();
			break;
		case 8:
			mp.release();mp=MediaPlayer.create(this,R.raw.music8);
			mp.setLooping(true);
			mp.start();
			break;
		case 9:
			mp.release();mp=MediaPlayer.create(this,R.raw.music9);
			mp.setLooping(true);
			mp.start();
			break;
		case 10:
			if (mp.isPlaying()){
				mp.pause();
			}
			break;
		case 11:
			if (!(mp.isPlaying())){
				mp.start();
			}
			break;
		}
		return super.onStartCommand(intent, flags, startId);
	}
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
}

效果图:


第七部分:帮助信息

package com.example.pedometre;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;

public class aide extends Activity{
	 @Override
	 protected void onCreate(Bundle savedInstanceState) {
	      super.onCreate(savedInstanceState);
	      setContentView(R.layout.aide);
	      ActionBar actionBar = getActionBar();
	      actionBar.setDisplayHomeAsUpEnabled(true);
	    }
	 
	 @Override
	    public boolean onOptionsItemSelected(MenuItem item) {
	        switch (item.getItemId()){
	        case android.R.id.home:
	        	finish();
	        	return true;
	        default:
	        	return super.onOptionsItemSelected(item);
	        }
	 }
}
效果图:


第八部分:布局文件

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <FrameLayout
        android:id="@+id/framelayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
         <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bg_chunse"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:orientation="vertical" >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_marginLeft="@dimen/horizontal"
            android:orientation="horizontal">
            <ImageButton
                android:layout_height="50dp"
                android:layout_width="50dp"
                android:layout_gravity="center_vertical"
                android:background="@drawable/time_duree">
            </ImageButton>
            <Chronometer
                android:id ="@+id/chronometer"
                android:layout_height="match_parent"
                android:layout_width="wrap_content"
                android:layout_weight="1"
                android:format="%s"
                android:gravity="center"
                android:textSize="22sp"
                android:textColor="#030303"/>
            <ImageButton 
                android:layout_height="50dp"
                android:layout_width="50dp"
                android:layout_gravity="center_vertical"
                android:background="@drawable/distance"/>
            <TextView 
                android:id="@+id/sy_distance"
                android:gravity="center"
                android:text="0 km"
                android:textSize="22sp"
                android:textColor="#030303"
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>
        </LinearLayout>
        
        <LinearLayout
            android:layout_height="60dp"
            android:layout_width="match_parent"
            android:layout_marginLeft="@dimen/horizontal"
            android:orientation="horizontal">
            <ImageButton
                android:layout_height="50dp"
                android:layout_width="50dp"
                android:layout_gravity="center_vertical"
                android:background="@drawable/sy_caluli">
            </ImageButton>
            <TextView 
                android:id="@+id/sy_caluli"
                android:gravity="center"
                android:text="0 kcal"
                android:textSize="22sp"
                android:textColor="#030303"
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>
            <ImageButton 
                android:layout_height="50dp"
                android:layout_width="50dp"
                android:layout_gravity="center_vertical"
                android:background="@drawable/vitesse"/>
            <TextView 
                android:id="@+id/sy_vitesse"
                android:gravity="center"
                android:text="0 km/h"
                android:textSize="22sp"
                android:textColor="#030303"
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>
        </LinearLayout>
        
        <TextView android:layout_width="match_parent"
                  android:layout_height="10sp"/>"
        
        <TextView
        android:id="@+id/tv_step"
        android:layout_width="220sp"
        android:layout_height="220sp"
        android:background="@drawable/circle_button"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        android:text="0"
        android:textColor="#FF0000"
        android:textSize="60sp" />
        
        <TextView android:layout_width="match_parent"
                  android:layout_height="10sp"/>
        
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
        <LinearLayout 
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
            <Button
               android:id="@+id/btn_start"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:onClick="btnClick"
               android:text="@string/start" />
    
            <Button
               android:id="@+id/btn_stop"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:onClick="btnClick"
               android:text="@string/stop" />
         </LinearLayout> 
         
         <LinearLayout 
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
            <Button
               android:id="@+id/btn_map"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:onClick="btnClick"
               android:text="@string/map" />
    
            <Button
               android:id="@+id/btn_music"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:onClick="btnClick"
               android:text="@string/music" />
         </LinearLayout>
         </LinearLayout>
    </LinearLayout>
    </FrameLayout>
    <ListView
            android:id="@+id/left_drawer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:background="#8B0000"
            android:divider="#CD853F"
            android:dividerHeight="3dp" />
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/bg_chunse"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <TextView
                    android:id="@+id/version_lable"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:paddingLeft="10dip"
                    android:paddingTop="5dip"
                    android:text="@string/version_lable"
                    android:textColor="@color/orange"
                    android:textSize="22sp" />

                <TextView
                    android:id="@+id/version_val"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_toRightOf="@+id/version_lable"
                    android:paddingLeft="10dip"
                    android:paddingTop="5dip"
                    android:textColor="@color/green"
                    android:textSize="22sp" />

                <TextView
                    android:id="@+id/description"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/version_lable"
                    android:gravity="left"
                    android:paddingLeft="10dip"
                    android:paddingRight="10dip"
                    android:paddingTop="10dip"
                    android:text="@string/about_desc"
                    android:textColor="@color/gray"
                    android:textSize="22sp" >
                </TextView>
            </RelativeLayout>
</ScrollView>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/bg_chunse"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:scrollX="2dp"
        android:textColor="#8B4513"
        android:textSize="18dp"
        android:text="@string/musicdec"></TextView>
    <LinearLayout 
        android:layout_width="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_height="wrap_content">
        <Button 
            android:id="@+id/mus_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textColor="#EE0000"
            android:onClick="onClick_stop"
            android:text="@string/stop"/>
        <Button 
            android:id="@+id/mus_exit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#EE0000"
            android:layout_weight="1"
            android:onClick="onClick_exit"
            android:text="@string/exit"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_height="match_parent">
        <Button 
            android:id="@+id/mus_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick"
            android:text="@string/music1"/>
        <Button 
            android:id="@+id/mus_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick1"
            android:text="@string/music2"/>
        <Button 
            android:id="@+id/mus_3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick2"
            android:text="@string/music3"/>
        <Button 
            android:id="@+id/mus_4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick3"
            android:text="@string/music4"/>
        <Button 
            android:id="@+id/mus_5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick4"
            android:text="@string/music5"/>
        <Button 
            android:id="@+id/mus_6"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick5"
            android:text="@string/music6"/>
        <Button 
            android:id="@+id/mus_7"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick6"
            android:text="@string/music7"/>
        <Button 
            android:id="@+id/mus_8"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick7"
            android:text="@string/music8"/>
        <Button 
            android:id="@+id/mus_9"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick8"
            android:text="@string/music9"/>
        
    </LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:contentDescription="@string/app_name"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:src="@drawable/splash"
    android:scaleType="fitXY">
</ImageView>
第九部分:string_value

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">pédomètre</string>
    <string name="action_settings">Réglages</string>
    <string name="help">Assistance</string>
    <string name="version_lable">Plus d\'infos</string>
    <string name="about_desc">Bonjour! Bienvenue à l\'utilisation de ce logiciel.\n\nCe logiciel vous permet d\'enregistrer le nombre de pas, de dessiner votre piste et de vous repaître de la musique.\n\nSi vous avez des questions, n\'hésitez pas à me contacter. Mon
        numéro de téléphone portable est +86 15156293795 et mon e-mail adresse est
        baoyukun1994@126.com.\n\nJe vous souhaite tous mes vœux de bonheur!</string>
    <string name="edit_text">edit</string>
    <string name="file">file</string>
    <string name="about">about</string>
    <string name="exit">Echapper</string>
    <string name="music">Musique</string>
    <string name="map">Carte</string>
    <string name="start">Commencer</string>
    <string name="stop">Arrêter</string>
    <string name="musicdec">Vous pouvez sélectionner une chanson en appuyant sur un bouton.\nPour les changer, il suffit que vous secouiez votre portable.</string>
    <string name="music1">假如爱有天意..... 李健</string>
    <string name="music2">年轮...........张碧晨</string>
    <string name="music3">默........... 那英</string>
    <string name="music4">小水果..........筷子兄弟</string>
    <string name="music5">匆匆那年.........王菲</string>
    <string name="music6">不可说......... 霍建华/赵丽颖</string>
    <string name="music7">全民共舞........ 正月十五</string>
    <string name="music8">剩下的盛夏.......TFBOYS</string>
    <string name="music9">明天你好........ 牛奶咖啡</string>
    <string name="restart">Continuer</string>
</resources>


        
用Android手机传感器做个简易计步器:手把手实现SensorEvent数据采集与分析 本文详细介绍了如何利用Android手机传感器开发高精度计步器,从SensorEvent数据采集到智能算法优化。通过解析加速度传感器工作原理、构建高效数据处理管道及实现智能步态识别算法,最终打造出电量友好且准确率超过90%的计步解决方案。 阅读详情

相关推荐

Android传感器计步器完整Demo开发实战

Android系统提供了丰富的传感器接口,使开发者能够实现对设备运动状态的精准感知,为应用增添智能化特性。本章将深入探讨Android传感器的基本分类,包括加速度传感器、陀螺仪、磁场传感器等,并分析其在实际应用中的典型场景,如计步器、体感游戏、定位导航等。通过对传感器工作原理及其在Android系统中的支持机制进行剖析,帮助开发者建立清晰的理论框架,为后续开发实践奠定坚实基础。

weixin_42602726的博客 654

基于手机传感器的计步算法

智能手机内置各种传感器模块,提出一种基于手机加速度传感器的计步算法。

u014791094的博客 2737

使用加速度传感器根据步频和步长测距离

该文档详细介绍加速度传感器的工作原理,以及如何通过加速度传感器获取的步频来计算行走的距离及速度。

Android Manager之SensorManager---距离传感器

一、获取距离传感器实例: SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); Sensor proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 二、注册传感器事件监听器: sensorManager.registerListener(this, proximitySensor

zdj_Develop的博客 3726

安卓运动计步器

基于安卓开发的计步器项目,可以精确地计步,并可以记录运动轨迹,查看历史记录等功能。

域控制器迁移后NETLOGON共享丢失的修复指南

本文详细解析了在Windows域控制器迁移后NETLOGON共享丢失的故障现象与修复方法。通过使用Dcdiag工具诊断,定位注册表键值SysVolReady异常及SCRIPTS目录缺失等核心原因,并提供了修改注册表、创建目录、重启Netlogon服务等逐步修复指南,帮助管理员快速恢复域用户登录功能,确保业务连续性。

weixin_29245767的博客 88

# Pedometer 计步器算法简介

Pedometer 计步器算法简介以Android 6.0 M 为例,它为Pedometer计步器(以下简称Pedo)提供了两颗虚拟传感器(以下用sensor):Step Counter和Step Detector.它们的定义分别是: Step Counter提供从系统启动sensor激活以后用户走动的步数。 Step Detector是当用户每走一步时就触发的事件。 事件产生的延迟应该在2秒以内。

老刘的技术专栏 6165

从‘查理复用’到TM52F1363:深入剖析5脚188数码管的驱动原理与避坑指南

本文深入解析了5脚188数码管的驱动原理,重点介绍了查理复用技术如何通过5个IO引脚高效驱动188段显示,并详细探讨了TM52F1363单片机的寄存器配置与驱动实现。文章还提供了常见问题的解决方案和性能优化技巧,帮助开发者避免实际应用中的各种陷阱。

weixin_29159441的博客 478

运动追踪(SportsTracker)—— 安卓应用

最近利用空余时间写了一款安卓应用——运动追踪(SportsTracker)。 下面就来介绍下这款应用以及设计到的部分技术。 一、应用简洁 这款运动追踪是根据用户随身携带手机的运动状态,分析出用户的运动状态,用户只需第一次运行该应用,后面用户不用任何操作,该运动追踪就会后台每天统计用户行走或是跑步的步数,并使用计算出运动的距离、时间、步伐、以及消耗的卡路里等,并以图表的形式展现给用户。

章志强的专栏 3581

Qwen3-Embedding选型指南:0.6B/4B/8B三版本性能对比与场景匹配建议

本文深入解析阿里开源的Qwen3-Embedding系列模型(0.6B/4B/8B)的性能差异与适用场景,提供从边缘计算到云端部署的实战选型建议。通过实测数据对比响应延迟、内存占用和多语言精度等核心指标,帮助技术团队根据业务需求选择最优模型版本,并分享边缘设备优化与云端成本测算策略。

qsc901234567的博客 892

Eplan P8自动线号生成全攻略:从电位定义点到连接编号的完整流程

本文详细解析了Eplan P8自动线号生成的全流程,从电位定义点的创建配置到连接编号的标准化管理,帮助电气设计人员提升图纸规范性和工作效率。重点介绍了自动编号方案的定义与调整技巧,以及企业级标准化实施建议,是掌握Eplan P8自动线号功能的实用指南。

weixin_29254029的博客 509

Android移动开发-调用步行检测和步行计数传感器开发简易计步器的实现

Android计步器的原理其实是通过手机的前后摆动模拟步伐节奏的监测。Android中与计步器有关的传感器有两个,一个是步行检测(TYPE_STEP_DETECTOR),另一个是步行计数(TYPE_STEP_COUNTER)。其中,步行检测的返回值为1时,表示当前检测到一个步伐;步行计数的返回值是累加后的数值,表示本次开机激活后的总步伐数。layout/activity_main.xml界面布局代码

_彼岸雨敲窗_的博客 7541

【深度剖析】三一重工的数字化转型(中篇)

三一重工在数字化转型方面取得了提高效率、降低成本、加强研发创新和改善内控管理等多方面的成效。本研究旨在通过对三一重工数字化转型的深入分析,引导企业思考在第四次工业革命与第三次能源革命交汇的超级技术窗口期,如何进一步把握发展机遇,并为同行业其他企业提供探索性的建议。作为装备制造行业的佼佼者,三一重工的数字化转型受到了业界的广泛关注。作为行业内首批接触并实践数字化转型的企业之一,三一重工的转型经验不仅成功,而且积累了丰富的理论与实践,为其他制造业企业的数字化转型提供了可借鉴的范例。

领信卓越的博客 2306

Android计步器源码解析:从加速度传感器到前台服务

在移动开发中,传感器数据的采集与处理是构建健康类应用的基础,而计步功能则是最典型的实践场景。加速度传感器通过感知三轴加速度变化,结合峰值检测与动态阈值算法,即可实现步数识别。然而,真实落地还面临系统级挑战:Android后台限制要求必须使用前台服务保活,动态权限适配(如ACTIVITY_RECOGNITION)直接决定传感器能否正常工作,同时厂商ROM的省电策略也需引导处理。本文以一套完整可运行的Android Studio计步器工程为例,从传感器选型、算法调参、数据持久化到系统适配层层拆解,详细展示如何将

weixin_31815843的博客 220

LPDDR5 学习笔记01:功能概述

LPDDR5/LPDDR5X SDRAM设备采用8/16DQ通道架构,支持2Gb-32Gb容量。通过CK命令时钟和更快的WCK数据时钟协同工作,7个CA引脚传输控制信息,支持2:1或4:1的WCK:CK比例。设备提供BG/8B/16B三种存储模式选择,分别支持不同数据速率(最高8.533Gbps)和突发长度。采用0.5V VDDQ电源电压,实现高速双倍数据速率传输,并通过差分WCK时钟完成数据采样。读写采用突发访问机制,需先激活命令再执行读写操作。新型LPDDR5X仅支持BG和16B模式,优化了高速性能。

一只豌豆象的博客 2197

信号处理仿真:自适应信号处理_(8).自适应信道均衡

在无线通信系统中,信道的多径效应和时变特性会导致信号的失真,从而影响通信质量。自适应信道均衡技术通过实时调整均衡器的参数,以补偿信道失真,提高信号的质量和可靠性。本节将详细介绍自适应信道均衡的原理、算法和实现方法,并通过具体的仿真例子来说明其应用。

2401_87715305的博客 1039

Android计步器开发实战:从传感器到数据持久化

本文详细介绍了Android计步器开发的全过程,从传感器选择(TYPE_STEP_COUNTER和TYPE_STEP_DETECTOR)到数据持久化实现。通过源码示例展示了后台服务、数据存储及性能优化技巧,帮助开发者快速构建高效、低耗电的计步应用。

uran的专栏 830

【FF-A】第二章 Introduction

Armv8.4 架构引入了在安全状态下的虚拟化扩展。Arm® SMMU v3.2 架构[1]为安全流添加了对第2阶段翻译的支持,以补充在 Armv8.4 处理器状态下的安全 EL2 翻译制度。这些架构特性使得在安全状态下,彼此不信任的软件组件能够相互隔离。关于在安全状态下引入虚拟化扩展以及固件框架目标的更多理念可在名为《在安全世界使用虚拟化进行隔离》的白皮书[3]中找到。软件组件只能访问物理地址空间和系统资源的区域,例如 GIC 中对其正确运行必要的中断。

baron-周贺贺-代码改变世界ctw 528

Android计步器UI设计与实现:从传感器到可视化

在移动健康应用开发中,计步器作为核心功能模块,其UI设计直接影响用户体验。Android平台通过SensorManager提供TYPE_STEP_COUNTER传感器接口,开发者需要处理传感器数据采集、节电优化等底层逻辑。数据可视化方面,MPAndroidChart库能高效实现动态曲线展示,而ConstraintLayout则适合构建响应式界面。良好的计步器设计需平衡实时反馈与性能消耗,采用ValueAnimator实现平滑过渡动画,同时适配深色模式提升夜间可用性。这类健康应用通常需要处理后台服务保活、多厂

weixin_30271335的博客 392

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Android中怎样使用计步器传感器 "TYPE_STEP_DETECTOR"

在Android 4.4以后的版本已经可以直接支持计步器sensor,参考下面的文章。 http://developer.android.com/about/versions/android-4.4.html#UserInput http://motzcod.es/post/82515321689/part-1-my-stepcounter-android-step-sensors

yuxiaohui78的专栏 1万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【Android入门到项目实战-- 9.2】—— 传感器实战使用教程(靠近黑屏和计步器)

Android传感器具体应用,实战使用教程,案例一:靠近屏幕黑屏;案例二:计步器

个人博客 2603

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

安卓计步器

针对计步器的基本需求功能如下: 1.通过传感器得到步数 2.通过数据库储存步数 3.从数据库调出相应数据显示步数 分析ios系统自带健康软件中的计步器,数据显示为: 1.步行+跑步距离 2.步数 3.已爬楼层 其中每项显示均包含日、周、月、年的数据柱形图显示和对应时长的平均值显示,并能显示所有数据的具体时间和数值。 当传感器的值发生变化时,会调用onSensorChanged方法...

fjnu_se的博客 813

安卓传感器的简单使用

前言前言介绍一些传感器的api利用加速传感器 简单实现计步器 前言 这学期学习了移动软件开发课程后,自己尝试实现了个小功能,就是利用手机自带的加速传感器实现个简单的计步器。 介绍一些传感器的api 一般来说,智能机中都支持一下常见的传感器 如:温度传感器(tempreture sensor);压力传感器(pressure sensor);光传感器(light sensor);加速度传感器(accelerometer sensor)等等等等; 传感器有几个比较重要的API: SensorManager(用以获

fjnu_se的博客 469

传感器的应用_计步器的开发和使用

传感器的应用_计步器的开发和使用

Sunnyztg的博客 1122

基于java的智能手表_基于安卓Android智能手环(计步器)APP设计(含录像)

基于安卓Android智能手环(计步器)APP设计(含录像)(毕业论文11800字,程序代码)该研究课题研究了计步app的一系列原理和方式:计步器是通过统计步数、距离、速度、时间等数据,测算卡路里或热量消耗,用以掌控运动量,防止运动量不足,或运动过量的一种工具。电子计步器主要由震动传感器和电子计数器组成。人在步行时重心都要有一点上下移动。以腰部的上下位移最为明显,所以记步器挂在腰带上最为适宜。电子...

weixin_28676289的博客 1683

Android计步器App开发实战:从传感器原理到完整项目实现

在移动应用开发中,计步功能看似平常,但实现一个准确且省电的计步器却需要深入掌握传感器技术、算法设计和服务生命周期管理。加速度传感器是计步的核心硬件,通过采集三轴加速度数据并提取人体行走时的周期性信号,结合高速滤波、低通滤波和自适应阈值等算法,可以有效过滤噪声并识别真实步数。在此基础上,利用前台服务和数据库持久化确保应用在后台稳定运行并保存历史数据,为用户提供实时步数、距离和卡路里等实用功能。无论是作为入门练手还是工程实践,Android计步器项目都覆盖了从底层硬件交互到上层业务实现的完整链路,适合开发者深入

weixin_29189363的博客 55
上一篇: poj_2250 Compromise(输出最长公共子序列)
下一篇: 把Linux系统装在U盘上
薄帷清风
博客等级 码龄11年 31粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值