Je voudrais développer une application de détecteur de métaux pour Android et pour ce faire, j'utilise le magnétomètre à côté de la classe native GeomagneticField. Voici ce que je suis en train de faire:Obtenir l'emplacement de l'utilisateur sur Android
- Récupérer les valeurs x, y, z du magnétomètre et calculer le champ magnétique comme x^2 + y^2 + z^2.
- Calculez le champ géomagnétique en utilisant le seul constructeur donné par la classe GeomagneticField. Pour calculer mes coordonnées, j'utilise le gestionnaire de localisation et les autres classes qui s'y rapportent.
- Comparer les champs magnétiques pour détecter un métal.
Voici mon code:
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;
}
Mon problème est que la variable earthField évalue toujours à 0.0 et cela me fait penser la méthode getLocation (définie par l'utilisateur) renvoie toujours null. Qu'est-ce que je fais de mal?
Votre solution fonctionne. Cependant, quelle est la bonne façon de comparer les valeurs obtenues à partir du magnétomètre avec l'objet GeomagneticField afin de détecter les métaux? – leqo
Malheureusement, j'ai été mal informé dans la logique de votre processus. Sur stackoverflow j'ai trouvé la réponse à votre question: http://stackoverflow.com/questions/16371777/how-to-detect-a-metal-using-magnetic-sensor-in-android-phone. Si je comprends bien, une erreur dans votre méthode getField() pour déterminer magnat. –