4

I'm creating an Android app for a chinese client and they need map integration, so Google maps is not an option since all Google services are blocked in China. I'm trying to use Baidu maps, which is called Baidu LBS (location-based services) cloud.

Getting a basic map with no overlays to work was relatively easy. The process is described here (in Chinese, but the code speaks for itself if you don't understand the language). Downloading the latest Baidu Android SDK (v3.2.0 at time of writing) and integrating it into my Eclipse project as a library was no problem, but don't trust the documentation in that link too much even though it is the official one. Their examples often contain code that wouldn't even compile. The name of the .jar file for example was completely different from what you see in their screenshot.

Oh and also their .jar library is obfuscated which is super annoying to work with :-(

I needed to register a Baidu account and go to their control center to generate a key. To create an access key ("ak") for mobile you need to enter the SHA1 fingerprint of the keystore which signs your app, followed by the package name specified in your manifest. Then I added the generated key to my manifest under the tag

<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="xxx...xxx" />

I then copied code from their sample project's CloudSearchActivity because I have specific coordinates that I would like to display. I implemented the CloudListener interface as shown:

@Override
public void onGetSearchResult(final CloudSearchResult result, final int error)
{
    Log.w("onGetSearchResult", "status=" + result.status + ". size=" + result.size + ". total=" + result.total + ". error=" + error);
    if(null != result && null != result.poiList && 0 < result.poiList.size())
    {
      mBaiduMap.clear();
      final BitmapDescriptor bitmapDescriptor=BitmapDescriptorFactory.fromResource(R.drawable.icon_address_grey);
      LatLng latitudeLongitude;
      LatLngBounds.Builder builder=new Builder();
      for(final CloudPoiInfo info : result.poiList)
      {
        latitudeLongitude=new LatLng(info.latitude, info.longitude);
        final OverlayOptions overlayOptions=new MarkerOptions().icon(bitmapDescriptor).position(latitudeLongitude);
        mBaiduMap.addOverlay(overlayOptions);
        builder.include(latitudeLongitude);
      }
      final LatLngBounds bounds=builder.build();
      MapStatusUpdate mapStatusUpdate=MapStatusUpdateFactory.newLatLngBounds(bounds);
      mBaiduMap.animateMapStatus(mapStatusUpdate);
    }
}

And I added code to launch a query (also copied from their sample project):

  @Override
  public View onCreateView(final LayoutInflater layoutInflater, final ViewGroup viewGroup,
    final Bundle savedInstanceState)
  {
    // initialize needs to be called
    SDKInitializer.initialize(getApplication());
    CloudManager.getInstance().init(MyFragment.this);

    view=(ViewGroup)layoutInflater.inflate(R.layout.fragment_map, viewGroup, false);

    mMapView=(MapView)view.findViewById(R.id.baiduMapView);
    mBaiduMap=mMapView.getMap();

    NearbySearchInfo info=new NearbySearchInfo();
    info.ak="xxx...xxx";
    info.geoTableId=12345;
    info.tags="";
    info.radius=30000;
    info.location="116.403689,39.914957";
    CloudManager.getInstance().nearbySearch(info);

    return view;
  }

Unfortunately I keep getting a status value of 102 from the server (according to this API page that means STATUS_CODE_SECURITY_CODE_ERROR. Now I don't know what to do. Things that I don't understand:

  1. Why do I need to repeat my access key ("ak") when building the query? Is it not enough to have it in the manifest once?
  2. What is this "geoTableId" value in the query supposed to be?

Any ideas?

peedee
  • 3,257
  • 3
  • 24
  • 42

1 Answers1

1

After many hours of research I have made some progress on the open questions.

  1. The reason for the "ak" field in a cloud search query is not duplication, it is in fact a different access key. Somewhere in a hidden place Baidu says that access keys "for mobile" will not work for these cloud searches, you need an ak "for server". So the solution is to go back to the Baidu control center and create another key "for server". This key needs to be used in the query, while the "for mobile" key needs to remain in the manifest.

  2. geoTableId is an identifier of your account, not unsimilar to the access keys. It is a (currently) 5 digit number that you need to obtain in the Baidu control center. The other keys were generated in the tab titled "API控制台" (API control desk), but for the geoTableId you need to switch to the tab called "数据管理" (data management). There I think I needed to press the "创建" (~create) button on top left, then enter a name, select "是" (yes) where they ask if this is for release (not sure about that translation) and then click "保存" (save). After this, your freshly generated number is displayed in the top field in parentheses behind the name you chose just now.

These steps have allowed me to send "successful" queries where the server answers with status 0 (STATUS_CODE_SUCCEED). However, so far all the answers I get are empty, I have yet to find a query which produces a non-empty answer. If anyone manages to do that, please let me know!

peedee
  • 3,257
  • 3
  • 24
  • 42
  • Hi PeeDeep. Need some help with Baidu maps. I see that you are working on Baidu related stuff. Can you please check this question https://stackoverflow.com/questions/42273462/baidu-android-map-sdk-and-navigation-sdk-integration-2017 – D-D Feb 16 '17 at 12:17
  • Very sorry, but I haven't touched this stuff in over 2 years, barely remember what I did back then :-( – peedee Feb 16 '17 at 12:44