Android 基于指南针方向绘制abitmap

Android 基于指南针方向绘制abitmap,android,bitmap,compass,Android,Bitmap,Compass,我需要做的是在圆外的边缘绘制位图。 有时我做对了,但当我旋转设备时,它就错了。 我还尝试了旋转动画,但没有得到我想要的结果 请帮忙 这就是我们所期望的: 我得到的是:对于这个图像,它工作得很好 这里出问题了 在这里: 代码(compass的谷歌教程): CompassFragment类: public class CompassFragment extends Fragment implements SensorEventListener { SensorManager

我需要做的是在圆外的边缘绘制位图。
有时我做对了,但当我旋转设备时,它就错了。
我还尝试了旋转动画,但没有得到我想要的结果

请帮忙

这就是我们所期望的:

我得到的是:对于这个图像,它工作得很好

这里出问题了

在这里:

代码(compass的谷歌教程):

CompassFragment类:

   public class CompassFragment extends Fragment implements SensorEventListener {

    SensorManager sensorManager;
    private Sensor sensorAccelerometer;
    private Sensor sensorMagneticField;

    private float[] valuesAccelerometer;
    private float[] valuesMagneticField;

    private float[] matrixR;
    private float[] matrixI;
    private float[] matrixValues;

    TextView readingAzimuth, readingPitch, readingRoll;
    Compass myCompass;
 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_compass, container, false);
        readingAzimuth = (TextView) view.findViewById(R.id.azimuth);
        readingPitch = (TextView) view.findViewById(R.id.pitch);
        readingRoll = (TextView) view.findViewById(R.id.roll);
        myCompass = (Compass) view.findViewById(R.id.mycompass);
        return view;
    }

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
        sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorMagneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

        valuesAccelerometer = new float[3];
        valuesMagneticField = new float[3];

        matrixR = new float[9];
        matrixI = new float[9];
        matrixValues = new float[3];

    }

@Override
    public void onResume() {

        sensorManager.registerListener(this,
                sensorAccelerometer,
                SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this,
                sensorMagneticField,
                SensorManager.SENSOR_DELAY_NORMAL);
        super.onResume();
    }

@Override
    public void onPause() {

        sensorManager.unregisterListener(this,
                sensorAccelerometer);
        sensorManager.unregisterListener(this,
                sensorMagneticField);
        super.onPause();
    }

@Override
    public void onSensorChanged(SensorEvent event) {
        switch (event.sensor.getType()) {
            case Sensor.TYPE_ACCELEROMETER:
                for (int i = 0; i < 3; i++) {
                    valuesAccelerometer[i] = event.values[i];
                }
                break;
            case Sensor.TYPE_MAGNETIC_FIELD:
                for (int i = 0; i < 3; i++) {
                    valuesMagneticField[i] = event.values[i];
                }
                break;
        }

        boolean success = SensorManager.getRotationMatrix(
                matrixR,
                matrixI,
                valuesAccelerometer,
                valuesMagneticField);

        if (success) {
            SensorManager.getOrientation(matrixR, matrixValues);

            double azimuth = Math.toDegrees(matrixValues[0]);
            double pitch = Math.toDegrees(matrixValues[1]);
            double roll = Math.toDegrees(matrixValues[2]);

            readingAzimuth.setText("Azimuth: " + String.valueOf(azimuth));
            readingPitch.setText("Pitch: " + String.valueOf(pitch));
            readingRoll.setText("Roll: " + String.valueOf(roll));

            myCompass.update(matrixValues[0]);
        }

    }

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

    }
}
公共类CompassFragment扩展了实现SensorEventListener的片段{
传感器管理器传感器管理器;
专用传感器;
专用传感器磁场;
私人浮动[]价值加速度计;
私人浮动[]价值磁场;
私人浮动[]矩阵;
私人股本;第十一条;
私有浮动[]矩阵值;
文本视图读取齐茅斯、读取俯仰、读取滚动;
指南针;
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
视图=充气机。充气(R.layout.fragment\u罗盘,容器,假);
readingAzimuth=(TextView)view.findViewById(R.id.aziration);
readingPitch=(TextView)view.findViewById(R.id.pitch);
readingRoll=(TextView)view.findViewById(R.id.roll);
myCompass=(Compass)view.findviewbyd(R.id.myCompass);
返回视图;
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
sensorManager=(sensorManager)getActivity().getSystemService(Context.SENSOR\u服务);
SensorAccelerator=sensorManager.getDefaultSensor(传感器类型\加速计);
sensorMagneticField=sensorManager.getDefaultSensor(传感器类型\u磁场);
数值加速度计=新浮点数[3];
valuesMagneticField=新浮点数[3];
matrixR=新浮动[9];
matrixI=新浮动[9];
matrixValues=新浮点数[3];
}
@凌驾
恢复时公开作废(){
sensorManager.registerListener(此,
传感器加速度计,
传感器管理器。传感器延迟(正常);
sensorManager.registerListener(此,
传感器磁场,
传感器管理器。传感器延迟(正常);
super.onResume();
}
@凌驾
公共无效暂停(){
sensorManager.unregisterListener(此,
传感器(加速度计);
sensorManager.unregisterListener(此,
传感器磁场;
super.onPause();
}
@凌驾
传感器更改时的公共无效(传感器事件){
开关(event.sensor.getType()){
外壳传感器.U型加速计:
对于(int i=0;i<3;i++){
valuesAccelerometer[i]=事件值[i];
}
打破
外壳传感器。类型\u磁场:
对于(int i=0;i<3;i++){
值磁场[i]=事件值[i];
}
打破
}
布尔成功=SensorManager.getRotationMatrix(
matrixR,
matrixI,
数值加速度计,
数值(磁场);
如果(成功){
SensorManager.getOrientation(matrixR、matrixValues);
双方位角=数学toDegrees(矩阵值[0]);
双节距=数学toDegrees(matrixValues[1]);
双辊=数学toDegrees(matrixValues[2]);
读取zimuth.setText(“方位角:+String.valueOf(方位角));
读取Pitch.setText(“Pitch:+String.valueOf(Pitch));
读取Roll.setText(“Roll:+String.valueOf(Roll));
myCompass.update(矩阵值[0]);
}
}
@凌驾
精度更改时的公共无效(传感器,int精度){
}
}
罗盘等级:

public class Compass extends View {
    private Bitmap bitmap;
    private float direction;
    private HashMap<String, Bitmap> mStore = new HashMap<String, Bitmap>();
    private Context context;
    private int h, w, r;
    private Paint paint;
    private Canvas canvas;

    public Compass(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        this.context = context;

    }

    public Compass(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public Compass(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-ge

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(
                MeasureSpec.getSize(widthMeasureSpec),
                MeasureSpec.getSize(heightMeasureSpec));
    }
 @Override
    protected void onDraw(Canvas canvas) {
        w = getMeasuredWidth();
        h = getMeasuredHeight();
        r = 0;
        if (w > h) {
            r = h / 2;
        } else {
            r = w / 2;
        }
        paint = new Paint();
//        Paint.ANTI_ALIAS_FLAG
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        canvas.drawCircle(w / 2, h / 2, r, paint);
        paint.setColor(Color.RED);
        drawImage1(canvas);
    }
    private void drawImage1(Canvas canvas) {
        BitmapFactory.Options myOptions = new BitmapFactory.Options();
        myOptions.inDither = true;
        myOptions.inScaled = false;
        myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
        myOptions.inPurgeable = true;
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher, myOptions);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.BLUE);
        Bitmap workingBitmap = Bitmap.createBitmap(bitmap);
        Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
        float left = (float) ((w / 2 + r * Math.sin(-direction)));
        float top = (float) (h / 2 - r * Math.cos(-direction));
        Log.e("cords", left + "  " + top);
        canvas.drawBitmap(mutableBitmap, left, top, paint);
    }
}


<?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:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <TextView
            android:id="@+id/azimuth"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/mainColor" />

        <TextView
            android:id="@+id/pitch"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/mainColor" />

        <TextView
            android:id="@+id/roll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/mainColor" />
    </LinearLayout>

    <com.example.compass.Compass
        android:id="@+id/mycompass"
        class="com.nilecode.Compass"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp">

    </com.example.compass.Compass>
</LinearLayout>
公共类Compass扩展视图{
私有位图;
私人浮动方向;
private HashMap mStore=new HashMap();
私人语境;
私人住宅内的h、w、r;
私人油漆;
私人帆布;
公共罗盘(上下文){
超级(上下文);
//TODO自动生成的构造函数存根
this.context=上下文;
}
公共指南针(上下文、属性集属性){
超级(上下文,attrs);
//TODO自动生成的构造函数存根
}
公共指南针(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
//托多汽车公司
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
设置测量尺寸(
测量等级getSize(宽度测量等级),
测量等级getSize(高度测量等级));
}
@凌驾
受保护的void onDraw(画布){
w=getMeasuredWidth();
h=getMeasuredHeight();
r=0;
如果(w>h){
r=h/2;
}否则{
r=w/2;
}
油漆=新油漆();
//Paint.ANTI_别名_标志
绘制.设置样式(绘制.样式.笔划);
油漆。设置行程宽度(5);
油漆。设置颜色(颜色。白色);
paint.setAntiAlias(真);
帆布。画圈(w/2,h/2,r,油漆);
油漆。设置颜色(颜色。红色);
drawImage1(画布);
}
私有void drawImage1(画布){
BitmapFactory.Options myOptions=新的BitmapFactory.Options();
myOptions.inDither=true;
myOptions.inScaled=false;
myOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//重要
myOptions.inpurgable=true;
位图Bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_启动器,myOptions);
油漆=新油漆();
paint.setAntiAlias(真);
油漆。