В этом стрелку на компасе показывает направление от вашего местоположения до Каабы (назначения Адреса)
вы можете просто использовать подшипники. Таким образом, вы получите прямой угол от вашего местоположения до места назначения.
Location userLoc=new Location("service Provider");
//get longitudeM Latitude and altitude of current location with gps class and set in userLoc
userLoc.setLongitude(longitude);
userLoc.setLatitude(latitude);
userLoc.setAltitude(altitude);
Location destinationLoc = new Location("service Provider");
destinationLoc.setLatitude(21.422487); //kaaba latitude setting
destinationLoc.setLongitude(39.826206); //kaaba longitude setting
float bearTo=userLoc.bearingTo(destinationLoc);
bearingTo даст вам диапазон от -180 до 180, что немного смутит. Нам нужно будет преобразовать это значение в диапазон от 0 до 360, чтобы получить правильное вращение.
Это таблица того, что мы действительно хотим, сравнивая с тем, что bearingTo дает нам
+-----------+--------------+
| bearingTo | Real bearing |
+-----------+--------------+
| 0 | 0 |
+-----------+--------------+
| 90 | 90 |
+-----------+--------------+
| 180 | 180 |
+-----------+--------------+
| -90 | 270 |
+-----------+--------------+
| -135 | 225 |
+-----------+--------------+
| -180 | 180 |
+-----------+--------------+
поэтому мы должны добавить этот код после bearTo
// If the bearTo is smaller than 0, add 360 to get the rotation clockwise.
if (bearTo < 0) {
bearTo = bearTo + 360;
//bearTo = -100 + 360 = 260;
}
вам нужно реализующий SensorEventListener и его функции (onSensorChanged, onAcurracyChabge) и написать весь код внутри onSensorChanged
Полный код для справки o е Qibla компас
public class QiblaDirectionCompass extends Service implements SensorEventListener{
public static ImageView image,arrow;
// record the compass picture angle turned
private float currentDegree = 0f;
private float currentDegreeNeedle = 0f;
Context context;
Location userLoc=new Location("service Provider");
// device sensor manager
private static SensorManager mSensorManager ;
private Sensor sensor;
public static TextView tvHeading;
public QiblaDirectionCompass(Context context, ImageView compass, ImageView needle,TextView heading, double longi,double lati,double alti) {
image = compass;
arrow = needle;
// TextView that will tell the user what degree is he heading
tvHeading = heading;
userLoc.setLongitude(longi);
userLoc.setLatitude(lati);
userLoc.setAltitude(alti);
mSensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
if(sensor!=null) {
// for the system's orientation sensor registered listeners
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);//SensorManager.SENSOR_DELAY_Fastest
}else{
Toast.makeText(context,"Not Supported", Toast.LENGTH_SHORT).show();
}
// initialize your android device sensor capabilities
this.context =context;
@Override
public void onCreate() {
// TODO Auto-generated method stub
Toast.makeText(context, "Started", Toast.LENGTH_SHORT).show();
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); //SensorManager.SENSOR_DELAY_Fastest
super.onCreate();
}
@Override
public void onDestroy() {
mSensorManager.unregisterListener(this);
Toast.makeText(context, "Destroy", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
Location destinationLoc = new Location("service Provider");
destinationLoc.setLatitude(21.422487); //kaaba latitude setting
destinationLoc.setLongitude(39.826206); //kaaba longitude setting
float bearTo=userLoc.bearingTo(destinationLoc);
//bearTo = The angle from true north to the destination location from the point we're your currently standing.(asal image k N se destination taak angle)
//head = The angle that you've rotated your phone from true north. (jaise image lagi hai wo true north per hai ab phone jitne rotate yani jitna image ka n change hai us ka angle hai ye)
GeomagneticField geoField = new GeomagneticField(Double.valueOf(userLoc.getLatitude()).floatValue(), Double
.valueOf(userLoc.getLongitude()).floatValue(),
Double.valueOf(userLoc.getAltitude()).floatValue(),
System.currentTimeMillis());
head -= geoField.getDeclination(); // converts magnetic north into true north
if (bearTo < 0) {
bearTo = bearTo + 360;
//bearTo = -100 + 360 = 260;
}
//This is where we choose to point it
float direction = bearTo - head;
// If the direction is smaller than 0, add 360 to get the rotation clockwise.
if (direction < 0) {
direction = direction + 360;
}
tvHeading.setText("Heading: " + Float.toString(degree) + " degrees");
RotateAnimation raQibla = new RotateAnimation(currentDegreeNeedle, direction, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
raQibla.setDuration(210);
raQibla.setFillAfter(true);
arrow.startAnimation(raQibla);
currentDegreeNeedle = direction;
// create a rotation animation (reverse turn degree degrees)
RotateAnimation ra = new RotateAnimation(currentDegree, -degree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
// how long the animation will take place
ra.setDuration(210);
// set the animation after the end of the reservation status
ra.setFillAfter(true);
// Start the animation
image.startAnimation(ra);
currentDegree = -degree;
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
код XML здесь
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/flag_pakistan">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/heading"
android:textColor="@color/colorAccent"
android:layout_centerHorizontal="true"
android:layout_marginBottom="100dp"
android:layout_marginTop="20dp"
android:text="Heading: 0.0" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/heading"
android:scaleType="centerInside"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true">
<ImageView
android:id="@+id/imageCompass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="@drawable/images_compass"/>
<ImageView
android:id="@+id/needle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:scaleType="centerInside"
android:src="@drawable/arrow2"/>
</RelativeLayout>
</RelativeLayout>
Вы можете проверить это сообщение блога на датчиках и ориентации экрана: http://android-developers.blogspot.com/2010/ 09/one-screen-turn-deserves-another.html – 2010-11-29 22:28:05
Спасибо, я уже прочитал эту статью. К сожалению, это не касается проблемы, поставленной в вопросе. – Damian 2010-11-29 23:40:00
Я нашел решение, в котором я работал хорошо http://stackoverflow.com/questions/7978618/rotating-an-imageview-like-a-compass-with-the-north-pole-set- где-то еще – dharan 2012-09-17 11:21:44