2016-08-10 11 views
1

안드로이드 용 금속 탐지기 응용 프로그램을 개발하고 싶습니다. 그래서 자력계를 GeomagneticField 기본 클래스와 함께 사용하고 싶습니다. 이것은 내가하는 일입니다 :안드로이드에서 사용자 위치 얻기

  1. 자력계에서 x, y, z 값을 검색하고 자기장을 x^2 + y^2 + z^2로 계산합니다.
  2. GeomagneticField 클래스에 의해 주어진 유일한 생성자를 사용하여 Geomagnetic 필드를 계산하십시오. 내 좌표를 계산하려면 위치 관리자와 관련된 다른 클래스를 사용하고 있습니다.
  3. 금속을 탐지하기 위해 자기장을 비교하십시오.

    public class MainActivity extends AppCompatActivity implements SensorEventListener, LocationListener { 
    
        SensorManager man; 
        Sensor sensor; 
        SensorEventListener thisActivity = this; 
        double earthField; 
        Location l; 
        LocationManager locationManager; 
    
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         setContentView(R.layout.activity_main); 
    
         man = (SensorManager) getSystemService(SENSOR_SERVICE); 
         sensor = man.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 
    
         l = getLocation(); 
         if(l != null) 
         { 
          GeomagneticField gmf = new GeomagneticField((float) l.getLatitude(), 
            (float) l.getLongitude(), 
            (float) l.getAltitude(), 
            l.getTime()); 
          earthField = getEarthField(gmf); 
         } 
         else 
         { 
          ((TextView)findViewById(R.id.debug)).setText("l è nullo"); 
         } 
        } 
    
        @Override 
        protected void onPause() { 
         super.onPause(); 
         man.unregisterListener(this); 
        } 
    
        @Override 
        protected void onResume() { 
         super.onResume(); 
    
         man.registerListener(thisActivity, 
           sensor, 
           Sensor.TYPE_MAGNETIC_FIELD, 
           SensorManager.SENSOR_DELAY_NORMAL); 
        } 
    
        @Override 
        public void onSensorChanged(SensorEvent event) { 
         float x = event.values[0]; 
         float y = event.values[1]; 
         float z = event.values[2]; 
         float magneticField = (float) getField(x, y, z); 
    
         ((TextView) findViewById(R.id.xreading)).setText("X: " + x + ""); 
         ((TextView) findViewById(R.id.yreading)).setText("Y: " + y + ""); 
         ((TextView) findViewById(R.id.zreading)).setText("Z: " + z + ""); 
    
         ((TextView) findViewById(R.id.earthTxt)).setText("Earth: " + earthField); 
         ((TextView) findViewById(R.id.fieldTxt)).setText("Calculated: " + magneticField); 
    
         // I'm not sure i have to repeat this step inside OnSensorChanged. 
         // Instructions inside the if statement are executed by onCreate, too. 
         if(l != null) 
         { 
          GeomagneticField gmf = new GeomagneticField((float) l.getLatitude(), 
            (float) l.getLongitude(), 
            (float) l.getAltitude(), 
            l.getTime()); 
          earthField = getEarthField(gmf); 
         } 
    
    
         TextView metalNearby = (TextView) findViewById(R.id.metalNearby); 
    
         if (magneticField > 1.4*earthField || magneticField < 0.6*earthField) { 
          //there is a high probability that some metal is close to the sensor 
          metalNearby.setText("Ho rilevato un metallo"); 
         } 
         else { 
          metalNearby.setText("Sto cercando..."); 
         } 
        } 
    
        private double getEarthField(GeomagneticField gmf) { 
         return getField(gmf.getX(), gmf.getY(), gmf.getZ()); 
        } 
    
        private double getField(float x, float y, float z) { 
         return Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2); 
        } 
    
        @Override 
        public void onAccuracyChanged(Sensor sensor, int accuracy) { } 
    
        public Location getLocation() 
        { 
         Location location = null; 
         try 
         { 
          locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
          locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 
    
          // Creating an empty criteria object 
          Criteria criteria = new Criteria(); 
    
          // Getting the name of the provider that meets the criteria 
          String provider = locationManager.getBestProvider(criteria, false); 
    
          try 
          { 
           location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
          } 
          catch (SecurityException e) 
          { 
           e.printStackTrace(); 
          } 
         } 
         catch (Exception ex) 
         { 
          ex.printStackTrace(); 
         } 
    
         finally 
         { 
          return location; 
         } 
        } 
    
        @Override 
        public void onLocationChanged(Location location) 
        { 
         l = location; 
        } 
    

    내 문제가 변수 earthField가 항상 0.0으로 평가하는이며,이 날 메소드의 getLocation (정의 된 사용자)는 항상 null을 반환 생각하게한다 :

여기 내 코드입니다. 내가 뭘 잘못 했니? 당신이 새로운 위치를 몇 시간마다 또는 일부 여행 미터마다 필요한 경우

답변

0

, 그 같은 코드를 사용하려고 :

public void getLocation() { 
     try { 
      mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 
      boolean isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
      boolean isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      if (isNetworkEnabled) { 
       mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE, mLocationListener); 
      } 

      if (isGPSEnabled) { 
       mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE, mLocationListener); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

MIN_TIME을 -이 시간을 통해 시스템으로 위치를

MIN_DISTANCE을받을 것이다 - 거리 만 같음

mLocationListener - 청취자가있는 청취자

+0

귀하의 솔루션이 작동합니다. 그러나, 금속 탐지를 위해 자력계에서 얻은 값과 GeomagneticField 객체를 비교하는 올바른 방법은 무엇입니까? – leqo

+0

불행히도 나는 당신의 프로세스의 논리에 대해 잘못된 정보를 가지고있다. stackoverflow에서 귀하의 질문에 대한 답변을 찾았 : http://stackoverflow.com/questions/16371777/how-to-detect-a-metal-using-magnetic-sensor-in-android-phone. 내가 이해하기 때문에, 당신의 메소드 getField()에서 magnitute를 결정하는 데 오류가있다. –