android指南针

来源:互联网 发布:json(",")什么意思 编辑:程序博客网 时间:2024/04/28 07:39

主要利用方向传感器:

  方向传感器返回三个角度:按照顺序

  1.表示手机顶部与正北的夹角
  values[0]: 方位角

  2.表示手机顶部或尾部翘起的高度
  values[1]: 倾斜角

  3.表示手机左侧或者右侧抬起的高度
  values[2]: 旋转角

  思路:程序先准备一张指南针图片,改图片上方向指南针指向北方。接下来开发一个检测方向的传感器,程序检测到手机顶部绕z转过的多少度,让指南针图片反转过多少度,所以只需添加一张图片,并让图片总是反转方向传感器返回的第一个角度值既可


代码如下:
Welcome.java

package com.hhf.compass;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.ImageView;

public class Welcome extends Activity{

private AlphaAnimation myAnimation_Alpha;
private ImageView iv;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

iv = (ImageView) findViewById(R.id.ivStart);
myAnimation_Alpha=new AlphaAnimation(1.0f, 0.1f);
myAnimation_Alpha.setDuration(3000);
myAnimation_Alpha.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub

}

@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub

}

@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
Intent intent = new Intent(Welcome.this,Compass.class);
startActivity(intent);
finish();
}
});
}

@Override
public void onStart() {

super.onStart();

iv.startAnimation(myAnimation_Alpha);
}

}

Compass.java

package com.hhf.compass;


import android.app.Activity;
import android.content.Intent;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

public class Compass extends Activity implements SensorListener {
private static final String TAG = "Compass";

private ImageView ImgCompass;
private TextView OrientText;
private SensorManager sm = null;
private RotateAnimation myAni = null;
private float DegressQuondam = 0.0f;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.compass);

OrientText = (TextView) findViewById(R.id.OrientText);
ImgCompass = (ImageView) findViewById(R.id.ivCompass);
}
@Override
public void onStart() {
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
super.onStart();

}

@Override
protected void onResume() {
super.onResume();
sm.registerListener(this, SensorManager.SENSOR_ORIENTATION
| SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
protected void onStop() {
sm.unregisterListener(this);
super.onStop();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 1, 1, "旋转").setIcon(R.drawable.icon);
menu.add(0, 2, 2, "关于").setIcon(R.drawable.icon);
menu.add(0, 3, 3, "退出").setIcon(R.drawable.quit);

return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 1:
AniRotateImage(DegressQuondam + 90.0f);
break;
case 2: {
Intent theActivity = new Intent(this, About.class);
startActivity(theActivity);
break;
}
case 3:
finish();
break;
}

return super.onOptionsItemSelected(item);
}

private void AniRotateImage(float fDegress) {
myAni = new RotateAnimation(DegressQuondam, fDegress,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
myAni.setDuration(300);
myAni.setFillAfter(true);// 为实现指南针效果,设置旋转后不还原原图
ImgCompass.startAnimation(myAni);
DegressQuondam = fDegress;
}

public void onSensorChanged(int sensor, float[] values) {
synchronized (this) {
if (sensor == SensorManager.SENSOR_ORIENTATION) {
Log.d(TAG, "onSensorChanged: " + sensor + ", x: " + values[0]
+ ", y: " + values[1] + ", z: " + values[2]);

// OrientText.setText("--- NESW ---");
if (Math.abs(values[0] - DegressQuondam) < 1)
return;

switch ((int) values[0]) {
case 0: // North 北
OrientText.setText("正北");
break;
case 90: // East 东
OrientText.setText("正东");
break;
case 180: // South 南
OrientText.setText("正南");
break;
case 270: // West 西
OrientText.setText("正西");
break;
default: {
int v = (int) values[0];
if (v > 0 && v < 90) {
OrientText.setText("北偏东" + v);
}

if (v > 90 && v < 180) {
v = 180 - v;
OrientText.setText("南偏东" + v);
}

if (v > 180 && v < 270) {
v = v - 180;
OrientText.setText("南偏西" + v);
}
if (v > 270 && v < 360) {
v = 360 - v;
OrientText.setText("北偏西" + v);
}
}
}

((TextView) findViewById(R.id.OrientValue)).setText(String.valueOf(values[0]));

if (DegressQuondam != -values[0])
AniRotateImage(-values[0]);
}

// if (sensor == SensorManager.SENSOR_ACCELEROMETER) { // //}

}
}

public void onAccuracyChanged(int sensor, int accuracy) {
Log.d(TAG, "onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
}
}

About.java

package com.hhf.compass;


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;

public class About extends Activity {

public void onCreate(Bundle savedInstanceState) {
StringBuilder sb = new StringBuilder(getString(R.string.app_name));
sb.append(" ");
sb.append(getString(R.string.app_ver));

super.onCreate(savedInstanceState);

this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.about);


((TextView) findViewById(R.id.tvTitle)).setText(sb.toString());
((TextView) findViewById(R.id.tvContent)).setText(R.string.aboutContent);

((Button) findViewById(R.id.btnOk)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
}

对应布局文件:
main.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ivStart"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:src="http://ranfeng0610.blog.163.com/blog/@drawable/compass" >

</ImageView>

compass.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<TextView
android:id="@+id/OrientText"
android:layout_width="fill_parent"
android:layout_height="90dp"
android:gravity="center"
android:text="NESW"
android:textColor="#ffffff"
android:textSize="25px"
android:textStyle="bold" >
</TextView>

<ImageView
android:id="@+id/ivCompass"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="http://ranfeng0610.blog.163.com/blog/@drawable/bg" >
</ImageView>

<TextView
android:id="@+id/OrientValue"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:gravity="right|center_vertical"
android:text="NESW"
android:textColor="#ffffff"
android:textSize="12px"
android:textStyle="bold" >
</TextView>

</LinearLayout>

about.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/TableLayout"
android:layout_width="280dp"
android:layout_height="200dp" >

<TableRow
android:id="@+id/TRtitle"
android:layout_width="fill_parent"
android:layout_height="80dp" >

<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/TLtitle"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TableRow
android:id="@+id/TRtt"
android:layout_width="fill_parent"
android:layout_height="80dp" >

<ImageView
android:id="@+id/ImageView01"
android:layout_width="80dp"
android:layout_gravity="center"
android:src="http://ranfeng0610.blog.163.com/blog/@drawable/pisces" >
</ImageView>

<TextView
android:id="@+id/tvTitle"
android:layout_width="200dp"
android:layout_height="70dp"
android:gravity="center"
android:text="@string/app_name"
android:textColor="#ffffff"
android:textSize="25px"
android:textStyle="bold" >
</TextView>
</TableRow>
</TableLayout>
</TableRow>

<TableRow
android:id="@+id/TRcontent"
android:layout_width="fill_parent"
android:layout_height="90dp" >

<TextView
android:id="@+id/tvContent"
android:layout_width="200dp"
android:layout_height="50dp"
android:text="@+id/TextView02" >
</TextView>
</TableRow>

<TableRow
android:id="@+id/TRMarquee"
android:layout_width="fill_parent"
android:layout_height="90dp" >

<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/TLMarquee"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TableRow
android:id="@+id/TRtm"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:gravity="center_horizontal" >

<TextView
android:id="@+id/tvQueen"
android:layout_width="160dp"
android:layout_height="30dp"
android:ellipsize="marquee"
android:gravity="center_horizontal"
android:singleLine="true"
android:text=".....all pisces....."
android:textColor="#ffffff"
android:textSize="18px"
android:textStyle="bold" >
</TextView>
</TableRow>
</TableLayout>
</TableRow>

<TableRow
android:id="@+id/TRButton"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:gravity="center_horizontal" >

<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/TLButton"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TableRow
android:id="@+id/TRtb"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:gravity="center_horizontal" >

<Button
android:id="@+id/btnOk"
android:layout_width="100dp"
android:layout_height="50dp"
android:text="@string/alert_ok" >
</Button>
</TableRow>
</TableLayout>
</TableRow>

</TableLayout>


style.xml

<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="style_NavCompass">
<item name="android:windowFullscreen">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@drawable/black</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
</style>

</resources>

清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hhf.compass"
android:versionCode="1"
android:versionName="1.0" >

<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name=".Welcome"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/style_NavCompass" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Compass"
android:screenOrientation="portrait"
android:theme="@style/style_NavCompass" >
</activity>
<activity
android:name="com.hhf.compass.About"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Dialog" >
</activity>
</application>

<uses-sdk android:minSdkVersion="3" />

<uses-permission android:name="android.permission.WAKE_LOCK" >
</uses-permission>

</manifest>

指南针效果:
android指南针 - 无尘 - 无尘
 android指南针 - 无尘 - 无尘