使用高德SDK开发简单导航App for Android

首先参考高德开放平台SDK开发指南
在文档与支持-Android平台下可自行选择参考哪类开发。

第一步:配置Android Studio

Android Studio配置起来很麻烦,难免会出现各种问题,把我搞得几度崩溃。
进入正题:


1. 新建工程



New-New Project-Empty Views Activity,记住这个Package name,等会要用。
language选择Java,最后一栏选择Groovy DSL,点击Finish完成工程创建

 

 第二步:准备工作

1. 申请Key

在高德平台控制台中,创建自己的应用

2. 编辑应用信息

Package name用上面步骤中的。

标红的这两项有问题的可以网上搜一搜很多解决办法。
这里提一嘴,这里一定要确保机器上的SHA1和签名apk的是同一个,不然应用会显示算路失败。后面会讲到这个问题,当时困扰了我好久。

第三步:导入高德SDK

1. 从官网下载下载开发包

我下载的是3D包

2. 添加 jar 文件

将下载的地图 SDK 的 jar包复制到工程的 libs 目录下。如果有老版本 jar 包在其中,请删除。

3. 编辑dependencies

添加这行代码到build.gradle(:app)中,让SDK的文件能被检索到

    implementation fileTree(include: ['*.jar'], dir: 'libs')

同样在build.gradle(:app)中添加这一段代码

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

第三步:配置权限文件


1. 编辑AndroidManifest.xml

把这段代码粘贴到<manifest>标签中

<!--允许访问网络,必选权限-->
    <uses-permission android:name="android.permission.INTERNET" />

    <!--允许获取粗略位置,若用GPS实现定位小蓝点功能则必选-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <!--允许获取设备和运营商信息,用于问题排查和网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <!--允许获取网络状态,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!--允许获取wifi网络信息,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <!--允许获取wifi状态改变,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

    <!--允许写入扩展存储,用于数据缓存,若无此权限则写到私有目录-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!--允许读设备等信息,用于问题排查-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <!--允许访问网络,必选权限-->
    <uses-permission android:name="android.permission.INTERNET" />

    <!--允许读设备等信息,用于问题排查-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <!--允许获取网络状态-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!--允许获取wifi网络信息-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <!--允许写入扩展存储,用于搜索结果缓存,若无此权限则写到私有目录-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!--允许读设备等信息,用于问题排查-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

 接下来将name和value添加进meta-data>标签中。

value就是上面申请的Key,name不用管

<meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="Your Key">
        </meta-data>

2. 编辑activity_main.xml


接下来初始化地图容器
在activity_main.xml中添加地图控件代码

<com.amap.api.maps.MapView
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

        </com.amap.api.maps.MapView>

添加完后,activity_main.xml是如下这样

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <com.amap.api.maps.MapView
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

        </com.amap.api.maps.MapView>



    </RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

3. 编辑主函数MainActivity.java


管理地图生命周期,添加以下代码


public class MainActivity extends Activity {
  MapView mMapView = null;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main);
    //获取地图控件引用
    mMapView = (MapView) findViewById(R.id.map);
    //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
    mMapView.onCreate(savedInstanceState);
  }
  @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();
    }
 @Override
 protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
    mMapView.onSaveInstanceState(outState);
  } 
}

第四步:显示地图

1. 编辑主函数

构造 AMap 对象,添加代码

    private void initializeMapView(Bundle savedInstanceState) {
        mMapView = findViewById(R.id.map);
        if (mMapView != null) {
            mMapView.onCreate(savedInstanceState);
            aMap = mMapView.getMap();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mMapView != null) {
            mMapView.onResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mMapView != null) {
            mMapView.onPause();
        }
    }

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

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mMapView != null) {
            mMapView.onSaveInstanceState(outState);
        }
    }

编辑onCreate()函数

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        initializeMapView(savedInstanceState);

    }

2. 显示效果

 第五步:显示定位

1. 设置定位权限获取

编辑MainActivity.java,在MainActivity类中添加代码

    private void requestLocationPermissions() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
        }
    }

    private void setupAmapPrivacy() {
        MapsInitializer.updatePrivacyShow(this, true, true);
        MapsInitializer.updatePrivacyAgree(this, true);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限已授予", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "权限被拒绝,应用可能无法正常工作", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

2. 显示定位蓝点

编辑MainActivity.java,在MainActivity类中添加代码

    private void configureMap() {
        if (aMap == null) return;

        MyLocationStyle locationStyle = MapConfigurator.createDefaultLocationStyle();
        aMap.setMyLocationStyle(locationStyle);
        aMap.getUiSettings().setMyLocationButtonEnabled(true);
        aMap.setMyLocationEnabled(true);
        aMap.moveCamera(CameraUpdateFactory.zoomTo(16));
    }

修改onCreate()
 

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

        setContentView(R.layout.activity_main);

        initializeMapView(savedInstanceState);
        configureMap();
    }

3. 显示效果

第六步:启动导航组件

1. 添加xml文件

在layout文件夹中新建3个xml文件

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent">

        <com.amap.api.maps.MapView
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </RelativeLayout>
    <Button
        android:id="@+id/btnGotoNavi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="前往导航"
        android:onClick="gotoNavi"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="MissingConstraints,OnClick" />

</androidx.constraintlayout.widget.ConstraintLayout>

activity_search.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SearchActivity"
    android:orientation="vertical">

    <EditText
        android:id="@+id/search_edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/search_rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/search_edit"
        app:layout_constraintVertical_bias="1.0"
        tools:layout_editor_absoluteX="-51dp"
    />
</LinearLayout>

activity_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="18dp">

</TextView>

2. 添加两个类

在App-Java-com.amap.navi.map 文件夹中新建两个Java类: RvAdapter.java与SearchActivity.java

RvAdapter.java

package com.amap.navi.map;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.amap.api.services.help.Tip;

import java.util.List;
import java.util.Map;

public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> implements View.OnClickListener {

    private final List<Tip> list;
    private final Context context;
    private final RecyclerView rv;
    private OnItemClickListener mOnItemClickListener;

    @Override
    public void onClick(View v) {
        int position = rv.getChildAdapterPosition(v);
        //程序执行到此,会去执行具体实现的onItemClick()方法
        if (mOnItemClickListener != null) {
            mOnItemClickListener.onItemClick(rv, v, position, list.get(position));
        }
    }

    public interface OnItemClickListener {
        void onItemClick(RecyclerView parent, View view, int position, Tip data);
    }

    public RvAdapter(Context context, RecyclerView rv, List<Tip> list) {
        this.context = context;
        this.rv = rv;
        this.list = list;
    }

    public void setOnItemClickListener(OnItemClickListener clickListener) {
        this.mOnItemClickListener = clickListener;
    }

    public void setData(List<Tip> list) {
        if (list == null) return;
        this.list.clear();
        this.list.addAll(list);
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.search_item, parent, false);
        view.setOnClickListener(this);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Tip tip = list.get(position);
        ((TextView) holder.itemView).setText(tip.getName());
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }
}

SearchActivity.java

package com.amap.navi.map;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.EditText;


import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;

import java.util.ArrayList;
import java.util.List;

public class SearchActivity extends AppCompatActivity implements Inputtips.InputtipsListener, TextWatcher,RvAdapter.OnItemClickListener {
    private RvAdapter rvAdapter;
    private Inputtips inputtips;
//    private AMapNavi aMapNavi;
    private EditText editText;
    private RecyclerView recyclerView;
    private ArrayList<Tip> list = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        editText = findViewById(R.id.search_edit);
        editText.addTextChangedListener(this);
        recyclerView = (RecyclerView) findViewById(R.id.search_rv);
        LinearLayoutManager layoutManager = new LinearLayoutManager(SearchActivity.this, RecyclerView.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);

        rvAdapter = new RvAdapter(this, recyclerView, new ArrayList<>());
        rvAdapter.setOnItemClickListener(this);
        recyclerView.setAdapter(rvAdapter);

        inputtips = new Inputtips(this, (InputtipsQuery) null);
        inputtips.setInputtipsListener(this);
    }



    //通过适配器把数据展示到recyclerView中去
    @Override
    public void onGetInputtips(List<Tip> list, int i) {
        rvAdapter.setData(list);
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        InputtipsQuery inputtipsQuery = new InputtipsQuery(String.valueOf(charSequence), null);
        inputtipsQuery.setCityLimit(true);
        inputtips.setQuery(inputtipsQuery);
        inputtips.requestInputtipsAsyn();
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }

    @Override
    public void onItemClick(RecyclerView parent, View view, int postion, Tip data) {

    }
    @Override
    public void onBackPressed() {
        Log.d("SearchActivity", "onBackPressed Called");
        super.onBackPressed();
    }


}

3. 编辑MainActivity.java

编辑onCreate()函数,添加以下代码

// 无起终点启动导航组件的代码
        findViewById(R.id.btnGotoNavi).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 无起终点启动导航
                AmapNaviParams params = new AmapNaviParams(null, null, null, AmapNaviType.DRIVER, AmapPageType.ROUTE);
                AmapNaviPage.getInstance().showRouteActivity(getApplicationContext(), params, null);
            }
        });

    }
    // 在 MainActivity 中,或者任何合适的地方
    private void exitNavigation() {
        AmapNaviPage.getInstance().exitRouteActivity();
    }

4. 在MainActivity类中添加新方法

gotoNavi()

public void gotoNavi(View view) {
        // Start the SearchActivity without finishing the current activity
        Intent intent = new Intent(this, SearchActivity.class);
        startActivity(intent);
    }

5. 更新AndroidManifest.xml

在application标签中添加

        android:allowNativeHeapPointerTagging="false"

新建一个activity

        <activity
            android:name="com.amap.api.navi.AmapRouteActivity"
            android:theme="@android:style/Theme.NoTitleBar"
            android:configChanges="orientation|keyboardHidden|screenSize|navigation" />

6. 显示效果

在UniApp使用高德地图SDK可以通过以下步骤实现: 1. 在UniApp项目的根目录下找到`manifest.json`文件,打开并添加以下代码到`uni-app`节点下: ```json "": { "android": { "features": [ { "name": "android.hardware.location", "required": true } ] } } ``` 这样可以添加定位权限,使得应用可以获取用户位置信息。 2. 下载高德地图SDK的AAR包,将其放置在UniApp项目的`unpackage/libs/android`目录下。 3. 在`manifest.json`文件中的`app-plus`节点下添加以下代码: ```json "app-plus": { "usingComponents": { "map": "@myplugin/map" // 自定义插件名 }, "android": { "permission": [ "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION" ], "package": [ "libs/android/your_amap_sdk.aar" // 替换为你下载的高德地图SDK AAR包路径 ] } } ``` 其中的`@myplugin/map`是自定义的插件名,可以根据自己的需要进行修改。`your_amap_sdk.aar`需要替换为你下载的高德地图SDK AAR包的路径。 4. 在需要使用高德地图的页面中,引入高德地图组件,例如: ```html <template> <view> <view class="map-container"> <map :longitude="longitude" :latitude="latitude" :markers="markers"></map> </view> </view> </template> <script> export default { data() { return { longitude: 0, latitude: 0, markers: [] }; }, methods: { getLocation() { // 获取用户位置信息 uni.getLocation({ type: 'gcj02', success: (res) => { this.longitude = res.longitude; this.latitude = res.latitude; this.markers = [{ id: '1', longitude: res.longitude, latitude: res.latitude, title: '我的位置' }]; } }); } }, mounted() { this.getLocation(); } }; </script> ``` 上述代码中,引入了`map`组件,并通过定位API获取用户的地理位置信息,并在地图上显示。 5. 运行项目,即可在Android使用高德地图SDK。 以上就是在UniApp Android使用高德地图SDK简单步骤。请确保已经下载并配置了高德地图SDK,并在真机或模拟器上进行测试。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值