【课设分享】安卓APP——地图定位器

开发工具

  • Android Studio
  • API 29:Android 10

功能介绍

项目总体包括6大模块:界面设计、定位、地图切换、当前城市天气、搜索地点、导航,具体实现了切换多种类型的地图、显示当前城市天气信息、显示当前定位信息、语音输入搜索地点、全国地点搜索、步骑行导航、导航语音播报等功能。

各模块详解

界面设计

  1. 设计内容
    界面布局

界面的布局构想如上。

  1. 实现方法

利用AS自带的布局方法。

  1. 实现步骤

在项目的activity_main.xml文件里实现:
①线性布局
界面共用到9个线性布局,选取底栏第一行(搜索框和语音)的线性布局为例,线性布局的核心代码如下:

<LinearLayout

    android:layout_width="fill_parent"      //布局宽度设为与手机宽度相等
    android:layout_height="64dp"    //布局高度开始设置wrap_content,再在//design界面直接调整,调整完成后code界面即显示具体数值
    android:gravity="center_horizontal"     //重力方向设为水平方向居中
    android:layout_gravity="center_vertical"    //设为垂直方向居中,和上一行结合即可同时实现水平垂直居中
    android:background="#ffffff"    //设置底栏背景颜色为白色(顶栏背景为半透明黑色:android:background="#e0000000",e0表示透明度为半透明)
    android:orientation="horizontal">    //指定布局内控件排列方式为水平排列

</LinearLayout>

②View类
界面共用到了四种view控件,分别举例如下:

<TextView
    android:id="@+id/tv_Lat"    //设置id,便于在MainActivity.java里设置语句
    android:layout_width="wrap_content"     //文本框宽度
    android:layout_height="wrap_content"    //文本框高度
    android:text=""     //文本内容,在MainActivity.java设置显示
    android:textcolor="#ffffff"     //字体颜色为白色
    android:textSize="15dp" />      //字体大小
<View
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:background="@mipmap/weather"></View>    //设置View的背景为一张图片,图片放在res目录下面
<ImageView  //和View的功能相同
    android:layout_width="25dp"
    android:layout_height="25dp"
    android:background="@mipmap/search" />
<AutocompleteTextView       //搜索框
    android:id="@+id/search"
    android:layout_width="200dp"
    android:layout_height="45dp"
    android:hint="请输入搜索地点:"   //设置当EditText内容为空时显示的文本
    android:textcolor="#000000"
    android:textcolorHint="#000000"
    android:textSize="16dp" />

③button类

Button用在布局中的:普通地图按钮、卫星地图按钮、步行导航按钮、骑行导航按钮、语音输入按钮。以语音按钮为例:

<Button

    android:id="@+id/speak"

    android:layout_width="30dp"

    android:layout_height="30dp"

    android:layout_marginLeft="30dp"  //语音按钮左侧是搜索框,设置两者间隔为30dp

    android:background="@mipmap/speak" />

④checkbox类

在地图的实现过程中,有一些界面或功能需要根据用户需要设置显示或隐藏,只有checkbox可以实现。界面中用到checkbox的有:定位信息、实时路况、热力分布。以定位信息的checkbox为例:

a. 创建checkbox

<CheckBox

    android:id="@+id/cb3"

    android:layout_width="30dp"

    android:layout_height="30dp"

    android:layout_marginBottom="15dp"		//定位按钮下是步行导航按钮,设置间隔为15dp

    android:background="@drawable/location"		//背景调用location.xml

    android:button="@null"/>	//隐藏默认图标,否则会重复显示

b. 修改checkbox外观:因为checkbox选中前后应设置不同的图片以免混淆,所以要在drawable目录下新建selector类型的location.xml文件

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@mipmap/before1"                //选中前的图片
        android:state_checked="true"></item>
    <item
        android:drawable="@mipmap/after1"                 //选中后的图片
        android:state_checked="false"></item>
</selector>
  1. 最终展示

定位

  1. 实现方法:调用百度地图SDK

本项目包含的JAR包开发资源如下:

注:百度地图SDK的导入方式可参考官方教程或其他教程。
  1. 实现步骤:

①在AndroidManifest.xml文件设置权限;

<!-- 百度定位所需要权限,前面是LOCATE权限组的2个危险权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- 百度定位所需要的普通权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

<!-- 因为程序要与百度云服务交互 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

②在启动服务代码里初始化定位,并开启服务;

//启动各项服务
private  void startServe(){
    initLocation();//初始化定位
    mLocationClient.start();
    mLocationClient.requestLocation();
    baiduMap.setMyLocationEnabled(true);//开启图层定位

    initSearch();//初始化搜素
    waitNavi();//等待导航
}

③在初始化定位里面,添加定位按钮,打开GPS,设置坐标类型、定位模式、定位信息,并保存定位参数;

//初始化定位
private void initLocation() {
    mLocationClient = new LocationClient(getApplicationContext());
    mLocationClient.registerLocationListener(new MyLocationListener());
    SDKInitializer.initialize(getApplicationContext());
    setContentView(R.layout.activity_main);

    mapView = findViewById(R.id.bmapView);
    baiduMap = mapView.getMap();
    tv_Lat = findViewById(R.id.tv_Lat);
    tv_Lon = findViewById(R.id.tv_Lon);
    tv_Add = findViewById(R.id.tv_Add);
    btn_click=findViewById(R.id.speak);
    tv_mTem=findViewById(R.id.tem);
    mSearch=findViewById(R.id.search);
    //定位按钮
    DWCheck=findViewById(R.id.cb3);

    LocationClientOption option = new LocationClientOption();
    //设置坐标类型
    option.setCoorType("bd09ll");
    //打开GPS
    option.setOpenGps(true);
    //设置扫描时间间隔
    option.setScanSpan(1000);
    //设置定位模式,三选一
    option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
    /*option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
    option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);*/
    //设置需要地址信息
    option.setIsNeedAddress(true);
    //保存定位参数
    mLocationClient.setLocOption(option);

}

④设置一个百度位置监听器,获取当前定位信息变化和方向信息的变化,用checkbox注册一个监听器,来控制定位信息的显示与隐藏;

//内部类,百度位置监听器
public class MyLocationListener extends BDAbstractLocationListener {
    @Override
    public void onReceiveLocation(BDLocation bdLocation) {
        //获取当前定位的经纬度
        myLat = bdLocation.getLatitude();
        myLon = bdLocation.getLongitude();
        myAdd=bdLocation.getAddrStr();
        String city=bdLocation.getCity();
        DWCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    //位置显示和隐藏
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        black = (LinearLayout)findViewById(R.id.black);
        black.setVisibility(View.VISIBLE);
        if (isChecked){tv_Lat.setText(null);
            tv_Lon.setText(null);
            tv_Add.setText(null);
            black.setVisibility(View.INVISIBLE);
        }else {
            tv_Lat.setText("纬度:"+myLat+"");
            tv_Lon.setText("经度:"+myLon+"");
            tv_Add.setText("地址:"+myAdd+"");
            black.setVisibility(View.VISIBLE);
                }
            }
        });
        if(bdLocation.getLocType()==BDLocation.TypeGpsLocation || bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){
            navigateTo(bdLocation);
            changeZoom();
        }

        MyLocationData locData = new MyLocationData.Builder()
                .accuracy(bdLocation.getRadius())
                // 此处设置开发者获取到的方向信息,顺时针0-360
                .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                .longitude(bdLocation.getLongitude()).build();
        baiduMap.setMyLocationData(locData);

    }
}

⑤获取到定位信息后,要重新设置地图新的中心点和改变图层缩放比例。

//更新地图状态,设置地图新的中心点
private void navigateTo(BDLocation bdLocation) {
    if(isFirstLocate){
        LatLng ll = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());
        MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
        baiduMap.animateMapStatus(update);
        isFirstLocate = false;
    }

}

//改变图层缩放比例
private void changeZoom() {
    MapStatus.Builder builder = new MapStatus.Builder();
    builder.zoom(18.0f);
    baiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
  1. 最终展示

地图切换

  1. 实现方法:调用百度地图SDK

  2. 实现步骤:

①用两个button注册监听器,实现卫星地图与普通地图之间的转换;

//地图类型切换(卫星、普通、热力、路况)
        WXButton=findViewById(R.id.bn3);
        PTButton=findViewById(R.id.bn2);
        RLCheck=findViewById(R.id.reli);
        LKCheck=findViewById(R.id.lukuang);
        WXButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
            }
        });
        PTButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                baiduMap.setTrafficEnabled(false);
                baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
            }
        });

②用两个CheckBox注册监听器,实现选中时开启热力图和路况图,未选中时关闭。

        RLCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    baiduMap.setBaiduHeatMapEnabled(true);
                }else {
                    baiduMap.setBaiduHeatMapEnabled(false);
                }
            }
        });
        LKCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    baiduMap.setTrafficEnabled(true);
                }else {
                    baiduMap.setTrafficEnabled(false);
                }
            }
        });
  1. 最终展示


天气显示

  1. 实现方法:调用和风天气SDK

  2. 实现步骤:

①使用SDK时,需提前进行账户初始化操作,输入申请的id和key;

②编写getWeather( )函数,通过和风天气的接口heweather.getWeatherNow获取实况天气,及当前时间点的天气状况,这里只显示实测温度。
函数调用成功后先判断返回的status是否正确,当status正确时获取数据,对获取到的数据进行JSON解析,通过jsonObject.getString获取温度,并用setText()显示到textView中,若status不正确,则执行else语句;

 private void getWeather() {
        /**
         *  * 实况天气
         *  * 实况天气即为当前时间点的天气状况
         *  * @param context  上下文
         *  * @param listener  网络访问回调接口
         *  * 通过getWeatherNow和监听器OnResultWeatherNowBeanListener来监听返回的数据
         *  */
                HeWeather.getWeatherNow(MainActivity.this, new HeWeather.OnResultWeatherNowBeanListener() {
                    public static final String TAG = "HeWeather_getWeatherNow";
                    @Override
                    public void onError(Throwable e) {
                        Log.i(TAG, "onError:", e);
                        System.out.println("Weather Now Error:" + new Gson());
                    }
                    @Override
                    public void onSuccess(Now dataObject) {
                        Log.i(TAG, " Weather Now onSuccess:" + new Gson().toJson(dataObject));
                        String  temperature = null,city = null, district = null,weather = null,  cid = null;
                        if (dataObject.getStatus().equals("ok")) {
                            String JsonNow = new Gson().toJson(dataObject.getNow());
                            String JsonBasic = new Gson().toJson(dataObject.getBasic());
                            JSONObject jsonObject = null;
                            JSONObject jsonObject1 = null;
                            try {
                                jsonObject = new JSONObject(JsonNow);
                                jsonObject1 = new JSONObject(JsonBasic);
                                //  city = jsonObject1.getString("parent_city");
                                // district = jsonObject1.getString("location");
                                //cid = jsonObject1.getString("cid");
                                temperature = jsonObject.getString("tmp");
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        } else {
                          //  Toast.makeText(MainActivity.this, "Mistakes...", Toast.LENGTH_SHORT).show();
                            return;
                        }
                        String temperature2 = temperature + "℃";
                        // String city2 = city + "市 " + district;
                        cityID = cid;
                        //tv_location.setText(city2);
                        // tv_weather.setText(weather);
                        tv_mTem.setText(temperature2);

                    }
                });
            }

③在初始化地图时调用getWeather( )。

  1. 最终展示
    显示天气

地点搜索

  1. 实现方法:调用百度地图SDK。

  2. 实现步骤:

①初始化建议搜索模块,给SuggestionSearch实例化并且注册建议搜索事件监听,使用建议搜索服务获取建议列表,结果在onSuggestionResult()中更新 ,并且还注册了文本内容变化事件监听器(采用匿名内部类的形式实现),实现动态更新建议列表显示;

    //初始化搜索
    private void initSearch() {

        mSearchView = findViewById(R.id.search);
        // 初始化建议搜索模块,注册建议搜索事件监听
        mSuggestionSearch = SuggestionSearch.newInstance();
        mSuggestionSearch.setOnGetSuggestionResultListener(this);

        sugAdapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line);
        mSearchView.setAdapter(sugAdapter);
        mSearchView.setThreshold(1);

        /* 当输入关键字变化时,动态更新建议列表 */
        mSearchView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

            }

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                if (cs.length() <= 0) {
                    return;
                }

                /* 使用建议搜索服务获取建议列表,结果在onSuggestionResult()中更新 */
                mSuggestionSearch.requestSuggestion((new SuggestionSearchOption())
                        .keyword(cs.toString())
                        .city(mSearchView.getText().toString()));
            }

            @Override
            public void afterTextChanged(Editable arg0) {

            }
        });
    }

②编写建议搜索事件处理器的执行方法,需要适配器来提供数组的列表项内容就要先实现Adapter接口,然后用方法将适配器设置进文本框组件中,最后为文本框的点击事件注册事件监听器,这个事件处理器的工作内容就是对用户的点击做出响应,响应就是获取被点击地点的经纬度位置信息,同时移动到所选目的地。

    public void onGetSuggestionResult(SuggestionResult res) {
        if (res == null || res.getAllSuggestions() == null) {
            return;
        }

        List<String> suggest = new ArrayList<>();
        for (SuggestionResult.SuggestionInfo info : res.getAllSuggestions()) {
            if (info.key != null) {
                suggest.add(info.key);
            }
        }

        sugAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_dropdown_item_1line,
                suggest);
        mSearchView.setAdapter(sugAdapter);

        mSearchView.setOnItemClickListener((parent, view, position, id) -> {

            String address = suggest.get(position);
            //搜素目的地的经纬度信息
            pt = res.getAllSuggestions().get(position).getPt();

            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(40)
                    .direction(40)
                    .latitude(pt.latitude)
                    .longitude(pt.longitude)
                    .build();
            baiduMap.setMyLocationData(locData);

            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(pt).zoom(18.0f);
            baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

        });
        sugAdapter.notifyDataSetChanged();
    }

语音输入

  1. 实现方法:调用讯飞语音识别SDK

     注:SDK包的导入可参考官网教程
    
  2. 实现步骤:

①进行初始化操作,将申请的讯飞语音识别appID进行传参,只有初始化后才能进行相关操作;

②设置按钮监听,在检测到按钮被点击后,执行btnVoice( )方法,通过RecognizerDialog进行dialog对象的创建,dialog.setParameter方法设置语言模式为中文模式,
dialog.show方法显示识别视图,同时进行识别语言的回调监听,如果成功则执行printResult方法,如果错误,则执行onError( )方法;

    public void onClick(View v) { btnVoice();
    }
    private void btnVoice() {
        RecognizerDialog dialog = new RecognizerDialog(this,null);
        dialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        dialog.setParameter(SpeechConstant.ACCENT, "mandarin");

        dialog.setListener(new RecognizerDialogListener() {
            public void onResult(RecognizerResult recognizerResult, boolean b) {
                printResult(recognizerResult);
            }
            @Override
            public void onError(SpeechError speechError) {

            }
        });
        dialog.show();
        Toast.makeText(this, "请开始说话", Toast.LENGTH_SHORT).show();
    }

③接收完语音输入后进行结果解析,解析过程分为:
词法解析:按照构词规则将JSON字符串解析成Token流;
语法解析:根据JSON文法检查Token序列构成的JSON结构是否合法,非空JSON对象以键值对的形式出现,例如:{String:Value},之后将Token序列作为输入,遍历输出JSON.Array。

      //  解析识别结果
    public static String parseIatResult(String json) {
        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);
            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                // 转写结果词,默认使用第一个结果
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                JSONObject obj = items.getJSONObject(0);
                ret.append(obj.getString("w"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret.toString();
    }

④将parseIatResult解析的结果传递给String类型的text,通过editview的ID标识mSearch调用mSearch.append(text)方法,将识别结果显示到editview中。

    //语音回调结果:
    private void printResult(RecognizerResult results) {
        String text = parseIatResult(results.getResultString());
        // 自动填写地址
        mSearch.append(text);
    }
  1. 最终展示

路径导航与语音播报

  1. 实现方法:
    ① 步/骑行导航:调用百度地图骑行导航SDK实现;
    ② 语音播报:调用百度在线语言合成SDK实现。

  2. 实现步骤:

    注:骑行导航与步行导航的实现步骤完全一致,这里统一以骑行导航为例说明。

①权限设置:在AndroidManifest.xml文件中加入以下权限;

<!-- 获取访问手机振动器权限,用于导航过程中的震动提示 -->
    <uses-permission android:name="android.permission.VIBRATE" />
<!-- 获取摄像头权限,用于AR步行导航 -->
    <uses-permission android:name="android.permission.CAMERA" />
<!-- 百度语音合成所需权限 -->
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS"
    	tools:ignore="ProtectedPermissions" />

②骑行导航入口:以按钮点击事件作为导航入口,如果没有先进行目的地搜索选定,则弹出错误提示,否则初始化导航引擎;

//骑行导航按钮点击事件
        Bikebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(pt == null)
                    Toast.makeText(getApplicationContext(),"没有选定目的地,无法导航!",Toast.LENGTH_LONG).show();
                else
                    startBikeNvai();
            }
        });

③初始化导航引擎:如果导航初始化失败,则弹出错误提示,如果初始化成功,则先获取起始点位置;

    //开始骑行导航
    public void startBikeNvai(){
        //初始化导航引擎
        BikeNavigateHelper.getInstance().initNaviEngine(this, new IBEngineInitListener() {
            @Override
            public void engineInitSuccess() {
                //骑行导航初始化成功之后的回调
                getStartAndEndLocation();
                routePlanWithBikeParam();
            }

            @Override
            public void engineInitFail() {
                Toast.makeText(getApplicationContext(),"骑行导航回调失败",Toast.LENGTH_SHORT).show();
                //骑行导航初始化失败之后的回调
            }
        });
    }

④获取导航起始点位置:起点位置为当前定位位置,终点位置为用户搜索所得的目的地位置,然后使用起始点位置构造导航参数,并设置导航模式为普通骑行导航;

    //获取起始点位置
    private void getStartAndEndLocation() {
        //起终点位置
        LatLng startPt = new LatLng(myLat,myLon);
        LatLng endPt = pt;
        BikeRouteNodeInfo Bikestrinfo = new BikeRouteNodeInfo();
        BikeRouteNodeInfo Bikeendinfo = new BikeRouteNodeInfo();
        Bikestrinfo.setLocation(startPt);
        Bikeendinfo.setLocation(endPt);

        WalkRouteNodeInfo Walkstrinfo = new WalkRouteNodeInfo();
        WalkRouteNodeInfo Walkendinfo = new WalkRouteNodeInfo();
        Walkstrinfo.setLocation(startPt);
        Walkendinfo.setLocation(endPt);

        //.vehicle(0)默认的普通骑行导航
        Bikeparam = new BikeNaviLaunchParam().startNodeInfo(Bikestrinfo).endNodeInfo(Bikeendinfo).vehicle(0);
        //.extraNaviMode(0)默认的普通步行导航
        Walkparam = new WalkNaviLaunchParam().startNodeInfo(Walkstrinfo).endNodeInfo(Walkendinfo).extraNaviMode(0);
    }

⑤导航路径规划:利用上一步得到的导航参数进行路径规划,如果算路则败则弹出错误提示,如果算路成功,则跳转至诱导页面;

    //骑行导航路径规划
    private void routePlanWithBikeParam() {

        //发起算路
        BikeNavigateHelper.getInstance().routePlanWithRouteNode(Bikeparam, new IBRoutePlanListener() {
            @Override
            public void onRoutePlanStart() {
                //执行算路开始的逻辑
            }

            @Override
            public void onRoutePlanSuccess() {
                //算路成功
                //跳转至诱导页面
                Intent intent = new Intent(MainActivity.this, BikeGuideActivity.class);
                startActivity(intent);
            }

            @Override
            public void onRoutePlanFail(BikeRoutePlanError bikeRoutePlanError) {
                //执行算路失败的逻辑
                Toast.makeText(getApplicationContext(),"骑行导航算路失败",Toast.LENGTH_SHORT).show();
            }
        });
    }

⑥导航诱导页面:在诱导页面中,获取导航帮助实例,然后使用导航帮助实例获取诱导页面地图,如果地图不为空则显示诱导页面地图,然后初始化语音合成,为语音播报导航信息做准备;

 mNaviHelper = BikeNavigateHelper.getInstance();
        // 获取诱导页面地图展示View
        View view = mNaviHelper.onCreate(BikeGuideActivity.this);

        if (view != null) {
            setContentView(view);
        }

        initspeak();

⑦初始化语音合成:首先获取语音合成实例,然后设置语言合成监听器,并输入申请到的id和key,之后检查在线语言合成是否授权成功,如果授权成功则初始化语言合成模式为在线模式,设置发声的人声为第0号,否则弹出授权失败的错误提示;

    //初始化语音合成
    private void initspeak(){
        //获取监听器,SDK合成后会对这个类的方法进行回调
        SpeechSynthesizerListener listener = new MessageListener();
        //获取 SpeechSynthesizer 实例
        mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        mSpeechSynthesizer.setContext(this);
        mSpeechSynthesizer.setSpeechSynthesizerListener(listener);
        //输入申请的应用id和key
        mSpeechSynthesizer.setAppId("20325388");
        mSpeechSynthesizer.setApiKey("j4mnpV9nmRAiU8dj65UKGUgo","90xzDKRcnrcTTiCG7Ag16IIKxAvYKiVA");

        AuthInfo authInfo = mSpeechSynthesizer.auth(TtsMode.ONLINE);
        if (authInfo.isSuccess()) {
            Toast.makeText(getApplicationContext(), "授权成功", Toast.LENGTH_LONG).show();
            // 初始化在线模式
            int result = mSpeechSynthesizer.initTts(TtsMode.ONLINE);
            // 设置发声的人声音,在线生效
            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        } else {
            // 授权失败
            Toast.makeText(getApplicationContext(), "授权失败", Toast.LENGTH_SHORT).show();
        }
    }

⑧设置语音播报:调用语言合成的speak函数对语音文本进行合成并播报;

 //语音播报文本
        mNaviHelper.setTTsPlayer(new IBTTSPlayer() {
            @Override
            /**
             * 获取导航过程中语音,进行播报
             * @param s 播报语音文本
             * @param b 是否抢占播报
             */
            public int playTTSText(String s, boolean b) {
                //调用语音合成SDK的语音回调进行播报
                mSpeechSynthesizer.speak(s);
                return 0;
            }
        });

⑨开始导航:语音播报设置完毕后,启动导航。

 // 开始导航
        mNaviHelper.startBikeNavi(BikeGuideActivity.this);
  1. 最终展示

结尾

该项目由本人和本人所在小组的其他成员共同完成,主要参考了官方提供的API使用手册和官方demo,还有一些参考了他人分享的教程,该项目还有一些不完美的地方,欢迎大家根据自己的需求进行改进,完整代码请移步到以下连接:MapLocator8.0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值