前些天印尼客户要求在高通平台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)也都可以类似的实现此功能,有问题请在后面留言。