概要
GPSを理解したかった。
android1.6でナビ作って見た。
写真
地図は、出ない。
方角と距離で、辿り着く。
赤丸が目的地、青丸が北。
サンプルコード
package com.ohisamallc.ohiapp128;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.Toast;
public class ohiapp34 extends Activity implements LocationListener, SensorEventListener
{
private static final String TAG = "ohiapp34";
private static final String[] locationProviders = {
LocationManager.GPS_PROVIDER
};
private LocationManager locationManager;
private rdView rdView;
private EditText et0;
private EditText et1;
private SensorManager sensorManager;
private Sensor orienter;
private Sensor magter;
private Sensor accter;
private Location locb;
private static final int MATRIX_SIZE = 16;
float[] inR = new float[MATRIX_SIZE];
float[] outR = new float[MATRIX_SIZE];
float[] I = new float[MATRIX_SIZE];
float[] ov = new float[3];
float[] acc = new float[3];
float[] mag = new float[3];
private GeomagneticField geomagnetic;
private String add;
@Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Bundle extra = intent.getExtras();
add = extra.getString("add");
String[] csv = add.split(" > ");
String[] a = csv[1].split(",");
rdView = new rdView(this);
TableLayout tableLayout = new TableLayout(this);
et0 = new EditText(this);
et0.setWidth(150);
et1 = new EditText(this);
et1.setWidth(220);
et0.setText(csv[0]);
et1.setText(csv[1]);
TableRow tableRow1 = new TableRow(this);
tableRow1.addView(et0);
TableRow tableRow2 = new TableRow(this);
tableRow2.addView(et1);
tableLayout.addView(tableRow1, new TableLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
tableLayout.addView(tableRow2, new TableLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
tableLayout.addView(rdView, new TableLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
setContentView(tableLayout);
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
for (String name : locationProviders)
{
LocationProvider prov = locationManager.getProvider(name);
if (prov != null)
{
locationManager.requestLocationUpdates(name, 60000, 0f, this);
Location loc1 = locationManager.getLastKnownLocation(name);
if (loc1 != null)
{
}
}
}
locb = new Location(LocationManager.GPS_PROVIDER);
locb.setLatitude(new Float(a[0]));
locb.setLongitude(new Float(a[1]));
rdView.setlocb(locb);
sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
List<Sensor> list;
list = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if (list.size() > 0) orienter = list.get(0);
list = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
if (list.size() > 0) magter = list.get(0);
list = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (list.size() > 0) accter = list.get(0);
}
@Override protected void onResume()
{
super.onResume();
if (orienter != null)
{
sensorManager.registerListener(this, orienter, SensorManager.SENSOR_DELAY_UI);
}
if (magter != null)
{
sensorManager.registerListener(this, magter, SensorManager.SENSOR_DELAY_UI);
}
if (accter != null)
{
sensorManager.registerListener(this, accter, SensorManager.SENSOR_DELAY_UI);
}
}
@Override public void onDestroy()
{
locationManager.removeUpdates(this);
locationManager = null;
sensorManager.unregisterListener(this);
super.onDestroy();
}
public void onLocationChanged(Location loc)
{
synchronized (this)
{
if (loc.getProvider().equals(LocationManager.GPS_PROVIDER))
{
rdView.setloc(loc);
rdView.invalidate();
float latitude = new Double(loc.getLatitude()).floatValue();
float longitude = new Double(loc.getLongitude()).floatValue();
float altitude = new Double(loc.getAltitude()).floatValue();
geomagnetic = new GeomagneticField(latitude, longitude, altitude, new Date().getTime());
}
}
}
public void onProviderEnabled(String provider)
{
synchronized (this)
{
if (provider.equals(LocationManager.GPS_PROVIDER))
{
}
}
}
public void onProviderDisabled(String provider)
{
synchronized (this)
{
if (provider.equals(LocationManager.GPS_PROVIDER))
{
}
}
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
synchronized (this)
{
if (status == LocationProvider.OUT_OF_SERVICE)
{
}
if (provider.equals(LocationManager.GPS_PROVIDER))
{
}
}
}
@Override public void onAccuracyChanged(Sensor arg0, int arg1)
{
}
@Override public void onSensorChanged(SensorEvent event)
{
if (event.sensor == orienter)
{
rdView.setoriention(event.values);
}
if (event.sensor == magter)
{
mag = event.values.clone();
}
if (event.sensor == accter)
{
acc = event.values.clone();
}
if (mag != null && acc != null)
{
SensorManager.getRotationMatrix(inR, null, acc, mag);
SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X, outR);
SensorManager.getOrientation(inR, ov);
rdView.setov(ov);
float[] rotate = new float[9];
SensorManager.getRotationMatrix(rotate, null, acc, mag);
final float[] orient = new float[3];
SensorManager.getOrientation(rotate, orient);
rdView.invalidate();
float magneticNorth = event.values[SensorManager.DATA_X];
if (geomagnetic != null)
{
float trueNorth = magneticNorth + geomagnetic.getDeclination();
rdView.settn(trueNorth);
}
}
}
}
class rdView extends View
{
static final int NUM_SATS = 32;
private int flg = 1;
private Location loc;
private Calendar calen = Calendar.getInstance();
private float[] ori;
private float distance;
private float bearing;
private Location locb;
float[] ov = new float[3];
float tn;
private Path path = new Path();
private RectF rect = new RectF();
public rdView(Context context)
{
super(context);
rect.set(-0.5f, -0.5f, 0.5f, 0.5f);
path.addRoundRect(new RectF(-0.52f, -0.2f, -0.37f, 0.3f), 0.07f, 0.07f, Path.Direction.CW);
path.addRoundRect(new RectF(0.38f, -0.2f, 0.53f, 0.3f), 0.07f, 0.07f, Path.Direction.CW);
path.addRect(new RectF(-0.34f, -0.17f, 0.36f, 0.3f), Path.Direction.CW);
path.addRoundRect(new RectF(-0.34f, 0.25f, 0.36f, 0.35f), 0.05f, 0.05f, Path.Direction.CW);
path.addRoundRect(new RectF(-0.19f, 0.25f, -0.04f, 0.6f), 0.07f, 0.07f, Path.Direction.CW);
path.addRoundRect(new RectF(0.06f, 0.25f, 0.21f, 0.6f), 0.07f, 0.07f, Path.Direction.CW);
path.addArc(new RectF(-0.34f, -0.52f, 0.36f, 0.12f), 180, 180);
path.moveTo(-0.14f, -0.45f);
path.lineTo(-0.24f, -0.6f);
path.lineTo(-0.23f, -0.61f);
path.lineTo(-0.13f, -0.46f);
path.moveTo(0.16f, -0.45f);
path.lineTo(0.26f, -0.6f);
path.lineTo(0.28f, -0.61f);
path.lineTo(0.18f, -0.46f);
}
public void settn(float tn)
{
this.tn = tn;
}
public void setov(float[] ov)
{
this.ov = ov;
}
public void setoriention(float[] ori)
{
this.ori = ori;
}
public void setlocb(Location locb)
{
this.locb = locb;
}
public void setloc(Location loc)
{
this.loc = loc;
}
public void setflg(int flg)
{
this.flg = flg;
}
protected void onDraw(Canvas canvas)
{
Paint paint = new Paint();
Paint paint1 = new Paint();
final int outer = 0xFFC0C0C0;
final int inner = 0xFFff7010;
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2f);
paint.setStyle(Paint.Style.STROKE);
int centerX = this.getWidth() / 2;
int centerY = this.getHeight() / 2;
float maxRadius = (Math.min(this.getHeight() - 20, this.getWidth()) - 20) / 2;
double[] elevations = new double[] {0, Math.PI / 2, Math.PI / 3, Math.PI / 6};
for (double elevation : elevations)
{
double radius = (double) Math.cos(elevation) * maxRadius;
}
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setTextSize(30);
if (flg == 1)
{
if (loc != null)
{
bearing = loc.bearingTo(locb);
distance = loc.distanceTo(locb);
double h = (double) Math.cos((0 * Math.PI) / 180) * maxRadius;
int satX = (int) (centerX + h * Math.sin(((360 - ori[0]) * Math.PI) / 180));
int satY = (int) (centerY - h * Math.cos(((360 - ori[0]) * Math.PI) / 180));
paint.setColor(Color.BLUE);
canvas.drawCircle(satX, satY, 10, paint);
h = (double) Math.cos((30 * Math.PI) / 180) * maxRadius;
satX = (int) (centerX + h * Math.sin(((360 + bearing - ori[0]) * Math.PI) / 180));
satY = (int) (centerY - h * Math.cos(((360 + bearing - ori[0]) * Math.PI) / 180));
paint.setColor(Color.RED);
canvas.drawCircle(satX, satY, 10, paint);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(centerX, centerY);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
paint1.setColor(outer);
canvas.scale(200, 200);
canvas.drawOval(rect, paint1);
canvas.restore();
canvas.scale(140, 140);
paint1.setColor(Color.YELLOW);
canvas.rotate(360 + bearing - ori[0]);
canvas.drawPath(path, paint1);
canvas.restore();
paint.setColor(Color.DKGRAY);
String p;
p = "distance " + new Float(distance / 1000).toString() + " km";
canvas.drawText(p, 10, 30, paint);
p = "Lat " + new Float(loc.getLatitude()).toString();
canvas.drawText(p, 10, 60, paint);
p = "Lon " + new Float(loc.getLongitude()).toString();
canvas.drawText(p, 10, 90, paint);
p = "Alt " + new Float(loc.getAltitude()).toString() + "m";
canvas.drawText(p, 10, 150, paint);
if (loc.getTime() > 0)
{
calen.setTimeInMillis(loc.getTime());
SimpleDateFormat a = new SimpleDateFormat("HH:mm:ss");
canvas.drawText(a.format(calen.getTime()), 10, 210, paint);
}
}
}
}
}
以上。