简体   繁体   中英

Rotation Vector Sensor in Android App not Working on my Moto G

So I have an app written in Android Eclipse that displays a map over a fixed marker and then moves around based on the change in rotation using a rotation vector sensor. When I ran it on my device, the screen would not move when the phone was tilted. I tried everything and even had my professor look at it. He could not find the problem in the code. Finally we ran it on his device and it worked perfectly! I have a Moto G and I was wondering if anyone new why this code works on other android devices but not mine. Below is the code for the project.

package com.example.flymap_awc;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.util.Log;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends Activity implements SensorEventListener {
  static final LatLng HAMBURG = new LatLng(53.558, 9.927);
  static final LatLng KIEL = new LatLng(53.551, 9.993);
  private GoogleMap map;

  private SensorManager mSensorManager;

  private double oldx = 0, oldy=0, oldz = 0;


  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
        .getMap();
    Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
        .title("Hamburg"));
    Marker kiel = map.addMarker(new MarkerOptions()
        .position(KIEL)
        .title("Kiel")
        .snippet("Kiel is cool")
        .icon(BitmapDescriptorFactory
            .fromResource(R.drawable.ic_launcher)));

    // Move the camera instantly to hamburg with a zoom of 15.
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

    // Zoom in, animating the camera.
    map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

    mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

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


    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR)
        {

            if(oldx==0 && oldy ==0 && oldz ==0 ){
            // if this is the first run (oldx/y/z=0, get the initial orientation
                oldx = event.values[0];
                oldy = event.values[1];
                oldz =event.values[2];

               //set oldx to event.values[0], etc.
            }

            // get change in rotation amount store as dx,dy,dz
            double dx = oldx - event.values[0];
            double dy = oldy - event.values[1];
            double dz = oldz - event.values[2];
            double dTotal = Math.abs(dx) + Math.abs(dy) + Math.abs(dz);
            if (dTotal > 0.05)
            {
                double lat = map.getCameraPosition().target.latitude;
                double lng = map.getCameraPosition().target.longitude;

                lat +=dx;
                lng -=dy;

                Log.println(100,"100","lat, lng, dx, dy" + lat + lng+dx+dy);

                LatLng loc = new LatLng(lat, lng);
                map.moveCamera(CameraUpdateFactory.newLatLng(loc));

                oldx = event.values[0];
                oldy = event.values[1];
                oldz = event.values[2];

            }

            //filter out noise where Math.abs(dx) + Math.abs(dy)+ Math.abs(dz) > 0.05
            // get current lat lng
            //that my map camera is point at (or targeting)


            // add to the lat and lng based on dx dy
            //may want to compensate for zoom inverse proportionally

            //may have to do lng -=dy to move intuitively
            //move camera using camerupdatefactory to the new LatLng(lat,lng)

            // update old oldy oldz

        }
    }







protected void onResume(){
        super.onResume();
        // register this class as a listener for the orientation sensor
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
                SensorManager.SENSOR_DELAY_NORMAL);

    }
    protected void onPause(){
        super.onPause();
        //unregister listener
        mSensorManager.unregisterListener(this);

    }
} 

And here is the manifest code

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.flymap_awc"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

 <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>

    <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- The following two permissions are not required to use
     Google Maps Android API v2, but are recommended. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
         >

        <meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />

        <activity
            android:name="com.example.flymap_awc.MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


    <meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyDC4pK6_RmiSsDoWFAEmTUO2DRynTR0lik"/>
    </application>

</manifest>

ROTATION_VECTOR requires gyroscope to work, that's why.

Underlying base sensor(s): Accelerometer, Gyroscope AND Magnetometer

One of my app stopped working too due to that, on the Moto G.

I just had a quick glance over your code. I think the problem is that your code is assuming that the sensor is present and successfully registered. In my limited experience, the sensor may be unavailable due to either not existing in the device or being faulty.

Try doing the following checks and see what you get:

  • Ensure mSensorManager.registerListener returns true .
  • Ensure mSensorManager.getDefaultSensor doesn't return null .
  • Ensure onSensorChanged gets called. You could put a breakpoint in it or add a line to write a log message.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM