安卓百度地图:访问密钥不适用于位置搜索



我正在为中国客户创建一个Android应用程序,他们需要地图集成,所以谷歌地图不是一个选择,因为所有谷歌服务在中国都被封锁了。我正在尝试使用百度地图,它被称为百度LBS(基于位置的服务)云。

获得没有叠加层的基本地图相对容易。这里描述了这个过程(用中文,但如果你不懂语言,代码不言自明)。下载最新的百度 Android SDK(撰写本文时为 v3.2.0)并将其作为库集成到我的 Eclipse 项目中没有问题,但不要太相信该链接中的文档,即使它是官方文档。他们的例子通常包含甚至无法编译的代码。例如,.jar文件的名称与您在其屏幕截图中看到的名称完全不同。

哦,还有他们的.jar库被混淆了,使用起来非常烦人:-(

我需要注册一个百度帐户,然后去他们的控制中心生成密钥。要为移动设备创建访问密钥 ("ak"),您需要输入对应用进行签名的密钥库的 SHA1 指纹,后跟清单中指定的软件包名称。然后,我将生成的密钥添加到标签下的清单中

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

然后,我从他们示例项目的 CloudSearchActivity 中复制了代码,因为我有想要显示的特定坐标。我实现了 CloudListener 接口,如下所示:

@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);
    }
}

我添加了代码来启动查询(也从他们的示例项目中复制):

  @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;
  }

不幸的是,我一直从服务器获得 102 的状态值(根据此 API 页面,这意味着STATUS_CODE_SECURITY_CODE_ERROR.现在我不知道该怎么办。我不明白的事情:

  1. 为什么在构建查询时需要重复我的访问密钥 ("ak")?在清单中拥有一次还不够吗?
  2. 查询中的这个"geoTableId"值应该是什么?

有什么想法吗?

经过几个小时的研究,我在开放性问题上取得了一些进展。

  1. 云搜索查询中"ak"字段的原因不是重复,它实际上是一个不同的访问密钥。在一个隐蔽的地方,百度说"移动"的访问密钥不适用于这些云搜索,你需要一个ak"for server"。所以解决方案是回到百度控制中心,为服务器创建另一个密钥。此键需要在查询中使用,而"适用于移动设备"键需要保留在清单中。

  2. geoTableId 是您帐户的标识符,与访问密钥不相似。这是一个(目前)5位数字,您需要在百度控制中心获得。其他键是在标题为"API控制台"(API控制台)的选项卡中生成的,但是对于geoTableId,您需要切换到名为"数据管理"(数据管理)的选项卡。在那里,我想我需要按左上角的"创建"(~创建)按钮,然后输入一个名称,选择"是"(是),他们询问这是否要发布(不确定该翻译),然后单击"保存"(保存)。在此之后,您新生成的号码将显示在您刚才选择的名称后面的括号中的顶部字段中。

这些步骤允许我发送"成功"查询,其中服务器以状态 0 (STATUS_CODE_SUCCEED) 进行应答。但是,到目前为止,我得到的所有答案都是空的,我还没有找到产生非空答案的查询。如果有人设法做到这一点,请告诉我!

最新更新