標籤:android 音樂 搖搖 換歌
前些天印尼客戶要求在高通平台7251上加一個搖搖切歌功能。查了些資料,基本實現了此功能。
直接上源碼,用svn查看修改點。
前面兩個ic_mp_shake_off_btn是兩張圖片,資源隨便讓UI做兩張即可。
接下來就是audio_player.xml檔案的修改:(這個就是你要將你的表徵圖按鈕放在哪個地方)
對應的修改其他解析度的布局檔案audio_player.xml
接下來添加對應的字串:String.xml
<span style="font-size:24px;"> <string name="shake_on_notif">搖一搖換歌功能已開啟.</string> <string name="shake_off_notif">搖一搖換歌功能已關閉.</string></span>
各國語言的翻譯也自己去添加.
接下來修改音樂播放的主類:MediaPlaybackActivity.java
首先要添加變數:private ImageButton mShakeButton;
接下來再通過findViewById來執行個體化搖搖按鈕並添加監聽;
<pre name="code" class="java"><span style="font-size:24px;"> mShakeButton = ((ImageButton) findViewById(R.id.shake)); mShakeButton.setOnClickListener(mShakeListener); </span>
在函數onConfigurationChanged也做同樣的操作;
<span style="font-size:24px;"> mShakeButton = ((ImageButton) findViewById(R.id.shake)); mShakeButton.setOnClickListener(mShakeListener); </span>
現在就來實現監聽的函數;
<span style="font-size:24px;"> <span style="font-size:18px;">private View.OnClickListener mShakeListener = new View.OnClickListener() { public void onClick(View v) { shakeEnable(); } };</span></span>
寫shakeEnable()函數的函數體;
<span style="font-size:24px;"> <span style="font-size:18px;">private void shakeEnable(){if (mService == null) {return;}try {if (mService.getShakeFlag()== false){mService.setShakeFlag(true);showToast(R.string.shake_on_notif);}else{mService.setShakeFlag(false);showToast(R.string.shake_off_notif);}setShakeButtonImage();}catch (RemoteException ex) { } }</span></span>
在ServiceConnection裡修改按鈕的可操作和設定圖片;
寫setShakeButtonImage 函數:
<span style="font-size:24px;"> <span style="font-size:18px;">private void setShakeButtonImage() { if (mService == null) return; try {if (mService.getShakeFlag() == false) {mShakeButton.setImageResource(R.drawable.ic_mp_shake_off_btn);}else{mShakeButton.setImageResource(R.drawable.ic_mp_shake_on_btn);} }catch (RemoteException ex) { } }</span></span>
MediaPlaybackActivity.java這個檔案修改好了;
接下來看看MediaPlaybackService.java
先import onShakeListener
<span style="font-size:24px;">import com.android.music.ShakeDetector.onShakeListener;</span>
申明變數:
private boolean mShakeFlag = false;
ShakeDetector mShakeDetector = null;
在onCreate()中從sharedpreference中讀取值,來設定是否開啟搖搖功能;
<span style="font-size:24px;"> <span style="font-size:18px;">mShakeFlag = mPreferences.getBoolean("shakeflag", false); setShakeOnorOff();</span></span>
在onDestroy()中取消註冊:
<span style="font-size:24px;"> <span style="font-size:18px;">if (mShakeDetector != null) {mShakeDetector.unRegisterListener(); }</span></span>實現函數:
<span style="font-size:24px;"> <span style="font-size:18px;"> private void setShakeOnorOff(){ if (mShakeFlag == true){ mShakeDetector= new ShakeDetector(this); mShakeDetector.registerListener(); mShakeDetector.setOnShakeListener(new onShakeListener() { @Override public void onShake() { // TODO Auto-generated method stub if (isPlaying()){ gotoNext(true); } } }); }else{if (mShakeDetector != null) {mShakeDetector.unRegisterListener();} }Editor ed = mPreferences.edit();ed.putBoolean("shakeflag", mShakeFlag);SharedPreferencesCompat.apply(ed); } public void setShakeFlag(boolean shakeflag) { synchronized (this) { mShakeFlag = shakeflag; setShakeOnorOff(); } } public boolean getShakeFlag() { return mShakeFlag; }</span></span>
在IMediaPlaybackService.Stub中設定是否開啟搖搖功能
<span style="font-size:24px;"> <span style="font-size:18px;">public void setShakeFlag(boolean shakeflag) { mService.get().setShakeFlag(shakeflag); } public boolean getShakeFlag() { return mService.get().getShakeFlag(); }</span></span>
接下來就是在IMediaPlaybackService.aidl檔案中添加對應的函數;
<span style="font-size:24px;"> <span style="font-size:18px;">void setShakeFlag(boolean shakeflag); boolean getShakeFlag();</span></span>
最後就是添加一個檔案ShakeDetector.java
<span style="font-size:18px;">package com.android.music; 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 ShakeDetector implements SensorEventListener {private static final String TAG = "ShakeDetector";private Context mContext;private long lastTime; private float last_x;private float last_y;private float last_z;private static final double SHAKE_SHRESHOLD = 3000d;//這個值可根據sensor的靈敏度來調整 private Sensor sensor;private SensorManager sensorManager;public onShakeListener shakeListener;public ShakeDetector(Context context) {mContext = context;sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);} public boolean registerListener() {if (sensorManager != null) {sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);if (sensor != null) {this.sensorManager.registerListener(this, sensor,SensorManager.SENSOR_DELAY_GAME);return true;}}return false;}public void unRegisterListener() {System.out.println("ShakeDetector:unRegisterListener");if (sensorManager != null && sensor != null)sensorManager.unregisterListener(this , sensor);}public void setOnShakeListener(onShakeListener listener) {shakeListener = listener;}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {// TODO Auto-generated method stub}@Overridepublic void onSensorChanged(SensorEvent event) {// TODO Auto-generated method stublong curTime = java.lang.System.currentTimeMillis();if ((curTime - lastTime) > 50) {long diffTime = (curTime - lastTime);lastTime = curTime;float x = event.values[0];float y = event.values[1];float z = event.values[2]; float speed = Math.abs(x + y + z - last_x - last_y - last_z)/ diffTime * 10000;System.out.println("ShakeDetector:onSensorChanged speed ="+speed);if (speed > SHAKE_SHRESHOLD) {shakeListener.onShake();}last_x = x;last_y = y;last_z = z;}} public interface onShakeListener {public void onShake();}}</span>
好,到此為止,就可以實現搖搖切歌功能了,如果有用得上的,可以拿去用一下,別的平台(展訊,MTK)也都可以類似的實現此功能,有問題請在後面留言。
Android平台搖搖切歌功能