在Unity使用低功耗蓝牙通信(BLE)需要用到设备的位置信息。但是调用Input.location.Start()程序会闪退。
解决办法:调用原生安卓接口。
参见《Unity2021通过aar调用Android方法》编写一个aar插件gpsplugin,在插件中提供获取GPS位置的接口StartGPSLocation,插件代码如下
package com.example.gpsplugin;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;
public class GPSPluginInstance {
private LocationManager locationManager;
private LocationListener locationListener;
private static final int REQUEST_LOCATION_PERMISSION = 1;
double latitude = 0.0;
double longitude = 0.0;
public int Add(int i, int j) {
return i + j;
}
private static Activity unityActivity;
public static void receiveUnityActivity(Activity tActivity) {
unityActivity = tActivity;
}
public void Toast(String msg) {
Toast.makeText(unityActivity, msg, Toast.LENGTH_SHORT).show();
}
public void StartGPSLocation() {
// 初始化 LocationManager
locationManager = (LocationManager) unityActivity.getSystemService(Context.LOCATION_SERVICE);
// 创建 LocationListener
if(locationListener == null)
{
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// 状态改变时调用
}
@Override
public void onProviderEnabled(String provider) {
// 提供者启用时调用
}
@Override
public void onProviderDisabled(String provider) {
// 提供者禁用时调用
}
};
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, locationListener);
}
}
AndroidManifest.xml中添加蓝牙和位置权限(注意Android12以上和之前的版本不一样)
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Unity代码,在使用Input.location.Start()的地方替换成StartGPSLocation就行了
public class BLEBluetoothGunMgr : MonoBehaviour
{
void Start()
{
InitializePlugin("com.example.gpsplugin.GPSPluginInstance");
}
public void GetPos()
{
//Input.location.Start()
StartGPSLocation();
}
void InitializePlugin(string pluginName)
{
unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
_pluginInstance = new AndroidJavaObject(pluginName);
if (_pluginInstance == null)
{
Debug.Log("Plugin Instance Error");
}
_pluginInstance.CallStatic("receiveUnityActivity", unityActivity);
}
public void Toast()
{
if (_pluginInstance != null)
{
_pluginInstance.Call("Toast", "Hi,from Unity");
}
}
public void StartGPSLocation()
{
if (_pluginInstance != null)
{
_pluginInstance.Call("StartGPSLocation");
}
}
}