• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 android.view;
18 
19 import android.content.Context;
20 import android.hardware.Sensor;
21 import android.hardware.SensorEvent;
22 import android.hardware.SensorEventListener;
23 import android.hardware.SensorManager;
24 import android.util.Config;
25 import android.util.Log;
26 
27 /**
28  * Helper class for receiving notifications from the SensorManager when
29  * the orientation of the device has changed.
30  */
31 public abstract class OrientationEventListener {
32     private static final String TAG = "OrientationEventListener";
33     private static final boolean DEBUG = false;
34     private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
35     private int mOrientation = ORIENTATION_UNKNOWN;
36     private SensorManager mSensorManager;
37     private boolean mEnabled = false;
38     private int mRate;
39     private Sensor mSensor;
40     private SensorEventListener mSensorEventListener;
41     private OrientationListener mOldListener;
42 
43     /**
44      * Returned from onOrientationChanged when the device orientation cannot be determined
45      * (typically when the device is in a close to flat position).
46      *
47      *  @see #onOrientationChanged
48      */
49     public static final int ORIENTATION_UNKNOWN = -1;
50 
51     /**
52      * Creates a new OrientationEventListener.
53      *
54      * @param context for the OrientationEventListener.
55      */
OrientationEventListener(Context context)56     public OrientationEventListener(Context context) {
57         this(context, SensorManager.SENSOR_DELAY_NORMAL);
58     }
59 
60     /**
61      * Creates a new OrientationEventListener.
62      *
63      * @param context for the OrientationEventListener.
64      * @param rate at which sensor events are processed (see also
65      * {@link android.hardware.SensorManager SensorManager}). Use the default
66      * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL
67      * SENSOR_DELAY_NORMAL} for simple screen orientation change detection.
68      */
OrientationEventListener(Context context, int rate)69     public OrientationEventListener(Context context, int rate) {
70         mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
71         mRate = rate;
72         mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
73         if (mSensor != null) {
74             // Create listener only if sensors do exist
75             mSensorEventListener = new SensorEventListenerImpl();
76         }
77     }
78 
registerListener(OrientationListener lis)79     void registerListener(OrientationListener lis) {
80         mOldListener = lis;
81     }
82 
83     /**
84      * Enables the OrientationEventListener so it will monitor the sensor and call
85      * {@link #onOrientationChanged} when the device orientation changes.
86      */
enable()87     public void enable() {
88         if (mSensor == null) {
89             Log.w(TAG, "Cannot detect sensors. Not enabled");
90             return;
91         }
92         if (mEnabled == false) {
93             if (localLOGV) Log.d(TAG, "OrientationEventListener enabled");
94             mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
95             mEnabled = true;
96         }
97     }
98 
99     /**
100      * Disables the OrientationEventListener.
101      */
disable()102     public void disable() {
103         if (mSensor == null) {
104             Log.w(TAG, "Cannot detect sensors. Invalid disable");
105             return;
106         }
107         if (mEnabled == true) {
108             if (localLOGV) Log.d(TAG, "OrientationEventListener disabled");
109             mSensorManager.unregisterListener(mSensorEventListener);
110             mEnabled = false;
111         }
112     }
113 
114     class SensorEventListenerImpl implements SensorEventListener {
115         private static final int _DATA_X = 0;
116         private static final int _DATA_Y = 1;
117         private static final int _DATA_Z = 2;
118 
onSensorChanged(SensorEvent event)119         public void onSensorChanged(SensorEvent event) {
120             float[] values = event.values;
121             int orientation = ORIENTATION_UNKNOWN;
122             float X = -values[_DATA_X];
123             float Y = -values[_DATA_Y];
124             float Z = -values[_DATA_Z];
125             float magnitude = X*X + Y*Y;
126             // Don't trust the angle if the magnitude is small compared to the y value
127             if (magnitude * 4 >= Z*Z) {
128                 float OneEightyOverPi = 57.29577957855f;
129                 float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi;
130                 orientation = 90 - (int)Math.round(angle);
131                 // normalize to 0 - 359 range
132                 while (orientation >= 360) {
133                     orientation -= 360;
134                 }
135                 while (orientation < 0) {
136                     orientation += 360;
137                 }
138             }
139             if (mOldListener != null) {
140                 mOldListener.onSensorChanged(Sensor.TYPE_ACCELEROMETER, event.values);
141             }
142             if (orientation != mOrientation) {
143                 mOrientation = orientation;
144                 onOrientationChanged(orientation);
145             }
146         }
147 
onAccuracyChanged(Sensor sensor, int accuracy)148         public void onAccuracyChanged(Sensor sensor, int accuracy) {
149 
150         }
151     }
152 
153     /*
154      * Returns true if sensor is enabled and false otherwise
155      */
canDetectOrientation()156     public boolean canDetectOrientation() {
157         return mSensor != null;
158     }
159 
160     /**
161      * Called when the orientation of the device has changed.
162      * orientation parameter is in degrees, ranging from 0 to 359.
163      * orientation is 0 degrees when the device is oriented in its natural position,
164      * 90 degrees when its left side is at the top, 180 degrees when it is upside down,
165      * and 270 degrees when its right side is to the top.
166      * {@link #ORIENTATION_UNKNOWN} is returned when the device is close to flat
167      * and the orientation cannot be determined.
168      *
169      * @param orientation The new orientation of the device.
170      *
171      *  @see #ORIENTATION_UNKNOWN
172      */
onOrientationChanged(int orientation)173     abstract public void onOrientationChanged(int orientation);
174 }
175