草庐IT

Unity Android 接入高德定位SDK

小张不爱写代码 2023-12-10 原文

Unity版本 2020

第一步首先去高德开放平台注册账号然后申请Key

高德开放平台 | 高德地图API

注册好账号之后 点击控制台 然后选择管理key 新建一个应用 

 选择添加  然后创建一个key 选择Android平台  SHA1码获取方式参考我的另一篇博客

Android 签名文件.keystore转换.jks_小张不爱写代码的博客-CSDN博客_keystore转jks

 然后直接创建key即可

创建完毕之后去下载定位SDK

相关下载-Android 定位SDK | 高德地图API

打开Unity创建一个Unity项目

并创建如下脚本

using UnityEngine;
using UnityEngine.UI;

public class Sdk : MonoBehaviour
{
    public Text t;
    private AndroidJavaClass jc;
    private AndroidJavaObject jo;
    private void Awake()
    {
        if (Application.platform == RuntimePlatform.Android)
        {
            jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        }
    }

    public void StartAMap()
    {
        switch (Application.platform)
        {
            case RuntimePlatform.Android:
                jo.Call("StartAMap");
                break;
            default:
                StopAMapCallBack();
                break;
        }
    }

    public void StopAMap()
    {
        switch (Application.platform)
        {
            case RuntimePlatform.Android:
                jo.Call("StopAMap");
                break;
            default:
                break;
        }
    }
    public void StartAMapCallBack(string msg)
    {
        t.text = msg;
    }

    public void StopAMapCallBack()
    {
        t.text = "1111";
    }
}

然后创建如下结构 Button点击事件分别指向StartAMap和StopAMap即可

 然后直接出包导出AndroidStudio项目

导出完成之后 现在AS工程中的Libs文件夹中放入解压的高德SDK jar包

 导入之后在如图位置写入如下代码

implementation fileTree(dir: 'libs', include: ['*.jar'])

在AndroidManifest.xml上面写入如下权限

  <!--用于进行网络定位-->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <!--用于访问GPS定位-->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  <!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  <!--用于访问网络,网络定位需要上网-->
  <uses-permission android:name="android.permission.INTERNET" />
  <!--用于读取手机当前的状态-->
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <!--用于写入缓存数据到扩展存储卡-->
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
      tools:ignore="ScopedStorage" />
  <!--用于申请调用A-GPS模块-->
  <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
  <!--如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限-->
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
  <!--如果您的应用需要后台定位权限,且有可能运行在Android Q设备上,并且设置了target>28,必须增加这个权限声明-->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
      tools:ignore="ScopedStorage" />

在AndroidManifest.xml的Application节点内写入如下内容

  <meta-data
     android:name="com.amap.api.v2.apikey"
     android:value="6c8580a005a4f6d162f59e17ace1fbca" />
  <service android:name="com.amap.api.location.APSService" />

打开UnityPlayerActivity脚本 在末尾加入如下代码 用以动态申请权限

//权限管理
private static final String[] PERMISSIONS =
{
    Manifest.permission.INTERNET,
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_NETWORK_STATE,
    Manifest.permission.ACCESS_WIFI_STATE,
    Manifest.permission.CHANGE_WIFI_STATE,
    Manifest.permission.READ_PHONE_STATE,
    Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
    Manifest.permission.BLUETOOTH,
    Manifest.permission.BLUETOOTH_ADMIN,
};
private static final int PERMISSIONS_CODE = 1;
//申请权限
private void requestPermission()
{
    // 当API大于 23 时,才动态申请权限
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    {
        ActivityCompat.requestPermissions(this,PERMISSIONS,PERMISSIONS_CODE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case PERMISSIONS_CODE:
            //权限请求失败
            for(int i=0;i<grantResults.length-1;i++)
            {
                if(grantResults[i] != PackageManager.PERMISSION_GRANTED)
                {
                    Log.e("Permissions", "onRequestPermissionsResult: 权限请求失败:"+permissions[i].toString());
                }
            }
            break;
    }
}

然后在UnityPlayerActivity脚本中的OnCreate方法中调用requestPermission方法来申请权限

新创建一个类 写入如下代码

package com.unity3d.player.GaoDe;
import android.util.Log;
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.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class GaoDe {
    private static GaoDe instance = null;
    private static UnityPlayerActivity ccActivity = null;

    public static GaoDe Ins() {
        if (instance == null) {
            instance = new GaoDe();
        }
        return instance;
    }
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    //声明定位回调监听器
    public AMapLocationListener mLocationListener = null;
    //声明AMapLocationClientOption对象
    public AMapLocationClientOption mLocationOption = null;

    public void Init(UnityPlayerActivity act){
        ccActivity =  act;
        //初始化定位
        AMapLocationClient.updatePrivacyShow(ccActivity, true, true);
        AMapLocationClient.updatePrivacyAgree(ccActivity, true);
        try {
            //初始化定位
            mLocationClient = new AMapLocationClient(ccActivity);
        }catch (Exception e){
            e.printStackTrace();
            Log.d("Unity", "UnityPlayerActivity Init error: "+e);
        }
        //初始化AMapLocationClientOption对象
        mLocationOption = new AMapLocationClientOption();
        //设置定位监听
        mLocationListener = new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {
                OnLocationChanged(aMapLocation);
            }
        };
        //设置定位回调监听
        mLocationClient.setLocationListener(mLocationListener);
        //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置定位间隔,单位毫秒,默认为2000ms,最低1000ms。
        mLocationOption.setInterval(1000);
        //单位是毫秒,默认30000毫秒,建议超时时间不要低于8000毫秒。
        mLocationOption.setHttpTimeOut(8000);
        //优先使用gps
        mLocationOption.setGpsFirst(true);
        Log.d("Unity", "高德: InitOK");
    }

    private void OnLocationChanged(AMapLocation amapLocation){
        Log.d("Unity", "高德: OnLocationChanged");
        if(amapLocation == null) {
            amapLocation = mLocationClient.getLastKnownLocation();
        }
        if (amapLocation != null)
        {
            Log.e("AmapError", "amapLocation~=null start:");
            mLocationClient.stopLocation();
            int errorCode = amapLocation.getErrorCode();
            Log.e("AmapError", "amapLocation~=null errorCode:"+errorCode);
            //定位成功回调信息,设置相关消息
            int locationType = amapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表
            double longitude = amapLocation.getLongitude();//获取经度
            double latitude = amapLocation.getLatitude();//获取纬度
            String address = amapLocation.getAddress();
            String country = amapLocation.getCountry();
            String province = amapLocation.getProvince();
            String city = amapLocation.getCity();
            String district = amapLocation.getDistrict();
            String re = errorCode + "|" + longitude + "|" + latitude + "|" + address +"|"+ country +"|"+ province +"|"+ city +"|"+ district+"  errrrrrrr";
            Log.e("AmapError", "amapLocation~=null 位置信息:"+re);
            UnityPlayer.UnitySendMessage("Main Camera", "StartAMapCallBack", re);
        }
        else
        {
            //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
            Log.e("AmapError","location Error, ErrCode:"
                    + amapLocation.getErrorCode() + ", errInfo:"
                    + amapLocation.getErrorInfo());
            mLocationClient.stopLocation();
            UnityPlayer.UnitySendMessage("Main Camera", "StartAMapCallBack", "0|0|0");
        }
    }

    //开始定位
    public void StartAMap()
    {
        if(mLocationClient!=null) {
            //给定位客户端对象设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            //启动定位
            mLocationClient.startLocation();
            Log.d("Unity", "StartAMap: 已开启定位");
        }
        else{
            if(ccActivity!=null)
                Init(ccActivity);
            else
                Log.d("Unity", "StartAMap: mLocationClient是空的");
        }
    }

    //停止定位
    public void StopAMap()
    {
        if(mLocationClient!=null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
            mLocationOption = null;
            mLocationListener = null;
            UnityPlayer.UnitySendMessage("Main Camera", "StopAMapCallBack","");
        }
    }
}

打开UnityPlayerActivity脚本在最末尾加入如下代码 在OnCreate申请权限下面调用

GaoDe.Ins().Init(this); 用以初始化SDK

public void StartAMap(){
    GaoDe.Ins().StartAMap();
}

public void StopAMap()
{
    GaoDe.Ins().StopAMap();
}

然后就可以打包apk进行测试了  出现如下结果即可

有关Unity Android 接入高德定位SDK的更多相关文章

  1. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  2. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  3. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  4. 三分钟集成 TapTap 防沉迷 SDK(Unity 版) - 2

    三分钟集成Tap防沉迷SDK(Unity版)一、SDK介绍基于国家对上线所有游戏必须增加防沉迷功能的政策下,TapTap推出防沉迷SDK,供游戏开发者进行接入;允许未成年用户在周五、六、日以及法定节假日晚上8:00-9:00进行游戏,防沉谜时间段进入游戏会弹窗进行提示!开发环境要求:Unity2019.4或更高版本iOS10或更高版本Android5.0(APIlevel21)或更高版本🔗Unity集成Demo参考链接🔗UnityTapSDK功能体验APK下载链接二、集成前准备1.创建应用进入开发者后台,按照提示开始创建应用;2.开通服务在使用TDS实名认证和防沉迷服务之前,需要在上面创建的应

  5. ruby - 如何使用适用于 ruby​​ 的 aws sdk 创建 route53 记录集? - 2

    EC2会在实例停止然后重新启动时为其提供新的IP地址,因此我需要能够自动管理route53记录集,以便我可以一致地访问内容。遗憾的是,sdk的route53部分的文档远不如ec2的文档那么健壮(可以理解),所以我有点卡住了。到目前为止,从我所看到的情况来看,似乎change_resource_record_sets(link)是可行的方法,但我对:chages需要什么感到困惑>因为它提到了一个Change对象,但没有提供指向所述对象描述的链接。这是我的代码目前的样子:r53.client.change_resource_record_sets(:hosted_zone_id=>'MY_

  6. Ruby AWS::S3::S3Object (aws-sdk):是否有与 aws-s3 一样的流式数据方法? - 2

    在aws-s3中,有一种方法(AWS::S3::S3Object.stream)可让您将S3上的文件流式传输到本地文件。我无法在aws-sdk中找到类似的方法。即在aws-s3中,我这样做:File.open(to_file,"wb")do|file|AWS::S3::S3Object.stream(key,region)do|chunk|file.writechunkendendAWS::S3:S3Object.read方法确实将block作为参数,但似乎没有对其执行任何操作。 最佳答案 aws-sdkgem现在支持S3中对象的分

  7. ruby - 使用aws sdk获取带有特定标签的ec2实例 - 2

    我正在尝试找出使用ruby​​awssdk获取带有特定标签(例如“测试”)的ec2实例列表的最佳方法。ec2=AWS::EC2.new(:access_key_id=>"XXXXXXXXXXXXX",:secret_access_key=>"YYYYYYYYY")ec2list=ec2.instances.filter("Name","testing)由于某些原因,这似乎不起作用。它认为它会过滤掉集合,只给我带有标签测试的实例。有没有办法使用ruby​​sdk来做到这一点?谢谢。 最佳答案 如果您想要标签“Name”的值为“test

  8. ruby-on-rails - 使用 aws-sdk gem 删除 Amazon S3 上的 "Folder" - 2

    我可以使用以下方法删除AmazonS3上“文件夹”中的单个文件:s3=AWS::S3.new(:access_key_id=>ENV['AWS_ACCESS_KEY_ID'],:secret_access_key=>ENV['AWS_ACCESS_KEY'])folder_path='uploads/'+@image.s3_filenames3.buckets[ENV['AWS_BUCKET']].objects.with_prefix(folder_path).delete_all但这会留下一个空文件夹。我怎样才能完全删除文件夹(folder_path)?

  9. MicroBlaze在纯FPGA下 Xilinx SDK固化程序到外部SPI FLASH - 2

    外部SPIFLASH:MicronN25Q128A13ESE40G(128Mbit(16MByte))FPGA:XC7A100T CPU:Microblaze第一种情况:Microblaze在简单的应用,比如运行LED,IIC,SPI,UART之类的低俗接口驱动,或做一些简单的辅助型工作时,一般生成的applicationelf文件都不大,在10几KB或者几十,百几KB,此时使用FPGA内部的BRAM资源已经足够。XC7A100T本身就有600几KB的BRAM资源。这种情况下直接将硬件流文件和elf文件合并为download.bit文件,在直接烧录到外部SPIFLAH即可。1.Xilinx--

  10. 打通源码,高效定位代码问题|云效工程师指北 - 2

    大家好,我叫胡飞虎,花名虎仔,目前负责云效旗下产品Codeup代码托管的设计与开发。代码作为企业最核心的数据资产,除了被构建、部署之外还有更大的价值。为了帮助企业和团队挖掘更多源代码价值以赋能日常代码研发、运维等工作,云效代码团队在大数据和智能化方向进行了一系列的探索和实践(例如代码搜索与推荐),本文主要介绍我们如何通过直接打通源代码来提高研发与运维效率。随着微服务架构的流行,一个业务流程需要多个微服务共同完成。一旦出现问题,运维人员在面对数量多、调用链路复杂的情况下,很难快速锁定导致问题发生的罪魁祸首:代码。为了提高排查效率,目前常见的解决方案是:链路跟踪+日志分析工具相结合。即通过链路跟踪

随机推荐