Android开发之指南针


Android基于多种手机传感器开发指南针的项目

一、基于方向传感器

1.效果图

在这里插入图片描述

2.布局文件(activity_main)

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:id="@+id/top"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/retuen">

            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_margin="30dp"
                android:gravity="center"
                android:text="基于方向传感器"
                android:textColor="#009688"
                android:textSize="26dp" />

            <ImageView
                android:id="@+id/compass"
                android:layout_width="280dp"
                android:layout_height="280dp"
                android:layout_below="@+id/title"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="30dp"
                android:src="@drawable/znz" />

            <TextView
                android:id="@+id/value"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/compass"
                android:layout_alignLeft="@+id/compass"
                android:layout_alignRight="@+id/compass"
                android:layout_marginTop="30dp"
                android:text="方向传感器的返回值:"
                android:textColor="#FFC107"
                android:textSize="18dp" />

            <TextView
                android:id="@+id/value01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/value"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="30dp"
                android:background="@color/teal_200"
                android:gravity="center"
                android:text="方位"
                android:textColor="@color/black"
                android:textSize="38dp" />
        </RelativeLayout>

        <TextView
            android:id="@+id/retuen"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentBottom="true"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            android:background="@color/teal_700"
            android:text="返回上一级"
            android:textColor="@color/black"
            android:textSize="26dp" />

        <TextView
            android:id="@+id/exit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:layout_margin="8dp"
            android:background="#F44336"
            android:text="退出软件"
            android:textColor="@color/black"
            android:textSize="26dp" />

    </RelativeLayout>

</LinearLayout>

3.java文件(MainActivity)

package com.example;

import android.app.Activity;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.Nullable;

import java.util.List;

public class MainActivity extends Activity implements View.OnClickListener, SensorEventListener {
    //使用方向传感器编写指南针
    public SensorManager sensorManager;
    private float currentDegree;
    private TextView tvDirection;       //指南针文字显示方位控件
    private float azimuth = 0f;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        currentDegree = 0f;
        sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);

        setContentView(R.layout.activity_main);

        TextView return00 = findViewById(R.id.retuen);
        return00.setOnClickListener(this);

        TextView exit = findViewById(R.id.exit);
        exit.setOnClickListener(this);

        tvDirection = (TextView) findViewById(R.id.value01);
    }

    @Override
    public void onResume() {
        //为方向传感器注册监听器
        super.onResume();
        List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
        for (Sensor s : sensors) {
            sensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_FASTEST);
        }
    }

    @Override
    public void onClick(View v) {
        Intent intent;
        switch (v.getId()) {
            case R.id.retuen:
                intent = new Intent(this, MainActivity.class);
                startActivity(intent);
                finish();
                break;
            case R.id.exit:
                intent = new Intent(Intent.ACTION_MAIN);
                intent.addCategory(Intent.CATEGORY_HOME);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                finish();
                break;
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        TextView value = findViewById(R.id.value);
        ImageView imageView = findViewById(R.id.compass);
        float[] values = event.values;
        StringBuilder stringBuilder = new StringBuilder();
        if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
            stringBuilder.append("方向传感器的返回值:");
            stringBuilder.append("\nvalues[0]:" + values[0]);
            stringBuilder.append("\nvalues[1]:" + values[1]);
            stringBuilder.append("\nvalues[2]:" + values[2]);
            value.setText(stringBuilder.toString());
            float degree = event.values[0];     //取围绕z轴转过的角度
            azimuth = (degree + 360) % 360;
            RotateAnimation rotateAnimation = new RotateAnimation(currentDegree, -degree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            if (azimuth <= 15 || azimuth >= 345) {
                tvDirection.setText("方位:北");
            } else if (15 < azimuth && azimuth < 75) {
                tvDirection.setText("方位:东北");
            } else if (75 <= azimuth && azimuth <= 105) {
                tvDirection.setText("方位:东");
            } else if (105 < azimuth && azimuth < 165) {
                tvDirection.setText("方位:东南");
            } else if (165 <= azimuth && azimuth <= 195) {
                tvDirection.setText("方位:南");
            } else if (195 < azimuth && azimuth < 255) {
                tvDirection.setText("方位:西南");
            } else if (255 <= azimuth && azimuth <= 285) {
                tvDirection.setText("方位:西");
            } else if (285 < azimuth && azimuth < 345) {
                tvDirection.setText("方位:西北");
            }

            rotateAnimation.setDuration(200);
            rotateAnimation.setFillAfter(true);
            imageView.setAnimation(rotateAnimation);
            currentDegree = -degree;
        }
    }
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}


二、基于加速度传感器和磁场传感器

1.效果图

在这里插入图片描述

2.布局文件(compass01)

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:id="@+id/top"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/retuen">

            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_marginStart="20dp"
                android:layout_marginTop="30dp"
                android:layout_marginEnd="20dp"
                android:layout_marginBottom="20dp"
                android:gravity="center"
                android:text="基于加速度计和磁场传感器"
                android:textColor="#009688"
                android:textSize="26dp" />

            <ImageView
                android:id="@+id/compass"
                android:layout_width="280dp"
                android:layout_height="280dp"
                android:layout_below="@+id/title"
                android:layout_centerInParent="true"
                android:layout_marginTop="30dp"
                android:src="@drawable/znz" />

            <TextView
                android:id="@+id/value00"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/compass"
                android:layout_alignLeft="@+id/compass"
                android:layout_alignRight="@+id/compass"
                android:layout_marginTop="10dp"
                android:text="加速度计的返回值:"
                android:textColor="#FFC107"
                android:textSize="18dp" />

            <TextView
                android:id="@+id/value01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/value00"
                android:layout_alignLeft="@+id/compass"
                android:layout_alignRight="@+id/compass"
                android:layout_marginTop="10dp"
                android:text="磁场传感器的返回值:"
                android:textColor="#FFC107"
                android:textSize="18dp" />

            <TextView
                android:id="@+id/value02"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/value01"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="10dp"
                android:background="@color/teal_200"
                android:gravity="center"
                android:text="方位"
                android:textColor="@color/black"
                android:textSize="38dp" />

        </RelativeLayout>

        <TextView
            android:id="@+id/retuen"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentBottom="true"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            android:background="@color/teal_700"
            android:text="返回上一级"
            android:textColor="@color/black"
            android:textSize="26dp" />

        <TextView
            android:id="@+id/exit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            android:background="#F44336"
            android:text="退出软件"
            android:textColor="@color/black"
            android:textSize="26dp" />

    </RelativeLayout>

</LinearLayout>

3.java文件(TypeTwoActivity)

package com.example;

import android.app.Activity;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.Nullable;


public class TypeTwoActivity extends Activity implements View.OnClickListener, SensorEventListener {
    //通过加速度传感器和地磁传感器编写指南针
    public SensorManager sensorManager;
    private Sensor aSensor;     //定义加速度传感器
    private Sensor mSensor;     //定义磁场传感器

    private String TAG = "CompassActivity";
    public ImageView ivArrow;     //指南针指针控件
    private TextView tvDirection;       //指南针文字显示方位控件

    private float[] mGravity = new float[3];
    private float[] mGeomagnetic = new float[3];

    private float azimuth = 0f;
    private float currentAzimuth = 0;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.compass01);

        TextView return00 = findViewById(R.id.retuen);
        return00.setOnClickListener(this);

        TextView exit = findViewById(R.id.exit);
        exit.setOnClickListener(this);

        initView();
        initData();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (sensorManager != null) {
            sensorManager.unregisterListener(this);
        }
    }

    @Override

    protected void onResume() {
        super.onResume();
        if (null != sensorManager) {
// 注册陀螺仪传感器
            sensorManager.registerListener(this, aSensor,
                    SensorManager.SENSOR_DELAY_GAME);

// 注册磁场传感器
            sensorManager.registerListener(this, mSensor,
                    SensorManager.SENSOR_DELAY_GAME);
        }
    }

    @Override

    protected void onPause() {
        super.onPause();
        if (null != sensorManager) {
            sensorManager.unregisterListener(this);     // 取消注册陀螺仪传感器
        }
    }

    @Override
    public void onClick(View v) {
        Intent intent;
        switch (v.getId()) {
            case R.id.retuen:
                intent = new Intent(this, MainActivity.class);
                startActivity(intent);
                finish();
                break;
            case R.id.exit:
                intent = new Intent(Intent.ACTION_MAIN);
                intent.addCategory(Intent.CATEGORY_HOME);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                finish();
                break;
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        final float alpha = 0.97f;

        synchronized (this) {
//指南针转动角度算法
//判断当前是加速度感应器还是地磁感应器
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                TextView value00 = findViewById(R.id.value00);
                float[] values = event.values;
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append("加速度计的返回值:");
                stringBuilder.append("\nvalues[0]:" + values[0]);
                stringBuilder.append("\nvalues[1]:" + values[1]);
                stringBuilder.append("\nvalues[2]:" + values[2]);
                value00.setText(stringBuilder.toString());
                mGravity[0] = alpha * mGravity[0] + (1 - alpha)
                        * event.values[0];
                mGravity[1] = alpha * mGravity[1] + (1 - alpha)
                        * event.values[1];
                mGravity[2] = alpha * mGravity[2] + (1 - alpha)
                        * event.values[2];
            }

            if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
                TextView value01 = findViewById(R.id.value01);
                float[] values = event.values;
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append("磁场传感器的返回值:");
                stringBuilder.append("\nvalues[0]:" + values[0]);
                stringBuilder.append("\nvalues[1]:" + values[1]);
                stringBuilder.append("\nvalues[2]:" + values[2]);
                value01.setText(stringBuilder.toString());
                mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha)
                        * event.values[0];
                mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha)
                        * event.values[1];
                mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha)
                        * event.values[2];
            }

            float R[] = new float[9];
            float I[] = new float[9];
            boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
                    mGeomagnetic);
            if (success) {
                float orientation[] = new float[3];
                SensorManager.getOrientation(R, orientation);
                azimuth = (float) Math.toDegrees(orientation[0]); // orientation
                azimuth = (azimuth + 360) % 360;

                adjustArrow();

            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    /**
     * 初始化控件
     */
    private void initView() {
        ivArrow = (ImageView) findViewById(R.id.compass);
        tvDirection = (TextView) findViewById(R.id.value02);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        aSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

    /**
     * 陀螺仪方位显示&角度转动
     */
    private void adjustArrow() {
        if (ivArrow == null) {
            return;
        }

        Animation an = new RotateAnimation(-currentAzimuth, -azimuth,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        currentAzimuth = azimuth;
        Log.i(TAG, "azimuth:" + azimuth);

        if (azimuth <= 15 || azimuth >= 345) {
            tvDirection.setText("方位:北");
        } else if (15 < azimuth && azimuth < 75) {
            tvDirection.setText("方位:东北");
        } else if (75 <= azimuth && azimuth <= 105) {
            tvDirection.setText("方位:东");
        } else if (105 < azimuth && azimuth < 165) {
            tvDirection.setText("方位:东南");
        } else if (165 <= azimuth && azimuth <= 195) {
            tvDirection.setText("方位:南");
        } else if (195 < azimuth && azimuth < 255) {
            tvDirection.setText("方位:西南");
        } else if (255 <= azimuth && azimuth <= 285) {
            tvDirection.setText("方位:西");
        } else if (285 < azimuth && azimuth < 345) {
            tvDirection.setText("方位:西北");
        }

        an.setDuration(200);
        an.setRepeatCount(0);
        an.setFillAfter(true);

        ivArrow.startAnimation(an);//动画效果转动传感器
    }
}



三、资源下载

下载地址:Android开发之指南针
感兴趣的小伙伴可以做着玩一下!😛😛😛

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一些Android开发指南针: 1. 熟悉Java语言。Java是Android开发的主要语言,需要熟悉Java的基本语法和面向对象编程思想。 2. 学习Android SDK。Android SDK提供了很多API和工具,可以用来开发Android应用程序。需要学习如何使用SDK中的类和方法,以及如何构建Android应用程序。 3. 了解Android应用程序的生命周期。Android应用程序包含了许多不同的组件,如Activity、Service、BroadcastReceiver和ContentProvider等。需要了解它们之间的关系和生命周期。 4. 使用Android Studio进行开发Android Studio是Google推荐的Android开发工具,提供了许多功能和工具,可以帮助开发人员更快速地开发Android应用程序。 5. 了解Android的UI设计。Android应用程序通常需要精心设计的用户界面。需要学习如何使用布局和小部件来设计用户界面。 6. 学习如何使用Android的数据库。Android提供了SQLite数据库,可以用来存储和管理应用程序的数据。需要学习如何使用SQLite API来进行数据库操作。 7. 掌握Android的网络编程。许多Android应用程序需要与远程服务器进行通信,需要学习如何使用HTTP和其他网络协议来进行网络编程。 8. 学习如何进行调试和测试。开发Android应用程序时,需要进行调试和测试,以确保应用程序的质量和稳定性。 9. 参考官方文档和社区资源。Android开发有很多文档和资源可供参考,如官方文档、Stack Overflow等。可以通过这些资源来学习和解决问题。 希望这些指南针能够帮助您入门Android开发

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不服输的小乌龟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值