应用功能:摇一摇手机,自动连接Google Voice ,可以将语音转成文本
步骤:
1. 在 AndroidMainfest.xml 中添加权限:<uses-sdk android:minSdkVersion="7"/>
2.布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity$PlaceholderFragment"> <TextView android:text="shake" android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="voice" android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
主类:
package com.example.shakeilikeactivity; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Bundle; import android.speech.RecognizerIntent; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; public class MainActivity extends Activity { ShakeListener mShakeListener = null; private static final int VOICE_RECOGNITION = 83; private TextView tv1; private TextView tv2; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); this.setContentView(R.layout.fragment_main); tv1=(TextView)this.findViewById(R.id.textView1); tv2=(TextView)this.findViewById(R.id.textView2); mShakeListener = new ShakeListener(this); mShakeListener.setOnShakeListener(new ShakeListener.OnShakeListener() { @Override public void onShake() { tv1.setText("摇一摇成功啦!"); Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo"); //设置语音识别Intent调用的特定属性参数 try { //启动一个要求有返回值的activity调用 startActivityForResult(intent, VOICE_RECOGNITION); tv2.setText(""); } catch (ActivityNotFoundException a) { Toast t = Toast.makeText(getApplicationContext(), "Opps! Your device doesn't support Speech to Text", Toast.LENGTH_SHORT); t.show(); } //mShakeListener.stop(); } }); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case VOICE_RECOGNITION: { if (resultCode == RESULT_OK && null != data) { ArrayList<String> text = data .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); tv2.setText(text.get(0)); } break; } } } }
监听类实现:
package com.example.shakeilikeactivity; 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 ShakeListener implements SensorEventListener { String TAG = "ShakeListener"; // 速度阈值,当摇晃速度达到这值后产生作用 private static final int SPEED_SHRESHOLD = 3000; // 两次检测的时间间隔 private static final int UPTATE_INTERVAL_TIME = 70; // 传感器管理器 private SensorManager sensorManager; // 传感器 private Sensor sensor; // 重力感应监听器 private OnShakeListener onShakeListener; // 上下文 private Context mContext; // 手机上一个位置时重力感应坐标 private float lastX; private float lastY; private float lastZ; // 上次检测时间 private long lastUpdateTime; // 构造器 public ShakeListener(Context c) { // 获得监听对象 mContext = c; start(); } // 开始 public void start() { // 获得传感器管理器 sensorManager = (SensorManager) mContext .getSystemService(Context.SENSOR_SERVICE); if (sensorManager != null) { // 获得重力传感器 sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } // 注册 if (sensor != null) { sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); } } // 停止检测 public void stop() { sensorManager.unregisterListener(this); } // 设置重力感应监听器 public void setOnShakeListener(OnShakeListener listener) { onShakeListener = listener; } // 重力感应器感应获得变化数据 public void onSensorChanged(SensorEvent event) { // 现在检测时间 long currentUpdateTime = System.currentTimeMillis(); // 两次检测的时间间隔 long timeInterval = currentUpdateTime - lastUpdateTime; // 判断是否达到了检测时间间隔 if (timeInterval < UPTATE_INTERVAL_TIME) return; // 现在的时间变成last时间 lastUpdateTime = currentUpdateTime; // 获得x,y,z坐标 float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; // 获得x,y,z的变化值 float deltaX = x - lastX; float deltaY = y - lastY; float deltaZ = z - lastZ; // 将现在的坐标变成last坐标 lastX = x; lastY = y; lastZ = z; double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / timeInterval * 10000; Log.v(TAG, "===========log==================="); // 达到速度阀值,发出提示 if (speed >= SPEED_SHRESHOLD) { onShakeListener.onShake(); } } public void onAccuracyChanged(Sensor sensor, int accuracy) { } // 摇晃监听接口 public interface OnShakeListener { public void onShake(); } }