अपनी
पिछली पोस्ट में, मैंने तीनों विमानों में डिवाइस के झुकाव कोणों को कैसे प्राप्त किया
, इसके बारे में बात की। हालाँकि, जैसा कि यह निकला, विषय में इस्तेमाल किया गया तरीका एपीआई स्तर 8 (एंड्रॉइड 2.2) के बाद से
हटा दिया गया है । मैं इस त्रुटि को ठीक करूंगा और आपको बताऊंगा कि कट के तहत डेटा को सही तरीके से कैसे प्राप्त किया जाए।
पहला, थोड़ा सिद्धांत
Android के लिए प्रलेखन में, हमें SENSOR_ORIENTATION के बजाय विधि का उपयोग करने की पेशकश की गई है
getOrientation (float[] R, float[] values)
इस विधि में दो पैरामीटर हैं:
- आर - रोटेशनमैट्रिक्स या डिवाइस रोटेशन मैट्रिक्स;
- मान - प्रकार के तीन तत्वों की एक फ्लोट, जिसमें रेडियन में डिवाइस के झुकाव कोण लिखे गए हैं;
इसलिए, लक्ष्य को प्राप्त करने के लिए, हमें बस बहुत रोटेशन मैट्रिक्स प्राप्त करने की आवश्यकता है। और आप इसे दूसरी विधि से प्राप्त कर सकते हैं:
getRotationMatrix (float[] R, float[] I, float[] gravity, float[] geomagnetic)
पहले दो सरणियों में यह विधि रोटेशन मैट्रिक्स और डिवाइस के विचलन मैट्रिक्स (पृथ्वी के चुंबकीय ध्रुव;) से रखती है। ऐसा करने के लिए, उसे एक्सीलरोमीटर सेंसर और जियोमैग्नेटिक सेंसर से डेटा ट्रांसफर करना होगा। सौभाग्य से, TYPE_ACCELEROMETER और TYPE_MAGNETIC_FIELD को पदावनत नहीं किया जाता है। इसलिए, हम उनसे गवाही लेंगे।
अभ्यास के लिए आगे बढ़ते हैं
लेआउट हम पिछले उदाहरण के समान ले सकते हैं। यहाँ यह है:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView1" android:layout_width="60dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="25dp" android:text=" XY" /> <TextView android:id="@+id/xyValue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="25dp" android:text="0" /> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView3" android:layout_width="60dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="25dp" android:text=" XZ" /> /> <TextView android:id="@+id/xzValue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="25dp" android:text="0" /> </LinearLayout> <LinearLayout android:id="@+id/linearLayout3" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView5" android:layout_width="60dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="25dp" android:text=" ZY" /> <TextView android:id="@+id/zyValue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="25dp" android:text="0" /> </LinearLayout> </LinearLayout>
मुख्य गतिविधि में, चर घोषित करें:
private final SensorManager msensorManager;
OnCreate विधि SensorEventListener वर्ग के तरीकों को लागू करना चाहिए, इसलिए इसकी घोषणा बदल जाएगी:
public class Main extends Activity implements SensorEventListener{
और दो अनिवार्य तरीकों onAccuracyChanged और onSensorChanged को जोड़ा जाएगा।
और
setContentView से पहले हम लिखते हैं:
msensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); rotationMatrix = new float[16]; accelData = new float[3]; magnetData = new float[3]; OrientationData = new float[3]; xyView = (TextView) findViewById(R.id.xyValue);
यदि आप मेरी
अंतिम पोस्ट पढ़ते हैं, तो आपने कुछ भी नया नहीं देखा है। यदि नहीं, तो आपको यह जानना होगा कि पहली पंक्ति में हमें सेंसर प्रबंधक की वस्तु मिलती है।
अब हम onResume मेथड बनाएंगे, जिसमें हम स्पष्ट करेंगे कि हमें कौन सा सेंसर डेटा चाहिए:
@Override protected void onResume() { super.onResume(); msensorManager.registerListener(this, msensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI ); msensorManager.registerListener(this, msensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI ); }
यहां हम रजिस्टरलिस्टनर विधि को सेंसर के प्रकार की आवश्यकता करते हैं (
सेंसर पदनामों की एक
पूरी सूची ) और डेटा अपडेट की आवृत्ति (शायद SENSOR_DELAY_NORMAL, SENSOR_DELAY_UI, SENSOR_DELAY_GAME, या SENSOR_DELAY_FASTEST बढ़ते आवृत्ति क्रम में)।
ताकि हमारा कार्यक्रम स्मार्टफोन के संसाधनों को न खाए, ऑनपॉइंट इवेंट द्वारा कम से कम किया जा रहा है: सेंसर के डेटा को "हटाएं":
@Override protected void onPause() { super.onPause(); msensorManager.unregisterListener(this); }
चलो एक नई विधि बनाते हैं जिसमें सेंसर से डेटा सेंसर के अनुरूप सरणी में दर्ज किया जाएगा। LoadNewSensorData विधि को कॉल करें:
private void loadNewSensorData(SensorEvent event) { final int type = event.sensor.getType();
खैर, यह लगभग है! यह केवल onSensorChanged ईवेंट हैंडलर लिखने के लिए बना हुआ है:
public void onSensorChanged(SensorEvent event) { loadNewSensorData(event);
सब कुछ तैयार है! अब मैंने अपनी गलती को सुधार लिया और आपको सिखाया कि बिना सेंसर के डेटा कैसे प्राप्त किया जा सकता है। :)
अंत में, मैं
स्रोतों को लिंक प्रदान करूँगा,
समाप्त APK और
सूचना के
स्रोत के लिए ।
पुनश्च: आपने संभवतः पिछली सूची में अशक्त होने के विपरीत चर का एक अतिरिक्त चेक देखा। इसके बिना, कंपाइलर java.lang.NullPointerException को फेंकता है। यदि कोई किसी को समझाएगा या इंगित करेगा, तो मैं आभारी रहूंगा।
UPD: इस समस्या का हल
फायरएक्सल के लिए धन्यवाद।
स्वैप सेट करें और onCreate में findViewById के साथ पंक्तियों को देखें
उसके बाद, आप अतिरिक्त चेक निकाल सकते हैं।