Android開發 PopupWindow彈窗調用第三方地圖(百度,高德)實現導航功能

博客描述:後臺返回地點的經緯度在地圖上進行描點,點擊導航彈出PopupWindow進行選擇地圖操做,若是手機中沒有安裝地圖,提示沒有,不然傳值調起地圖進行導航操做php

看一下實現的效果,沒圖說再多都白搭java

 

這裏在打開第三方的時候能夠不用傳當前位置的經緯度,當你打開App時默認爲當前位置爲起點,只設置終點經緯度就能夠,文檔上也都有說明,android

若是你有定位獲取的經緯度,也能夠拼接上,注意不要拼接錯,還要注意的百度和高德地圖使用的經緯度不能用同一個,須要轉換,百度地圖獲算法

取到的經緯度須要經過方法處理成高德地圖能夠使用的,反之同理。api

另外附上文檔地址:ide

  百度地圖:http://lbsyun.baidu.com/index.php?title=uri/api/android佈局

  高德地圖:http://lbs.amap.com/api/amap-mobile/guide/android/route動畫

 

騰訊地圖後續有時間就添加上。ui

看完效果圖再看具體的實現方法this

先看實現PopupWindow的實現

PopupWindow的佈局文件

map_navgation_sheet.xml

<?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="wrap_content"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <TextView
        android:id="@+id/baidu_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20px"
        android:layout_marginRight="20px"
        android:layout_marginTop="35px"
        android:background="@drawable/shape_map_navagation_sheet_bg"
        android:gravity="center"
        android:text="百度地圖"
        android:textColor="#224E8F" />

    <!-- <View
         android:layout_width="match_parent"
         android:layout_height="1px"
         android:background="#cdcdcd" />-->

    <TextView
        android:id="@+id/gaode_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20px"
        android:layout_marginRight="20px"
        android:layout_marginTop="10px"
        android:background="@drawable/shape_map_navagation_sheet_bg"
        android:gravity="center"
        android:text="高德地圖"
        android:textColor="#224E8F" />

    <!--  <View
          android:layout_width="match_parent"
          android:layout_height="1px"
          android:background="#cdcdcd" />-->

    <TextView
        android:id="@+id/tencent_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingBottom="30px"
        android:paddingTop="30px"
        android:text="騰訊地圖"
        android:visibility="gone" />


    <!--<View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#cdcdcd" />-->

    <!--
        android:paddingBottom="30px"-->
    <TextView
        android:id="@+id/cancel_btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="40px"
        android:layout_marginLeft="20px"
        android:layout_marginRight="20px"
        android:layout_marginTop="15px"
        android:background="@drawable/shape_map_navagation_sheet_bg"
        android:gravity="center"
        android:text="取消"
        android:textColor="#224E8F" />
</LinearLayout>

PopupWindow彈出方法:

 @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void dhPopupView() {
        // : 2016/5/17 構建一個popupwindow的佈局
//        View popupView = ShopDetailsMap.this.getLayoutInflater().inflate(R.layout.map_navagation_sheet, null);
        View popupView = getLayoutInflater().inflate(R.layout.map_navagation_sheet, null);
//        Point position = getNavigationBarSize(mContext);

        TextView baidu_btn = popupView.findViewById(R.id.baidu_btn);
        TextView gaode_btn = popupView.findViewById(R.id.gaode_btn);
        TextView tencent_btn = popupView.findViewById(R.id.tencent_btn);
        TextView cancel_btn2 = popupView.findViewById(R.id.cancel_btn2);

        baidu_btn.setOnClickListener(this);
        gaode_btn.setOnClickListener(this);
        tencent_btn.setOnClickListener(this);
        cancel_btn2.setOnClickListener(this);
        // : 2016/5/17 建立PopupWindow對象,指定寬度和高度
//        window = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        window = new PopupWindow();

        window.setContentView(popupView);
        //設置寬高
        window.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        window.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);


        // : 2016/5/17 設置動畫
//        window.setAnimationStyle(R.style.popup_window_anim);
        // : 2016/5/17 設置背景顏色
        window.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#88323232")));
        // : 2016/5/17 設置能夠獲取焦點
        window.setFocusable(true);
        // : 2016/5/17 設置能夠觸摸彈出框之外的區域
        window.setOutsideTouchable(true);
        // :更新popupwindow的狀態
        window.update();
        window.setClippingEnabled(false);
//        int windowPos[] = calculatePopWindowPos(view, windowContentViewRoot);
//        window.showAtLocation(popupView,Gravity.BOTTOM,);
//        window.showAsDropDown(popupView, Gravity.BOTTOM, 0, 0);
        Rect rect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int winHeight = getWindow().getDecorView().getHeight();
        window.showAtLocation(popupView, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, winHeight - rect.bottom);
//        window.showAsDropDown(btnPopup, 0, 20);
      /*  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//            window.showAsDropDown(this.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
        }*/
    }

 

檢測是否安裝了第三方應用

 /*檢測應用是否安裝*/
    private boolean isAvilible(Context context, String packageName) {
        final PackageManager packageManager = context.getPackageManager();//獲取packagemanager
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);//獲取全部已安裝程序的包信息
        List<String> pName = new ArrayList<String>();//用於存儲全部已安裝程序的包名
        //從pinfo中將包名字逐一取出,壓入pName list中
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName;
                pName.add(pn);
            }
        }
        return pName.contains(packageName);//判斷pName中是否有目標程序的包名,有TRUE,沒有FALSE
    }

 

調用百度地圖方法

/*百度地圖*/
    public void baiduMap() {
        if (isAvilible(this, "com.baidu.BaiduMap")) {//傳入指定應用包名
            Intent il = new Intent();
            il.setData(Uri.parse("baidumap://map/direction?destination=" + lng + "," + lat + "&mode=driving"));
            startActivity(il);
        } else {//未安裝
            //market爲路徑,id爲包名
            //顯示手機上全部的market商店
            Toast.makeText(this, "您還沒有安裝百度地圖", Toast.LENGTH_LONG).show();
      //顯示手機上全部的market商店 Uri uri = Uri.parse("market://details?id=com.baidu.BaiduMap"); intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent);
} window.dismiss(); }

 

調用高德地圖方法

 /*高德地圖*/
    private void gaodeMap() {

        if (isAvilible(this, "com.autonavi.minimap")) {//傳入指定應用包名
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setPackage("com.autonavi.minimap");
            try {
//                intent = Intent.getIntent("amapuri://route/plan/?sid=BGVIS1&slat=39.92848272&slon=116.39560823&sname=A&did=BGVIS2&dlat=39.98848272&dlon=116.47560823&dname=B&dev=0&t=0");
                intent = Intent.getIntent("amapuri://route/plan/?dlat=" + lng + "&dlon=" + lat + "&d&dev=0&t=0");
                startActivity(intent);
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        } else {//未安裝
            //market爲路徑,id爲包名
            //顯示手機上全部的market商店
            Toast.makeText(this, "您還沒有安裝高德地圖", Toast.LENGTH_LONG).show();
            Uri uri = Uri.parse("market://details?id=com.autonavi.minimap");
            intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        }
        window.dismiss();
    }

注意:代碼中的lat和lng是後臺傳遞過來的經緯度,百度和高德使用的時候注意放置的位置。

下面貼總的代碼

/**
 * Created by dingchao on 2018/3/12.
 */

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ZoomControls;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;/**
 * 商鋪詳情查看地圖的時候顯示
 */
public class ShopDetailsMap extends BaseActivity implements View.OnClickListener {

    private MapView mMapView = null;
    private BaiduMap mBaiduMap = null;
    private BitmapDescriptor bitmapDescriptor;
    private ImageView iv_map_return;

    private Intent intent;
    private String lat;
    private String lng;
    private String shopName;
    private String shopAddress;
    PopupWindow window;

    /*定位*/

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        intent = getIntent();
        lat = intent.getStringExtra("lat");
        lng = intent.getStringExtra("lng");
        shopName = intent.getStringExtra("shopName");
        shopAddress = intent.getStringExtra("shopAddress");
        //在使用SDK各組件以前初始化context信息,傳入ApplicationContext
        //注意該方法要再setContentView方法以前實現
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.shop_details_map);


        iv_map_return = (ImageView) findViewById(R.id.iv_map_return);
        iv_map_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });




        /*顯示信息*/
        //infowindow中的佈局
        /*TextView tv = new TextView(ShopDetailsMap.this);
        tv.setBackgroundResource(R.mipmap.maptextbg);
        tv.setPadding(20, 10, 20, 20);
        tv.setTextColor(android.graphics.Color.WHITE);
        tv.setText("商鋪名稱" + "\n" + "北京市北京南站附近");
        tv.setGravity(Gravity.LEFT);*/

        View view1 = ViewGroup.inflate(ShopDetailsMap.this, R.layout.activity_shop_detail_map, null);
        TextView textView1 = view1.findViewById(R.id.tv_shop_details_map_text1);
        TextView textView2 = view1.findViewById(R.id.tv_shop_details_map_text2);

        textView1.setText(shopName);
        textView2.setText(shopAddress);


//        bitmapDescriptor = BitmapDescriptorFactory.fromView(tv);
        bitmapDescriptor = BitmapDescriptorFactory.fromView(view1);


        //顯示infowindow,-47是偏移量,使infowindow向上偏移,不會擋住marker
        //獲取地圖控件引用
        mMapView = (MapView) findViewById(R.id.bmapView);
        LatLng llText = new LatLng(Double.parseDouble(lng), Double.parseDouble(lat));
//        InfoWindow infoWindow = new InfoWindow(bitmapDescriptor, llText, -47, null);////不可觸發點擊
        InfoWindow infoWindow = new InfoWindow(bitmapDescriptor, llText, -47, new InfoWindow.OnInfoWindowClickListener() {//可觸發點擊
            @Override
            public void onInfoWindowClick() {
//                Toast.makeText(ShopDetailsMap.this, "被點擊", Toast.LENGTH_SHORT).show();
                dhPopupView();
            }
        });

        //在地圖上添加該文字對象並顯示
        //獲取地圖控件引用*/
        mMapView = (MapView) findViewById(R.id.bmapView);
        mBaiduMap = mMapView.getMap();
        mBaiduMap.showInfoWindow(infoWindow);
        /*這裏重點講解zoomBy後面的那個浮點型變量
            你們知道百度地圖一共有{"10米","20米","50米","100米","200米","500米","1公里","2公里","5公里",
            "10公里","20公里","25公里","50公里","100公里","200公里","500公里","1000公里","2000公里"}*/
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomBy(3);
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(llText));//設置定位的位置在屏幕的中間位置
        mBaiduMap.animateMapStatus(mapStatusUpdate);
        //構建Marker圖標,設置位置圓點
        BitmapDescriptor bitmap = BitmapDescriptorFactory
                .fromResource(R.mipmap.mapdian);
        //構建MarkerOption,用於在地圖上添加Marker

        OverlayOptions option = new MarkerOptions()
                .position(llText)
                .icon(bitmap);

        // 隱藏logo
        View child = mMapView.getChildAt(1);
        if (child != null && (child instanceof ImageView || child instanceof ZoomControls)) {
            child.setVisibility(View.INVISIBLE);
        }
        //在地圖上添加Marker,並顯示
        mBaiduMap.addOverlay(option);


//        mBaiduMap.addOverlay(option);
//        mBaiduMap.addOverlay(textOption);
    }

    //    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void dhPopupView() {
        // : 2016/5/17 構建一個popupwindow的佈局
//        View popupView = ShopDetailsMap.this.getLayoutInflater().inflate(R.layout.map_navagation_sheet, null);
        View popupView = getLayoutInflater().inflate(R.layout.map_navagation_sheet, null);
//        Point position = getNavigationBarSize(mContext);

        TextView baidu_btn = popupView.findViewById(R.id.baidu_btn);
        TextView gaode_btn = popupView.findViewById(R.id.gaode_btn);
        TextView tencent_btn = popupView.findViewById(R.id.tencent_btn);
        TextView cancel_btn2 = popupView.findViewById(R.id.cancel_btn2);

        baidu_btn.setOnClickListener(this);
        gaode_btn.setOnClickListener(this);
        tencent_btn.setOnClickListener(this);
        cancel_btn2.setOnClickListener(this);
        // : 2016/5/17 建立PopupWindow對象,指定寬度和高度
//        window = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        window = new PopupWindow();

        window.setContentView(popupView);
        //設置寬高
        window.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        window.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);


        // : 2016/5/17 設置動畫
//        window.setAnimationStyle(R.style.popup_window_anim);
        // : 2016/5/17 設置背景顏色
        window.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#88323232")));
        // : 2016/5/17 設置能夠獲取焦點
        window.setFocusable(true);
        // : 2016/5/17 設置能夠觸摸彈出框之外的區域
        window.setOutsideTouchable(true);
        // :更新popupwindow的狀態
        window.update();
        window.setClippingEnabled(false);
//        int windowPos[] = calculatePopWindowPos(view, windowContentViewRoot);
//        window.showAtLocation(popupView,Gravity.BOTTOM,);
//        window.showAsDropDown(popupView, Gravity.BOTTOM, 0, 0);
        Rect rect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int winHeight = getWindow().getDecorView().getHeight();
        window.showAtLocation(popupView, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, winHeight - rect.bottom);
//        window.showAsDropDown(btnPopup, 0, 20);
      /*  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//            window.showAsDropDown(this.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
        }*/
    }


    /*百度地圖*/
    public void baiduMap() {
        if (isAvilible(this, "com.baidu.BaiduMap")) {//傳入指定應用包名
            Intent il = new Intent();
            il.setData(Uri.parse("baidumap://map/direction?destination=" + lng + "," + lat + "&mode=driving"));
            startActivity(il);
        } else {//未安裝
            //market爲路徑,id爲包名
            //顯示手機上全部的market商店
            Toast.makeText(this, "您還沒有安裝百度地圖", Toast.LENGTH_LONG).show();
            Uri uri = Uri.parse("market://details?id=com.baidu.BaiduMap");
            intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        }
        window.dismiss();
    }


    /*高德地圖*/
    private void gaodeMap() {

        if (isAvilible(this, "com.autonavi.minimap")) {//傳入指定應用包名
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setPackage("com.autonavi.minimap");
            try {
//                intent = Intent.getIntent("amapuri://route/plan/?sid=BGVIS1&slat=39.92848272&slon=116.39560823&sname=A&did=BGVIS2&dlat=39.98848272&dlon=116.47560823&dname=B&dev=0&t=0");
                intent = Intent.getIntent("amapuri://route/plan/?dlat=" + lng + "&dlon=" + lat + "&d&dev=0&t=0");
                startActivity(intent);
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        } else {//未安裝
            //market爲路徑,id爲包名
            //顯示手機上全部的market商店
            Toast.makeText(this, "您還沒有安裝高德地圖", Toast.LENGTH_LONG).show();
            Uri uri = Uri.parse("market://details?id=com.autonavi.minimap");
            intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        }
        window.dismiss();
    }

    /*檢測應用是否安裝*/
    private boolean isAvilible(Context context, String packageName) {
        final PackageManager packageManager = context.getPackageManager();//獲取packagemanager
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);//獲取全部已安裝程序的包信息
        List<String> pName = new ArrayList<String>();//用於存儲全部已安裝程序的包名
        //從pinfo中將包名字逐一取出,壓入pName list中
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName;
                pName.add(pn);
            }
        }
        return pName.contains(packageName);//判斷pName中是否有目標程序的包名,有TRUE,沒有FALSE
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case baidu_btn:
//                Toast.makeText(this, "baidu", Toast.LENGTH_SHORT).show();
                baiduMap();
                break;
            case R.id.gaode_btn:
//                Toast.makeText(this, "gaode", Toast.LENGTH_SHORT).show();
                gaodeMap();
                break;
            case R.id.tencent_btn:
//                Toast.makeText(this, "tengxun", Toast.LENGTH_SHORT).show();
                break;
            case R.id.cancel_btn2:
//                Toast.makeText(this, "quxiao", Toast.LENGTH_SHORT).show();
                if (window != null) {
                    window.dismiss();
                }
                break;
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命週期管理
        mMapView.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity執行onResume時執行mMapView. onResume (),實現地圖生命週期管理
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity執行onPause時執行mMapView. onPause (),實現地圖生命週期管理
        mMapView.onPause();
    }


    /**
     * 啓動百度App進行導航
     *
     * @param address 目的地
     * @param lat     必填 緯度
     * @param lon     必填 經度
     */
    public static void goToBaiduActivity(Context context, String address, double lat, double lon) {
        double[] doubles = gcj02_To_Bd09(lat, lon);
        //啓動路徑規劃頁面
        Intent naviIntent = new Intent("android.intent.action.VIEW", android.net.Uri.parse("baidumap://map/direction?origin=" + doubles[0] + "," + doubles[1] + "&destination=" + address + "&mode=driving"));
        context.startActivity(naviIntent);
    }

    /**
     * 火星座標系 (GCJ-02) 與百度座標系 (BD-09) 的轉換算法 將 GCJ-02 座標轉換成 BD-09 座標
     *
     * @param lat
     * @param lon
     */
    public static double[] gcj02_To_Bd09(double lat, double lon) {
        double x = lon, y = lat;
//        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
        double z = Math.sqrt(x * x + y * y) + 0.00002;
//        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
        double theta = Math.atan2(y, x) + 0.000003;
        double tempLat = z * Math.sin(theta) + 0.006;
        double tempLon = z * Math.cos(theta) + 0.0065;
        double[] gps = {tempLat, tempLon};
        return gps;
    }


}

 

以上就是使用uri調用第三方地圖的全部代碼,若是有不理解的或者代碼有問題歡迎發送到個人郵箱:  dingchao7323@qq.com

相關文章
相關標籤/搜索