安卓實景導航

最近項目需求有個奇葩的需求就是說,用戶可以實景導航。
剛開始聽到這個需求的時候,我都驚呆了,什麼叫實景導航?看了下客戶的需求文檔,才知道是用戶想去某個地方,可以打開攝像頭,上面要放個箭頭指着目的地的方向,一聽腦袋大了,什麼鬼~但是我們程序員就是解決問題的啊~沒辦法,硬着頭皮往上搞~

首先
1,先確定我們自己的當前的位置(也就是經緯度)

2,目標點的經緯度

3,先判斷兩個位置的方位

4,利用傳感器去導航

這是相關的步驟:
直接上代碼

public static double getAngle(double lat1, double lng1, double lat2,double lng2) {
        double x1 = lng1;
        double y1 = lat1;
        double x2 = lng2;
        double y2 = lat2;
        double pi = Math.PI;
        double w1 = y1 / 180 * pi;
        double j1 = x1 / 180 * pi;
        double w2 = y2 / 180 * pi;
        double j2 = x2 / 180 * pi;
        double ret;
        if (j1 == j2) {
            if (w1 > w2)
                return 270; // 北半球的情況,南半球忽略
            else if (w1 < w2)
                return 90;
            else
                return -1;// 位置完全相同
        }
        ret = 4* Math.pow(Math.sin((w1 - w2) / 2), 2)- Math.pow(
                Math.sin((j1 - j2) / 2) * (Math.cos(w1) - Math.cos(w2)),2);
        ret = Math.sqrt(ret);
        double temp = (Math.sin(Math.abs(j1 - j2) / 2) * (Math.cos(w1) + Math
                .cos(w2)));
        ret = ret / temp;
        ret = Math.atan(ret) / pi * 180;
        if (j1 > j2){ // 1爲參考點座標
            if (w1 > w2)
                ret += 180;
            else
                ret = 180 - ret;
        } else if (w1 > w2)
            ret = 360 - ret;
        return ret;
    }
/**
     * @param lat1 緯度1
     * @param lng1 經度1
     * @param lat2 緯度2
     * @param lng2 經度2
     * @return 方向
     */
    public static String getDirection(double lat1, double lng1, double lat2,double lng2) {
        double jiaodu = getAngle(lat1, lng1, lat2, lng2);
        if ((jiaodu <= 10) || (jiaodu > 350))
            return "東";
        if ((jiaodu > 10) && (jiaodu <= 80))
            return "東北";
        if ((jiaodu > 80) && (jiaodu <= 100))
            return "北";
        if ((jiaodu > 100) && (jiaodu <= 170))
            return "西北";
        if ((jiaodu > 170) && (jiaodu <= 190))
            return "西";
        if ((jiaodu > 190) && (jiaodu <= 260))
            return "西南";
        if ((jiaodu > 260) && (jiaodu <= 280))
            return "南";
        if ((jiaodu > 280) && (jiaodu <= 350))
            return "東南";
        return "";
    }

上面代碼 咱們就知道方位了
下面就是指向了

float values = event.values[0];//getData(values)
            System.out.println(values);
            animation = new RotateAnimation(predegree,(float) Math.toDegrees(getData(values)),Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); 
            animation.setDuration(200); 
            //handler.sendEmptyMessage(1);
            imageview.startAnimation(animation); 
            predegree=-(float) Math.toDegrees(getData(values)); 

需要用到SensorManager類傳感器

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback {

    private static final String TAG = "CameraSurfaceView";

    private Context mContext;
    private SurfaceHolder holder;
    private Camera mCamera;
    private int mScreenWidth;
    private int mScreenHeight;

    public CameraView(Context context) {
        this(context, null);
    }

    public CameraView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        getScreenMetrix(context);
        initView();
    }

    private void getScreenMetrix(Context context) {
        WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        WM.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;
        mScreenHeight = outMetrics.heightPixels;
    }

    private void initView() {
        holder = getHolder();//獲得surfaceHolder引用
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//設置類型
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.i(TAG, "surfaceCreated");
        if (mCamera == null) {
            mCamera = Camera.open();//開啓相機
            try {
                mCamera.setPreviewDisplay(holder);//攝像頭畫面顯示在Surface上
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.i(TAG, "surfaceChanged");
        mCamera.startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i(TAG, "surfaceDestroyed");
        mCamera.stopPreview();//停止預覽
        mCamera.release();//釋放相機資源
        mCamera = null;
        holder = null;
    }

    @Override
    public void onAutoFocus(boolean success, Camera Camera) {
        if (success) {
            Log.i(TAG, "onAutoFocus success="+success);
        }
    }

}
有這方面需求的朋友,不懂的可以留言給我~
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章