1
Android用の金属探知機アプリケーションを開発したいので、GeomagneticFieldネイティブクラスと一緒に磁力計を使用したいと思います。これは私がやっていることです:Androidのユーザー位置を取得する
- 磁力計からx、y、z値を取り出し、磁場をx^2 + y^2 + z^2として計算します。
- GeomagneticFieldクラスによって与えられた唯一のコンストラクタを使用して地磁気場を計算します。私の座標を計算するために、私はLocation Managerとそれに関連する他のクラスを使用しています。
- これらの磁場を比較して金属を検出します。
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を返し考えさせる:
は、ここに私のコードです。 何が間違っていますか?
あなたのソリューションの作品を取得します。しかし、磁力計から得られた値をGeomagneticFieldオブジェクトと比較して金属を検出する正しい方法は何ですか? – leqo
残念ながら、私はあなたのプロセスの論理に悪い知らせをしています。 stackoverflowで私はあなたの質問への答えを見つけた:http://stackoverflow.com/questions/16371777/how-to-detect-a-metal-using-magnetic-sensor-in-android-phone。私はそれを理解しているので、あなたのメソッドgetField()のエラーmagnitを決定する。 –