高德LBS使用以及注意事项+debug版本直接用release的签名配置

1.注册一个LBS的账号申请Key 点击打开链接

其中:Package以及SHA1的获取可见:这里

让楼主郁闷的是明明一样的key就是报错:INVALID_USER_SCODE

查找一些资料得出如下结论:

1、注册的sha1与应用签名的签名文件(包括debug.keystore)的sha1不一致。
2、Debug和release的签名文件不一样,所以最好对应注册两个不同的key,避免发布后INVALID_USER_KEY。
3、注册key时应用的包名填写不正确
4、manifest文件中mete-data标签在application标签之外。

楼主Debug跟Release的就没关注

下面上改后的代码:(需要把jks拷入app对应目录) 

这样编译出来的debug版本直接用的是正式签名(release)噢

signingConfigs {
    release {
        storeFile file("key.story.jks")
        storePassword "123456"
        keyAlias "key"
        keyPassword "123456"
    }
}
buildTypes {
    debug {
        signingConfig signingConfigs.release
    }
    release {
        signingConfig signingConfigs.release
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

2.去官网下载jar...

点击打开链接



3.配置manifest

配置AndroidManifest.xml

首先,请在application标签中声明service组件,每个app拥有自己单独的定位service。

1
<service android:name= "com.amap.api.location.APSService" ></service>

接下来声明使用权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--用于进行网络定位-->
<uses-permission android:name= "android.permission.ACCESS_COARSE_LOCATION" ></uses-permission>
<!--用于访问GPS定位-->
<uses-permission android:name= "android.permission.ACCESS_FINE_LOCATION" ></uses-permission>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE" ></uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name= "android.permission.ACCESS_WIFI_STATE" ></uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name= "android.permission.CHANGE_WIFI_STATE" ></uses-permission>
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name= "android.permission.INTERNET" ></uses-permission>
<!-- 用于读取手机当前的状态-->
<uses-permission android:name= "android.permission.READ_PHONE_STATE" ></uses-permission>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据-->
<uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>

最后设置Key,在application标签中加入

1
2
3
<meta-data android:name= "com.amap.api.v2.apikey" android:value= "key" > //开发者申请的key      
             
</meta-data>

然后楼主搞了一个地图

想实现一个定位功能,楼主是在不才未能使用官网推荐的方式实现。其中还遇到过白地图的问题,原因是父控件透明度不是满状态!强烈鄙视官网的帮助!
下面贴上楼主定位库和标注实现的定位功能,先凑合用吧!
package tr.nuctech.com.tr0100.Activity;

import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.view.animation.Interpolator;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.Projection;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;

import java.util.ArrayList;
import java.util.List;

import tr.nuctech.com.tr0100.Bean.Constants;
import tr.nuctech.com.tr0100.R;
import tr.nuctech.com.tr0100.Util.LBSUtils;

public class MapActivity extends AppCompatActivity implements LocationSource,
        AMapLocationListener, AMap.OnMarkerClickListener {

    private MapView mapView;
    private AMap aMap;
//    private OnLocationChangedListener mListener;
    //初始化定位对象
    private AMapLocationClient locationClient = null;
    private AMapLocationClientOption locationOption = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        mapView = (MapView) findViewById(R.id.id_map);
        mapView.onCreate(savedInstanceState);// 此方法必须重写

        init();

        //初始化定位模块
        locationClient = new AMapLocationClient(this);
        locationOption = new AMapLocationClientOption();
//             设置定位模式为
        locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        // 设置定位监听
        locationClient.setLocationListener(this);
//            //只有持续定位设置定位间隔才有效,单次定位无效
//            layoutInterval.setVisibility(View.VISIBLE);
        //设置为不是单次定位
        locationOption.setOnceLocation(true);
        // 设置定位参数
        locationClient.setLocationOption(locationOption);
        new Thread(){
            @Override
            public void run() {
                super.run();
                        // 启动定位
                try {
                    Thread.sleep(2000);
                    locationClient.startLocation();
                    mHandler.sendEmptyMessage(LBSUtils.MSG_LOCATION_START);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }.start();

    }
    /**  * 初始化AMap对象  */  private void init() {
        if (aMap == null) {
            aMap = mapView.getMap();
            aMap.setLocationSource(this);// 设置定位监听
            aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
            aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
// 设置定位的类型为定位模式,参见类AMap            aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
            //marker
//            aMap.setOnMarkerDragListener(this);// 设置marker可拖拽事件监听器
//            aMap.setOnMapLoadedListener(this);// 设置amap加载成功事件监听器
            aMap.setOnMarkerClickListener(this);// 设置点击marker事件监听器
//            aMap.setOnInfoWindowClickListener(this);// 设置点击infoWindow事件监听器
//            aMap.setInfoWindowAdapter(this);// 设置自定义InfoWindow样式

        }
    }

    Handler mHandler = new Handler(){
        public void dispatchMessage(android.os.Message msg) {
            switch (msg.what) {
                case LBSUtils.MSG_LOCATION_START:
                    Toast.makeText(MapActivity.this,"正在定位...",Toast.LENGTH_SHORT).show();
                    break;
                //定位完成
                case LBSUtils.MSG_LOCATION_FINISH:
                    AMapLocation loc = (AMapLocation)msg.obj;
                    String result = LBSUtils.getLocationStr(loc);
                    Toast.makeText(MapActivity.this,result,Toast.LENGTH_SHORT).show();
//                    tvReult.setText(result);
                    break;
                case LBSUtils.MSG_LOCATION_STOP:
                    Toast.makeText(MapActivity.this,"定位停止",Toast.LENGTH_SHORT).show();

                    break;
                default:
                    break;
            }
        };
    };
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != locationClient) {
            /**  * 如果AMapLocationClient是在当前Activity实例化的,  * ActivityonDestroy中一定要执行AMapLocationClientonDestroy  */  locationClient.onDestroy();
            locationClient = null;
            locationOption = null;
        }
    }

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

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

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        //定位回调
        Toast.makeText(this,"onLocationChanged",Toast.LENGTH_SHORT).show();
        if (this != null && aMapLocation != null) {
            if (aMapLocation != null
                    && aMapLocation.getErrorCode() == 0) {

//                this.onLocationChanged(aMapLocation);// 显示系统小蓝点
                LatLng postion=new LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude());
                        CameraPosition position=new CameraPosition(postion
                , 18, 0, 30);
        aMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
                initMark(postion);
            }
            else
            {
                String errText = "定位失败," + aMapLocation.getErrorCode()+ ": " + aMapLocation.getErrorInfo();
                Toast.makeText(this,"errText",Toast.LENGTH_SHORT).show();
            }
        }
//        if (null != aMapLocation) {
//            Message msg = mHandler.obtainMessage();
//            msg.obj = aMapLocation;
//            msg.what = LBSUtils.MSG_LOCATION_FINISH;
//            mHandler.sendMessage(msg);
//        }


    }

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        Toast.makeText(this,"activate",Toast.LENGTH_SHORT).show();

    }

    @Override
    public void deactivate() {
        Toast.makeText(this,"deactivate",Toast.LENGTH_SHORT).show();
    }
    private void initMark(LatLng latLng)
    {
        ArrayList<BitmapDescriptor> giflist = new ArrayList<BitmapDescriptor>();
        giflist.add(BitmapDescriptorFactory
                .defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
        giflist.add(BitmapDescriptorFactory
                .defaultMarker(BitmapDescriptorFactory.HUE_RED));
        giflist.add(BitmapDescriptorFactory
                .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));

        MarkerOptions markerOption1 = new MarkerOptions().anchor(0.5f, 0.5f)
                .position(latLng).title("同方威视")
                .snippet("Creating a safer world").icons(giflist)
                .draggable(true).period(50);
        ArrayList<MarkerOptions> markerOptionlst = new ArrayList<MarkerOptions>();
        markerOptionlst.add(markerOption1);
        List<Marker> markerlst = aMap.addMarkers(markerOptionlst, true);

    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        jumpPoint(marker);
        return false;
    }
    /**  * marker点击时跳动一下  */  public void jumpPoint(final Marker marker) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();

        Projection proj = aMap.getProjection();
        Point startPoint = proj.toScreenLocation(Constants.XIAN);
        startPoint.offset(0, -100);
        final LatLng startLatLng = proj.fromScreenLocation(startPoint);
        final long duration = 1500;

        final Interpolator interpolator = new BounceInterpolator();
        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);
                double lng = t * Constants.XIAN.longitude + (1 - t)
                        * startLatLng.longitude;
                double lat = t * Constants.XIAN.latitude + (1 - t)
                        * startLatLng.latitude;
//                marker.setPosition(new LatLng(lat, lng));
                marker.setPosition(marker.getPosition());
                if (t < 1.0) {
                    handler.postDelayed(this, 16);
                }
            }
        });
    }
}

启动定位功能

高德定位服务包含GPS和网络定位(Wi-Fi和基站定位)两种能力。定位SDK将GPS、网络定位能力进行了封装,以三种定位模式对外开放

高精度定位模式:会同时使用网络定位和GPS定位,优先返回最高精度的定位结果;

低功耗定位模式:不会使用GPS,只会使用网络定位(Wi-Fi和基站定位);

仅用设备定位模式:不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位。

第一步,初始化定位客户端,设置监听

注:请在主线程中声明AMapLocationClient类对象,需要传Context类型的参数。推荐用getApplicationConext()方法获取全进程有效的context。

1
2
3
4
5
6
7
8
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient =  null ;
//声明定位回调监听器
public AMapLocationListener mLocationListener =  new AMapLocationListener();
//初始化定位
mLocationClient =  new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mlocationClient.setLocationListener(mLocationListener);

第二步,配置定位参数,启动定位

设置定位参数包括:定位模式(高精度定位模式,低功耗定位模式和仅设备定位模式),是否返回地址信息等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//声明mLocationOption对象
public AMapLocationClientOption mLocationOption =  null ;
//初始化定位参数
mLocationOption =  new AMapLocationClientOption();
//设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
//设置是否返回地址信息(默认返回地址信息)
mLocationOption.setNeedAddress( true );
//设置是否只定位一次,默认为false
mLocationOption.setOnceLocation( false );
//设置是否强制刷新WIFI,默认为强制刷新
mLocationOption.setWifiActiveScan( true );
//设置是否允许模拟位置,默认为false,不允许模拟位置
mLocationOption.setMockEnable( false );
//设置定位间隔,单位毫秒,默认为2000ms
mLocationOption.setInterval( 2000 );
//给定位客户端对象设置定位参数
mlocationClient.setLocationOption(mLocationOption);
//启动定位
mlocationClient.startLocation();

第三步,实现AMapLocationListener接口,获取定位结果

AMapLocationListener接口只有onLocationChanged方法可以实现,用于接收异步返回的定位结果,参数是AMapLocation类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public void onLocationChanged(AMapLocation amapLocation) {
     if (amapLocation !=  null ) {
         if (amapLocation.getErrorCode() ==  0 ) {
         //定位成功回调信息,设置相关消息
         amapLocation.getLocationType(); //获取当前定位结果来源,如网络定位结果,详见定位类型表
         amapLocation.getLatitude(); //获取纬度
         amapLocation.getLongitude(); //获取经度
         amapLocation.getAccuracy(); //获取精度信息
         SimpleDateFormat df =  new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
         Date date =  new Date(amapLocation.getTime());
         df.format(date); //定位时间
         amapLocation.getAddress(); //地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
         amapLocation.getCountry(); //国家信息
         amapLocation.getProvince(); //省信息
         amapLocation.getCity(); //城市信息
         amapLocation.getDistrict(); //城区信息
         amapLocation.getStreet(); //街道信息
                 amapLocation.getStreetNum(); //街道门牌号信息
         amapLocation.getCityCode(); //城市编码
         amapLocation.getAdCode(); //地区编码
     else {
               //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
         Log.e( "AmapError" , "location Error, ErrCode:"
             + amapLocation.getErrorCode() +  ", errInfo:"
             + amapLocation.getErrorInfo());
         }
     }
}

第四步,关于停止定位

停止定位:

1
mlocationClient.stopLocation(); //停止定位

销毁定位客户端:

销毁定位客户端之后,若要重新开启定位请重新New一个AMapLocationClient对象。

1
mlocationClient.onDestroy(); //销毁定位客户端。

地理围栏

地理围栏功能,是以一个圆形的地理边界作为虚拟围栏,当手机进入、离开该区域时,手机可以接收自动通知。

AMapLocationClient类的 addGeoFenceAlert(int fenceId,double latitude,double longitude, float radius, long expiration, PendingIntent intent) 方法可用于添加地理围栏,该方法的参数:

fenceId-围栏id

latitude-警戒区域中心点的纬度。

longitude-警戒区域中心点的经度。

radius-警戒区域的半径,单位为米。

expiration-警戒时间,单位为毫秒,设置为-1时表示没有时间限制。

intent-当检测到进入或离开警戒区域时将被激活的PendingIntent。该 intent 的 Bundle 的 status 字段值为0表示从区域中离开,1表示进入该区域。

说明:只在进入或离开警戒区域时给出一次警告信息,在警戒区域内活动或者在区域外活动无警告。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//实例化定位客户端
AMapLocationClient mlocationClient =  null ;
mlocationClient =  new AMapLocationClient(getApplicationContext());
 
//注册Receiver,设置过滤器
IntentFilter fliter =  new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
         fliter.addAction(GEOFENCE_BROADCAST_ACTION);
//mGeoFenceReceiver为自定义的广播接收器
registerReceiver(mGeoFenceReceiver, fliter);
 
//声明对应的intent对象
Intent intent =  new Intent(GEOFENCE_BROADCAST_ACTION);
//创建PendingIntent对象
PendingIntent mPendingIntent =  null ;
mPendingIntent = PendingIntent.getBroadcast(getApplicationContext(),  0 ,intent,  0 );
 
//添加地理围栏
mlocationClient.addGeoFenceAlert(fenceId, latLng.latitude,latLng.longitude,  1000 1000 60 30 , mPendingIntent);
 
//自定义广播接收器
private BroadcastReceiver mGeoFenceReceiver =  new BroadcastReceiver() {
     @Override
     public void onReceive(Context context, Intent intent) {
             // 接收广播内容,处理进出的具体操作。               
         }
     };
        //启动定位
mlocationClient.startLocation();

坐标转换

支持GPS/Mapbar/Baidu等多种类型坐标在高德地图上使用。参见类CoordinateConverter。

1
2
3
4
5
6
7
CoordinateConverter converter  =  new CoordinateConverter(); 
// CoordType.GPS 待转换坐标类型
converter.from(CoordType.GPS); 
// sourceLatLng待转换坐标点 DPoint类型
converter.coord(sourceLatLng); 
// 执行转换操作
DPoint desLatLng = converter.convert();

判断位置所在区域

CoordinateConverter类提供的isAMapDataAvailable(double latitude,double longitude)接口可以用来判断指定位置是否在大陆以及港、澳地区。

自2.2版本isAMapDataAvailable(double latitude,double longitude)方法参数进行了调整,第一个参数传纬度,第二个参数传经度;

1
2
3
4
CoordinateConverter converter  =  new CoordinateConverter(); 
//返回true代表当前位置在大陆、港澳地区,反之不在。
boolean isAMapDataAvailable = converter.isAMapDataAvailable(latitude,longitude);
//第一个参数为纬度,第二个为经度,纬度和经度均为高德坐标系。

注意事项

● 目前手机设备在长时间黑屏或锁屏时CPU会休眠,这导致定位SDK不能正常进行位置更新。若您有锁屏状态下获取位置的需求,您可以应用alarmManager实现1个可叫醒CPU的Timer,定时请求定位。

● 使用定位SDK务必要注册GPS和网络的使用权限。

● 在使用定位SDK时,请尽量保证网络畅通,如获取网络定位,地址信息等都需要设备可以正常接入网络。

● 定位SDK在国内返回高德类型坐标,海外定位将返回GPS坐标。

● 仅设备定位(通过GPS定位)是设备本地定位行为,是不返回地址信息的,地址信息在网络定位时会返回。


你可能感兴趣的:(高德LBS使用以及注意事项+debug版本直接用release的签名配置)