1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.apis.graphics; 18 19 import android.content.Context; 20 import android.graphics.*; 21 import android.hardware.Sensor; 22 import android.hardware.SensorEvent; 23 import android.hardware.SensorEventListener; 24 import android.hardware.SensorManager; 25 import android.os.Bundle; 26 import android.util.Log; 27 import android.view.View; 28 29 public class SensorTest extends GraphicsActivity { 30 private final String TAG = "SensorTest"; 31 32 private SensorManager mSensorManager; 33 private Sensor mSensor; 34 private SampleView mView; 35 private float[] mValues; 36 37 private static class RunAve { 38 private final float[] mWeights; 39 private final float mWeightScale; 40 private final float[] mSamples; 41 private final int mDepth; 42 private int mCurr; 43 RunAve(float[] weights)44 public RunAve(float[] weights) { 45 mWeights = weights; 46 47 float sum = 0; 48 for (int i = 0; i < weights.length; i++) { 49 sum += weights[i]; 50 } 51 mWeightScale = 1 / sum; 52 53 mDepth = weights.length; 54 mSamples = new float[mDepth]; 55 mCurr = 0; 56 } 57 addSample(float value)58 public void addSample(float value) { 59 mSamples[mCurr] = value; 60 mCurr = (mCurr + 1) % mDepth; 61 } 62 computeAve()63 public float computeAve() { 64 final int depth = mDepth; 65 int index = mCurr; 66 float sum = 0; 67 for (int i = 0; i < depth; i++) { 68 sum += mWeights[i] * mSamples[index]; 69 index -= 1; 70 if (index < 0) { 71 index = depth - 1; 72 } 73 } 74 return sum * mWeightScale; 75 } 76 }; 77 78 private final SensorEventListener mListener = new SensorEventListener() { 79 80 private final float[] mScale = new float[] { 2, 2.5f, 0.5f }; // accel 81 private float[] mPrev = new float[3]; 82 private long mLastGestureTime; 83 84 public void onSensorChanged(SensorEvent event) { 85 boolean show = false; 86 float[] diff = new float[3]; 87 88 for (int i = 0; i < 3; i++) { 89 diff[i] = Math.round(mScale[i] * (event.values[i] - mPrev[i]) * 0.45f); 90 if (Math.abs(diff[i]) > 0) { 91 show = true; 92 } 93 mPrev[i] = event.values[i]; 94 } 95 96 if (show) { 97 // only shows if we think the delta is big enough, in an attempt 98 // to detect "serious" moves left/right or up/down 99 Log.e(TAG, "sensorChanged " + event.sensor.getName() + 100 " (" + event.values[0] + ", " + event.values[1] + ", " + 101 event.values[2] + ")" + " diff(" + diff[0] + 102 " " + diff[1] + " " + diff[2] + ")"); 103 } 104 105 long now = android.os.SystemClock.uptimeMillis(); 106 if (now - mLastGestureTime > 1000) { 107 mLastGestureTime = 0; 108 109 float x = diff[0]; 110 float y = diff[1]; 111 boolean gestX = Math.abs(x) > 3; 112 boolean gestY = Math.abs(y) > 3; 113 114 if ((gestX || gestY) && !(gestX && gestY)) { 115 if (gestX) { 116 if (x < 0) { 117 Log.e("test", "<<<<<<<< LEFT <<<<<<<<<<<<"); 118 } else { 119 Log.e("test", ">>>>>>>>> RITE >>>>>>>>>>>"); 120 } 121 } else { 122 if (y < -2) { 123 Log.e("test", "<<<<<<<< UP <<<<<<<<<<<<"); 124 } else { 125 Log.e("test", ">>>>>>>>> DOWN >>>>>>>>>>>"); 126 } 127 } 128 mLastGestureTime = now; 129 } 130 } 131 } 132 133 public void onAccuracyChanged(Sensor sensor, int accuracy) { 134 } 135 }; 136 137 @Override onCreate(Bundle icicle)138 protected void onCreate(Bundle icicle) { 139 super.onCreate(icicle); 140 mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); 141 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 142 mView = new SampleView(this); 143 setContentView(mView); 144 if (false) Log.d(TAG, "create " + mSensorManager); 145 } 146 147 @Override onResume()148 protected void onResume() { 149 super.onResume(); 150 mSensorManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_FASTEST); 151 if (false) Log.d(TAG, "resume " + mSensorManager); 152 } 153 154 @Override onStop()155 protected void onStop() { 156 mSensorManager.unregisterListener(mListener); 157 super.onStop(); 158 if (false) Log.d(TAG, "stop " + mSensorManager); 159 } 160 161 private class SampleView extends View { 162 private Paint mPaint = new Paint(); 163 private Path mPath = new Path(); 164 private boolean mAnimate; 165 SampleView(Context context)166 public SampleView(Context context) { 167 super(context); 168 169 // Construct a wedge-shaped path 170 mPath.moveTo(0, -50); 171 mPath.lineTo(-20, 60); 172 mPath.lineTo(0, 50); 173 mPath.lineTo(20, 60); 174 mPath.close(); 175 } 176 177 @Override onDraw(Canvas canvas)178 protected void onDraw(Canvas canvas) { 179 Paint paint = mPaint; 180 181 canvas.drawColor(Color.WHITE); 182 183 paint.setAntiAlias(true); 184 paint.setColor(Color.BLACK); 185 paint.setStyle(Paint.Style.FILL); 186 187 int w = canvas.getWidth(); 188 int h = canvas.getHeight(); 189 int cx = w / 2; 190 int cy = h / 2; 191 192 canvas.translate(cx, cy); 193 if (mValues != null) { 194 canvas.rotate(-mValues[0]); 195 } 196 canvas.drawPath(mPath, mPaint); 197 } 198 199 @Override onAttachedToWindow()200 protected void onAttachedToWindow() { 201 mAnimate = true; 202 if (false) Log.d(TAG, "onAttachedToWindow. mAnimate="+mAnimate); 203 super.onAttachedToWindow(); 204 } 205 206 @Override onDetachedFromWindow()207 protected void onDetachedFromWindow() { 208 mAnimate = false; 209 if (false) Log.d(TAG, "onAttachedToWindow. mAnimate="+mAnimate); 210 super.onDetachedFromWindow(); 211 } 212 } 213 } 214