Real-time Navigation of Gaud Map

Posted by jeremywesselman on Tue, 02 Jul 2019 20:08:42 +0200

A summary of previous articles Gaud Map Picking Place And then, on this basis, we continue to summarize. Route Planning of Gaode Map Today, we will summarize the real-time navigation of Golden Map on this basis. If you haven't read the previous article, I suggest you know it first, otherwise you may not understand it very well.
In fact, real-time navigation should be relatively simple, but the API is not very clear, so I will take my own detours one by one to let you see if there are any gains. First of all, let's go through it according to the API of the official website. In short, there are four steps:

  • Define the implementation of AMapNaviView
    Simply put, a control is declared. This control and the previous map are not a package. The code is as follows:
  • Life Cycle of AMapNaviView
    Maintaining the lifecycle and implementing the Navigation view event listening interface, AMapNaviViewListener, as well as route planning, is the following code:
  • Route planning
    Here is a sentence: "Specific reference: driving path planning or walking path planning." That is to say, let's use the route planning mentioned above directly. There is a big pit here, which will be mentioned later.
  • Open Navigation
    The simplest is to rewrite the onCalculateRouteSuccess() function when implementing the interface in the second step.
Define the implementation of AMapNaviView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- Map Control for Real-time Navigation -->
    <!--<com.amap.api.maps.MapView-->
        <!--android:id="@+id/navi_view"-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="0dp"-->
        <!--android:layout_weight="1"/>-->

    <com.amap.api.navi.AMapNaviView
        android:id="@+id/navi_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>
Life Cycle of AMapNaviView
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //Get an example of AMapNaviView
    mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
    mAMapNaviView.setAMapNaviViewListener(this);

}

@Override
protected void onResume() {
    super.onResume();
    mAMapNaviView.onResume();
}

@Override
protected void onPause() {
    super.onPause();
    mAMapNaviView.onPause();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mAMapNaviView.onDestroy();
}
Open Navigation
@Override
public void onCalculateRouteSuccess() {
    super.onCalculateRouteSuccess();
    mAMapNavi.startNavi(NaviType.GPS);
}

As mentioned above, there is a bug here. That is to say, when we have multiple lines, how do we specify the lines? And even if there is only one route, navigation cannot be achieved here. Real-time navigation at this time is as follows:

At that time, I was very surprised, because demo didn't find out how Activeness of route planning transmitted route, starting point and end point to Activeness of real-time navigation. Later, I found a bright spot in route planning Activity.

mAMapNavi = AMapNavi.getInstance(getApplicationContext());

Navigation external control class object mAMapNavi is actually a case, let's see how to get this object in real-time navigation?

 //Real-time Navigation Acquisition of AMapNavi Example
 mAMapNavi = AMapNavi.getInstance(this);
 //Get an example of AMapNavi in demo
 //com.amap.navi.demo.activity.RouteNaviActivity
 mAMapNavi = AMapNavi.getInstance(getApplicationContext());

Although we have passed in different Context objects, the effect is the same. Let's see how getInstance(Context var0) in AMapNavi source code implements singletons.

public static synchronized AMapNavi getInstance(Context var0) {
        try {
            if(singletonAMapNavi == null) {
                singletonAMapNavi = new AMapNavi(var0);
            }
        } catch (Throwable var2) {
            du.a(var2);
            ey.b(var2, "AMapNavi", "getInstance(Context context)");
        }

        return singletonAMapNavi;
    }

Solve the transmission of starting point and end point, but the line seems to have not solved the value of the designated line yet! This value is also realized in the Route Planning Activity. Look at the event monitoring when we click on one of the routes. The code is as follows:

holder.getView(ll_itemview).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        currentPosition = position;
                        //Selected, re-selected and returned directly
                        if(lastPosition==currentPosition){
                            return;
                        }else{
                            //Current subscripts are assigned to currently selected line Subscripts
                            routeIndex = position;
                            //Replacement of lines
                            changeRoute();
                            //Select Item to set the background
                            selectedBackground(holder);
                            //Clear the background of the last setup
                            cleanSelector();
                        }
                        lastPosition = position;
                    }

                });
    /**
     * Choose routes
     */
    public void changeRoute() {

        //There is only one calculated path.
        if (routeOverlays.size() == 1) {
            //You have to tell AMapNavi which path you chose last.
            mAMapNavi.selectRouteId(routeOverlays.keyAt(0));
            return;
        }

        if (routeIndex >= routeOverlays.size())
            routeIndex = 0;
        //The route ID is obtained by subscribing the selected route.
        int routeID = routeOverlays.keyAt(routeIndex);
        //Highlighting the Road of Choice
        for (int i = 0; i < routeOverlays.size(); i++) {
            int key = routeOverlays.keyAt(i);
            routeOverlays.get(key).setTransparency(0.4f);
        }
        routeOverlays.get(routeID).setTransparency(1);
        /**Higher the weight of the road selected by the user so that the highlight of the route will not change the transparency of the overlapping section.**/
        routeOverlays.get(routeID).setZindex(zindex++);

        //You have to tell AMapNavi which path you chose last.
        mAMapNavi.selectRouteId(routeID);
        routeIndex++;

    }

We see that the mAMapNavi.selectRouteId(int id) method in the code above has been set up, so in real-time navigation, we can start navigation directly without re-planning the route. Here we look directly at the source code of the onCreate (Bundle saved Instance State) method.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        ActionBar actionbar = getSupportActionBar();
        if(actionbar!=null){
            actionbar.hide();
        }
        setContentView(R.layout.activity_gpsnavi);
        //Define the implementation of AMapNaviView 
        mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
        mAMapNaviView.onCreate(savedInstanceState);
        mAMapNaviView.setAMapNaviViewListener(this);
        //Get an example of AMapNavi
        mAMapNavi = AMapNavi.getInstance(this);
        //Adding listen callbacks to handle navigational view event listeners.
        mAMapNavi.addAMapNaviListener(this);
        //Initialize voice engine
        mTtsManager = TTSController.getInstance(getApplicationContext());
        //Instantiated voice engine
        mTtsManager.init();
        //Add navigation event listening. (The key is voice broadcasting)
        mAMapNavi.addAMapNaviListener(mTtsManager);
        //Start Real-time Navigation
        mAMapNavi.startNavi(NaviType.GPS);
        //Start Analog Navigation
        //mAMapNavi.startNavi(NaviType.EMULATOR);

    }

It has solved the problem of real-time navigation and voice playback. ID But finally there is another pit - when our Activity retreats to route planning activity, re-planning the route will fail, even re-initialization will fail, if you don't believe in evil, you can try, then how do we need to solve it? First look at the effect map:

You should see the "X" icon in the lower left corner. When we click on this icon, there will be two situations, one is to pop up a Dialog contained in SDK, the other is to customize an event, but no matter which one, we should always rewrite the event listening method, right?

@Override
 public boolean onNaviBackClick() {
//Callback interface of return button in lower left corner of navigation page 
//  false - Actively pop up the "Exit Navigation" dialog box by SDK.
//  true-SDK does not actively pop up the Exit Navigation Dialog Box, which is customized by users.

     return false;
 }

@Override
    public void onNaviCancel() {
//In the lower left corner of the navigation page, the callback interface after the "exit navigation dialog box" pops up after the button is clicked.
        finish();
    }

The code above calls the finish() method on the Activity, when the Activity executes the onDestroy() method, the AMapNavi object will be destroyed according to the maintenance of the life cycle above, resulting in the AMapNavi object not available when it falls back to the route planning Activity.
So we can modify the onDestroy() method:

@Override
    protected void onDestroy() {
        super.onDestroy();
        mAMapNavi.stopNavi();
        mTtsManager.destroy();
    }

The effect picture will be added in the daytime tomorrow. See the source code for details.

Topics: Android Amap SDK xml