当前位置:   article > 正文

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

使用高德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)中添加这一段代码

  1. sourceSets {
  2. main {
  3. jniLibs.srcDirs = ['libs']
  4. }
  5. }

第三步:配置权限文件


1. 编辑AndroidManifest.xml

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

  1. <!--允许访问网络,必选权限-->
  2. <uses-permission android:name="android.permission.INTERNET" />
  3. <!--允许获取粗略位置,若用GPS实现定位小蓝点功能则必选-->
  4. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  5. <!--允许获取设备和运营商信息,用于问题排查和网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
  6. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  7. <!--允许获取网络状态,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
  8. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  9. <!--允许获取wifi网络信息,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
  10. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  11. <!--允许获取wifi状态改变,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
  12. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  13. <!--允许写入扩展存储,用于数据缓存,若无此权限则写到私有目录-->
  14. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  15. <!--允许读设备等信息,用于问题排查-->
  16. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  17. <!--允许访问网络,必选权限-->
  18. <uses-permission android:name="android.permission.INTERNET" />
  19. <!--允许读设备等信息,用于问题排查-->
  20. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  21. <!--允许获取网络状态-->
  22. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  23. <!--允许获取wifi网络信息-->
  24. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  25. <!--允许写入扩展存储,用于搜索结果缓存,若无此权限则写到私有目录-->
  26. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  27. <!--允许读设备等信息,用于问题排查-->
  28. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  29. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  30. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

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

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

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

2. 编辑activity_main.xml


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

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

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <RelativeLayout
  9. xmlns:android="http://schemas.android.com/apk/res/android"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"
  12. >
  13. <com.amap.api.maps.MapView
  14. android:id="@+id/map"
  15. android:layout_width="match_parent"
  16. android:layout_height="match_parent" >
  17. </com.amap.api.maps.MapView>
  18. </RelativeLayout>
  19. </androidx.constraintlayout.widget.ConstraintLayout>

3. 编辑主函数MainActivity.java


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

  1. public class MainActivity extends Activity {
  2. MapView mMapView = null;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. //获取地图控件引用
  8. mMapView = (MapView) findViewById(R.id.map);
  9. //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
  10. mMapView.onCreate(savedInstanceState);
  11. }
  12. @Override
  13. protected void onDestroy() {
  14. super.onDestroy();
  15. //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
  16. mMapView.onDestroy();
  17. }
  18. @Override
  19. protected void onResume() {
  20. super.onResume();
  21. //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
  22. mMapView.onResume();
  23. }
  24. @Override
  25. protected void onPause() {
  26. super.onPause();
  27. //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
  28. mMapView.onPause();
  29. }
  30. @Override
  31. protected void onSaveInstanceState(Bundle outState) {
  32. super.onSaveInstanceState(outState);
  33. //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
  34. mMapView.onSaveInstanceState(outState);
  35. }
  36. }

第四步:显示地图

1. 编辑主函数

构造 AMap 对象,添加代码

  1. private void initializeMapView(Bundle savedInstanceState) {
  2. mMapView = findViewById(R.id.map);
  3. if (mMapView != null) {
  4. mMapView.onCreate(savedInstanceState);
  5. aMap = mMapView.getMap();
  6. }
  7. }
  8. @Override
  9. protected void onResume() {
  10. super.onResume();
  11. if (mMapView != null) {
  12. mMapView.onResume();
  13. }
  14. }
  15. @Override
  16. protected void onPause() {
  17. super.onPause();
  18. if (mMapView != null) {
  19. mMapView.onPause();
  20. }
  21. }
  22. @Override
  23. protected void onDestroy() {
  24. super.onDestroy();
  25. if (mMapView != null) {
  26. mMapView.onDestroy();
  27. }
  28. }
  29. @Override
  30. protected void onSaveInstanceState(Bundle outState) {
  31. super.onSaveInstanceState(outState);
  32. if (mMapView != null) {
  33. mMapView.onSaveInstanceState(outState);
  34. }
  35. }

编辑onCreate()函数

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_main);
  5. initializeMapView(savedInstanceState);
  6. }

2. 显示效果

 第五步:显示定位

1. 设置定位权限获取

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

  1. private void requestLocationPermissions() {
  2. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  3. && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  4. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
  5. }
  6. }
  7. private void setupAmapPrivacy() {
  8. MapsInitializer.updatePrivacyShow(this, true, true);
  9. MapsInitializer.updatePrivacyAgree(this, true);
  10. }
  11. @Override
  12. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  13. if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
  14. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  15. Toast.makeText(this, "权限已授予", Toast.LENGTH_SHORT).show();
  16. } else {
  17. Toast.makeText(this, "权限被拒绝,应用可能无法正常工作", Toast.LENGTH_SHORT).show();
  18. finish();
  19. }
  20. }
  21. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  22. }

2. 显示定位蓝点

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

  1. private void configureMap() {
  2. if (aMap == null) return;
  3. MyLocationStyle locationStyle = MapConfigurator.createDefaultLocationStyle();
  4. aMap.setMyLocationStyle(locationStyle);
  5. aMap.getUiSettings().setMyLocationButtonEnabled(true);
  6. aMap.setMyLocationEnabled(true);
  7. aMap.moveCamera(CameraUpdateFactory.zoomTo(16));
  8. }

修改onCreate()
 

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. requestLocationPermissions();
  5. setupAmapPrivacy();
  6. setContentView(R.layout.activity_main);
  7. initializeMapView(savedInstanceState);
  8. configureMap();
  9. }

3. 显示效果

第六步:启动导航组件

1. 添加xml文件

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

activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <RelativeLayout
  9. android:layout_width="0dp"
  10. android:layout_height="0dp"
  11. app:layout_constraintTop_toTopOf="parent"
  12. app:layout_constraintBottom_toBottomOf="parent"
  13. app:layout_constraintStart_toStartOf="parent"
  14. app:layout_constraintEnd_toEndOf="parent">
  15. <com.amap.api.maps.MapView
  16. android:id="@+id/map"
  17. android:layout_width="match_parent"
  18. android:layout_height="match_parent" />
  19. </RelativeLayout>
  20. <Button
  21. android:id="@+id/btnGotoNavi"
  22. android:layout_width="wrap_content"
  23. android:layout_height="wrap_content"
  24. android:text="前往导航"
  25. android:onClick="gotoNavi"
  26. app:layout_constraintTop_toTopOf="parent"
  27. tools:ignore="MissingConstraints,OnClick" />
  28. </androidx.constraintlayout.widget.ConstraintLayout>

activity_search.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".SearchActivity"
  8. android:orientation="vertical">
  9. <EditText
  10. android:id="@+id/search_edit"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"/>
  13. <androidx.recyclerview.widget.RecyclerView
  14. android:id="@+id/search_rv"
  15. android:layout_width="match_parent"
  16. android:layout_height="match_parent"
  17. app:layout_constraintBottom_toBottomOf="parent"
  18. app:layout_constraintTop_toBottomOf="@+id/search_edit"
  19. app:layout_constraintVertical_bias="1.0"
  20. tools:layout_editor_absoluteX="-51dp"
  21. />
  22. </LinearLayout>

activity_item.xml

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

2. 添加两个类

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

RvAdapter.java

  1. package com.amap.navi.map;
  2. import android.content.Context;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.TextView;
  7. import androidx.annotation.NonNull;
  8. import androidx.recyclerview.widget.RecyclerView;
  9. import com.amap.api.services.help.Tip;
  10. import java.util.List;
  11. import java.util.Map;
  12. public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> implements View.OnClickListener {
  13. private final List<Tip> list;
  14. private final Context context;
  15. private final RecyclerView rv;
  16. private OnItemClickListener mOnItemClickListener;
  17. @Override
  18. public void onClick(View v) {
  19. int position = rv.getChildAdapterPosition(v);
  20. //程序执行到此,会去执行具体实现的onItemClick()方法
  21. if (mOnItemClickListener != null) {
  22. mOnItemClickListener.onItemClick(rv, v, position, list.get(position));
  23. }
  24. }
  25. public interface OnItemClickListener {
  26. void onItemClick(RecyclerView parent, View view, int position, Tip data);
  27. }
  28. public RvAdapter(Context context, RecyclerView rv, List<Tip> list) {
  29. this.context = context;
  30. this.rv = rv;
  31. this.list = list;
  32. }
  33. public void setOnItemClickListener(OnItemClickListener clickListener) {
  34. this.mOnItemClickListener = clickListener;
  35. }
  36. public void setData(List<Tip> list) {
  37. if (list == null) return;
  38. this.list.clear();
  39. this.list.addAll(list);
  40. notifyDataSetChanged();
  41. }
  42. @NonNull
  43. @Override
  44. public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  45. View view = LayoutInflater.from(context).inflate(R.layout.search_item, parent, false);
  46. view.setOnClickListener(this);
  47. return new MyViewHolder(view);
  48. }
  49. @Override
  50. public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
  51. Tip tip = list.get(position);
  52. ((TextView) holder.itemView).setText(tip.getName());
  53. }
  54. @Override
  55. public int getItemCount() {
  56. return list.size();
  57. }
  58. static class MyViewHolder extends RecyclerView.ViewHolder {
  59. public MyViewHolder(@NonNull View itemView) {
  60. super(itemView);
  61. }
  62. }
  63. }

SearchActivity.java

  1. package com.amap.navi.map;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import androidx.recyclerview.widget.LinearLayoutManager;
  4. import androidx.recyclerview.widget.RecyclerView;
  5. import android.os.Bundle;
  6. import android.text.Editable;
  7. import android.text.TextWatcher;
  8. import android.util.Log;
  9. import android.view.View;
  10. import android.widget.EditText;
  11. import com.amap.api.services.help.Inputtips;
  12. import com.amap.api.services.help.InputtipsQuery;
  13. import com.amap.api.services.help.Tip;
  14. import java.util.ArrayList;
  15. import java.util.List;
  16. public class SearchActivity extends AppCompatActivity implements Inputtips.InputtipsListener, TextWatcher,RvAdapter.OnItemClickListener {
  17. private RvAdapter rvAdapter;
  18. private Inputtips inputtips;
  19. // private AMapNavi aMapNavi;
  20. private EditText editText;
  21. private RecyclerView recyclerView;
  22. private ArrayList<Tip> list = new ArrayList<>();
  23. @Override
  24. protected void onCreate(Bundle savedInstanceState) {
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.activity_search);
  27. editText = findViewById(R.id.search_edit);
  28. editText.addTextChangedListener(this);
  29. recyclerView = (RecyclerView) findViewById(R.id.search_rv);
  30. LinearLayoutManager layoutManager = new LinearLayoutManager(SearchActivity.this, RecyclerView.VERTICAL, false);
  31. recyclerView.setLayoutManager(layoutManager);
  32. rvAdapter = new RvAdapter(this, recyclerView, new ArrayList<>());
  33. rvAdapter.setOnItemClickListener(this);
  34. recyclerView.setAdapter(rvAdapter);
  35. inputtips = new Inputtips(this, (InputtipsQuery) null);
  36. inputtips.setInputtipsListener(this);
  37. }
  38. //通过适配器把数据展示到recyclerView中去
  39. @Override
  40. public void onGetInputtips(List<Tip> list, int i) {
  41. rvAdapter.setData(list);
  42. }
  43. @Override
  44. public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
  45. }
  46. @Override
  47. public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
  48. InputtipsQuery inputtipsQuery = new InputtipsQuery(String.valueOf(charSequence), null);
  49. inputtipsQuery.setCityLimit(true);
  50. inputtips.setQuery(inputtipsQuery);
  51. inputtips.requestInputtipsAsyn();
  52. }
  53. @Override
  54. public void afterTextChanged(Editable editable) {
  55. }
  56. @Override
  57. public void onItemClick(RecyclerView parent, View view, int postion, Tip data) {
  58. }
  59. @Override
  60. public void onBackPressed() {
  61. Log.d("SearchActivity", "onBackPressed Called");
  62. super.onBackPressed();
  63. }
  64. }

3. 编辑MainActivity.java

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

  1. // 无起终点启动导航组件的代码
  2. findViewById(R.id.btnGotoNavi).setOnClickListener(new View.OnClickListener() {
  3. @Override
  4. public void onClick(View v) {
  5. // 无起终点启动导航
  6. AmapNaviParams params = new AmapNaviParams(null, null, null, AmapNaviType.DRIVER, AmapPageType.ROUTE);
  7. AmapNaviPage.getInstance().showRouteActivity(getApplicationContext(), params, null);
  8. }
  9. });
  10. }
  11. // 在 MainActivity 中,或者任何合适的地方
  12. private void exitNavigation() {
  13. AmapNaviPage.getInstance().exitRouteActivity();
  14. }

4. 在MainActivity类中添加新方法

gotoNavi()

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

5. 更新AndroidManifest.xml

在application标签中添加

        android:allowNativeHeapPointerTagging="false"

新建一个activity

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

6. 显示效果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/297640
推荐阅读
相关标签
  

闽ICP备14008679号