android 摇一摇那点事儿

    今天我们说说摇一摇,以晃动手机切换壁纸为例子。

    首先说说晃动,做手机的应该知道,这个晃动就是重力感应了,也就是Gsensor了。

	public void startListener(){
		try{
			if(mSensorManager == null){
				mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
			}
		}catch(Exception e){
			Log.d("dream.zhou","SensorManager not exist");
		}
		
		if((null != mSensorManager) && (mSensor == null)){
			mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		}
		if(null != mSensor){
			mSensorManager.registerListener(ShakeBackListener.this,mSensor,SensorManager.SENSOR_DELAY_GAME,null);
		}
	}

首先我们获取到SensorManager,顾名思义就是管理Sensor传感器的Manager;然后获取代号为Sensor.TYPE_ACCELEROMETER的Sensor传感器;最后我们把我们的Sensor注册给SensorManager。这样我们就有了Gsensor了,那我们感应的地方在哪呢?
	@Override
	public void onSensorChanged(SensorEvent event) {
		// TODO Auto-generated method stub
		long currentUpdateTime = System.currentTimeMillis();
		long timeInterval = currentUpdateTime - mLastUpdateTime;
				
		if(timeInterval < SHAKE_TIME)return;
		mLastUpdateTime = currentUpdateTime;
		
		float x = event.values[0];
		float y = event.values[1];
		float z = event.values[2];
		
		float deltaX = x - mLastX;
		float deltaY = y - mLastY;
		float deltaZ = z - mLastZ;
		
		mLastX = x;
		mLastY = y;
		mLastZ = z;
		
		double speed = ((Math.sqrt(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ))/timeInterval)*10000;

		if((speed >= SHAKE_SPEED)&&((mLastUpdateTime - mLastChangeWallpaperTime) >= CHANGE_WALLPAPER_TIME)){
			mLastChangeWallpaperTime = mLastUpdateTime;
			mOnShakeListener.onShake();
		}

	}

就是这里了,首先我们隔一段时间接收一次数据,就是我们这里的x,y,z了,通过和上一次的mLastX,mLastY,mLastZ的差值,我们计算出晃动速度,最后我们判断速度大于某个值就去做我们想做的事情。这个事情都有什么呢?举例子,如我们要说的切换壁纸,还有切换音乐,还有寻找好友,还有接听电话,还有摇一摇等等吧,反正多了去,这些都是表现,其实质都是一样的。我们这里的mOnShakeListener.onShake();是一个接口。

接着我们说说切换壁纸
	@Override
	public void onCreate(){
		mContext = this;
		findWallpapers();
		mShakeBackListener = new ShakeBackListener(ShakeBackService.this);
		mOnShakeListener = new OnShakeListener(){
			@Override
			public void onShake(){
				// TODO Auto-generated method stub	
				nextWallpaper = Settings.System.getInt(mContext.getContentResolver(),"launcher.current.wallpaper",0) + 1;
				if(nextWallpaper >= mWallpaperCount){
					nextWallpaper = 0;
				}
				vibrate(VIBRATOR_TIME,needVibrate);
				selectWallpaper(nextWallpaper);
				Settings.System.putInt(mContext.getContentResolver(),"launcher.current.wallpaper",nextWallpaper);
			}
		};
		
		mShakeBackListener.setOnShakeListener(mOnShakeListener);
		mShakeBackListener.startListener();
		super.onCreate();
	}

这个就是我们刚才提到的onShake()接口了,首先我们会获取当前的壁纸是系统壁纸的第几张,然后得到下一张是第几张nextWallpaper,然后判断如果是最后一张就转移到第一张,接着我们让手机震动一下,这样我们用户会很有感觉的,知道已经晃动可以,壁纸已经切换了,接着就是切换壁纸了selectWallpaper(nextWallpaper);
    private void selectWallpaper(int position) {
        try {
            WallpaperManager wpm = (WallpaperManager) this.getSystemService(
                    Context.WALLPAPER_SERVICE);
            wpm.setResource(mImages.get(position));
        } catch (IOException e) {
            Log.e("dream.zhou", "Failed to set wallpaper: " + e);
        }
    }

获取到WallpaperManager也就是壁纸管理器,然后获取到我们需要的壁纸的ID:mImages.get(position),最后就是wpm.setResource(mImages.get(position));把壁纸换掉了。我们切换过壁纸之后就是记录当前的壁纸是那一张了。其实我知道大家这些都能看懂,接下来就不多扯淡了,把完整代码贴出来给大家做个参考吧。


首先是我们的Sensor类了:

package com.android.launcher2.shake;
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 ShakeBackListener implements SensorEventListener {
	
	private static final int SHAKE_SPEED = 1000;
	private static final int SHAKE_TIME = 200;
	private static final int CHANGE_WALLPAPER_TIME = 1500;
	private SensorManager mSensorManager = null;
	private Sensor mSensor = null;
	private OnShakeListener mOnShakeListener = null;
	private Context mContext = null;
	private float mLastX = 0;
	private float mLastY = 0;
	private float mLastZ = 0;
	private long mLastUpdateTime = 0;
	private long mLastChangeWallpaperTime = 2000;
		
	public ShakeBackListener(Context c){		
		mContext = c;
	}
	
	public void startListener(){
		try{
			if(mSensorManager == null){
				mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
			}
		}catch(Exception e){
			Log.d("dream.zhou","SensorManager not exist");
		}
		
		if((null != mSensorManager) && (mSensor == null)){
			mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		}
		if(null != mSensor){
			mSensorManager.registerListener(ShakeBackListener.this,mSensor,SensorManager.SENSOR_DELAY_GAME,null);
		}
	}
	
	public void stopListener(){		
		if(null != mSensorManager){
			mSensorManager.unregisterListener(this);
		}
	}
	
	public interface OnShakeListener{
		public void onShake();
	}
	
	public void setOnShakeListener(OnShakeListener listener){
		mOnShakeListener = listener;
	}

	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		// TODO Auto-generated method stub
		long currentUpdateTime = System.currentTimeMillis();
		long timeInterval = currentUpdateTime - mLastUpdateTime;
				
		if(timeInterval < SHAKE_TIME)return;
		mLastUpdateTime = currentUpdateTime;
		
		float x = event.values[0];
		float y = event.values[1];
		float z = event.values[2];
		
		float deltaX = x - mLastX;
		float deltaY = y - mLastY;
		float deltaZ = z - mLastZ;
		
		mLastX = x;
		mLastY = y;
		mLastZ = z;
		
		double speed = ((Math.sqrt(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ))/timeInterval)*10000;

		if((speed >= SHAKE_SPEED)&&((mLastUpdateTime - mLastChangeWallpaperTime) >= CHANGE_WALLPAPER_TIME)){
			mLastChangeWallpaperTime = mLastUpdateTime;
			mOnShakeListener.onShake();
		}

	}

}

下面是我的Service类了:

package com.android.launcher2.shake;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Vibrator;
import com.android.launcher2.shake.ShakeBackListener.OnShakeListener;
import android.util.Log;
import android.app.WallpaperManager;
import java.io.IOException;
import com.android.launcher.R;
import android.content.res.Resources;
import java.util.ArrayList;
import android.provider.Settings;

public class ShakeBackService extends Service{
	
	private long VIBRATOR_TIME = 50;
	private ShakeBackListener mShakeBackListener = null;
	private OnShakeListener mOnShakeListener = null;
	private Vibrator mVibrator = null;
	private Context mContext = null;
	private boolean needVibrate = true;
	private ArrayList<Integer> mImages;
	private int nextWallpaper = 0;
	private int mWallpaperCount = 0;
	
	private IShakeBackService.Stub mBinder = new IShakeBackService.Stub() {
		
	};
	
	@Override
	public void onCreate(){
		mContext = this;
		findWallpapers();
		mShakeBackListener = new ShakeBackListener(ShakeBackService.this);
		mOnShakeListener = new OnShakeListener(){
			@Override
			public void onShake(){
				// TODO Auto-generated method stub	
				Log.d("dream.zhou.launcher2222","mWallpaperCount="+mWallpaperCount);
				nextWallpaper = Settings.System.getInt(mContext.getContentResolver(),"launcher.current.wallpaper",0) + 1;
				Log.d("dream.zhou.launcher2222","nextWallpaper="+nextWallpaper);
				if(nextWallpaper >= mWallpaperCount){
					nextWallpaper = 0;
				}
				vibrate(VIBRATOR_TIME,needVibrate);
				selectWallpaper(nextWallpaper);
				Settings.System.putInt(mContext.getContentResolver(),"launcher.current.wallpaper",nextWallpaper);
			}
		};
		
		mShakeBackListener.setOnShakeListener(mOnShakeListener);
		mShakeBackListener.startListener();
		super.onCreate();
	}

    private void findWallpapers() {
        mImages = new ArrayList<Integer>(24);

		mWallpaperCount = 0;

        final Resources resources = getResources();
        final String packageName = resources.getResourcePackageName(R.array.wallpapers);

        addWallpapers(resources, packageName, R.array.wallpapers);
        addWallpapers(resources, packageName, R.array.extra_wallpapers);
    }

    private void addWallpapers(Resources resources, String packageName, int list) {
        final String[] extras = resources.getStringArray(list);
        for (String extra : extras) {
            int res = resources.getIdentifier(extra, "drawable", packageName);
            if (res != 0) {
				mWallpaperCount++;
                mImages.add(res);
            }
        }
    }

    private void selectWallpaper(int position) {
        try {
            WallpaperManager wpm = (WallpaperManager) this.getSystemService(
                    Context.WALLPAPER_SERVICE);
            wpm.setResource(mImages.get(position));
        } catch (IOException e) {
            Log.e("dream.zhou", "Failed to set wallpaper: " + e);
        }
    }

	private void vibrate(long duration,boolean need){
		if(mVibrator == null){
			mVibrator = (Vibrator)mContext.getSystemService(Context.VIBRATOR_SERVICE);
		}
		if(need){
			mVibrator.vibrate(duration);
		}
	}
		
	@Override
	public void onDestroy(){
		mShakeBackListener.stopListener();
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return mBinder;
	}
	
}

今天就说到这里,还是那句话给大师饭后取乐,给后来者抛砖引玉,别在背后骂我就行。




猜你喜欢

转载自blog.csdn.net/zhiyuan263287/article/details/18656187