前些天印尼客户要求在高通平台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; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } @Override public void onSensorChanged(SensorEvent event) { // TODO Auto-generated method stub long 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)也都可以类似的实现此功能,有问题请在后面留言。