在前面的文章中,介绍了Android实现UWB的相关框架以及示例程序,在后续的章节中,将从Android源码角度来逐步解析UWB相关实现。
随着官方 Android API 的引入,开发者将能够创建在配备 UWB 硬件的不同 Android 智能手机上无缝工作的应用,而不是使用来自不同 OEM 厂商的不同套装 API。
目前谷歌已经将UWB相关内容放在Android 开源项目(AOSP)中,增加了一个超宽带(UWB)系统API。例如,UwbManager 类 “提供了一种执行 UWB 操作的方法,例如查询设备的能力,确定本地设备和远程设备之间的距离和角度”。API 的实现遵循 IEEE 的 802.15.4z 标准,用于低速率无线网络。(整体为FiRa标准,关于FiRa标准可以查看之前的文章)
到2023年4月,拥有超宽带(UWB)硬件的安卓设备包括三星 Galaxy Note 20, S21+, S22+, Z Fold 2, 3, 4,Google Pixel 6 Pro, Pixel 7 Pro,而使用这一硬件的应用只有三星的 SmartThings 应用的 SmartThings Find 功能。
整体而言,Android UWB 目前仍处于起步阶段,虽然它有望带来巨大的可能性,但其在现实世界中的作用和应用还没有充分实现。随着官方 Android API 的引入,开发者将能够创建在配备 UWB 硬件的不同 Android 智能手机上无缝工作的应用,而不是使用来自不同 OEM 厂商的不同套装 API。
跟踪官方的相关平台文档,可以查到,目前已经可以在android开发平台找到相关接口的文档:
UwbManager ?|? Android Developers
相关的开发内容包括:`androidx.core.uwb
`、`androidx.core.uwb.exception
`。
关于UwbManager的定义也在包:android.uwb
中。
@SystemApi
@SystemService(Context.UWB_SERVICE)
public final class UwbManager {
private static final String TAG = "UwbManager";
private final Context mContext;
private final IUwbAdapter mUwbAdapter;
private final AdapterStateListener mAdapterStateListener;
private final RangingManager mRangingManager;
private final UwbVendorUciCallbackListener mUwbVendorUciCallbackListener;
private final UwbOemExtensionCallbackListener mUwbOemExtensionCallbackListener;
/**
* Interface for receiving UWB adapter state changes
*/
public interface AdapterStateCallback {
// UWB adapter状态改变接口
}
/**
* 抽象类用于接收ADF provision state,需被应用扩展
*/
public abstract static class AdfProvisionStateCallback {
private final AdfProvisionStateCallbackProxy mAdfProvisionStateCallbackProxy;
public AdfProvisionStateCallback() {
mAdfProvisionStateCallbackProxy = new AdfProvisionStateCallbackProxy();
}
//...
private static class AdfProvisionStateCallbackProxy extends
IUwbAdfProvisionStateCallbacks.Stub {
//AIDL接口
}
}
/**
* Interface for receiving vendor UCI responses and notifications.
* 接收供应商UCI响应和通知,由上层应用发送命令
*/
public interface UwbVendorUciCallback {
void onVendorUciResponse(
@IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload);
void onVendorUciNotification(
@IntRange(from = 9, to = 15) int gid, int oid, @NonNull byte[] payload);
}
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public interface UwbOemExtensionCallback {
//Oem扩展接口
}
public UwbManager(@NonNull Context ctx, @NonNull IUwbAdapter adapter) {
mContext = ctx;
mUwbAdapter = adapter;
mAdapterStateListener = new AdapterStateListener(adapter);
mRangingManager = new RangingManager(adapter);
mUwbVendorUciCallbackListener = new UwbVendorUciCallbackListener(adapter);
mUwbOemExtensionCallbackListener = new UwbOemExtensionCallbackListener(adapter);
}
//均需要有UWB权限
@RequiresPermission(permission.UWB_PRIVILEGED)
public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull AdapterStateCallback callback) {
mAdapterStateListener.register(executor, callback);
}
@RequiresPermission(permission.UWB_PRIVILEGED)
public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) {
mAdapterStateListener.unregister(callback);
}
@RequiresPermission(permission.UWB_PRIVILEGED)
public void registerUwbVendorUciCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull UwbVendorUciCallback callback) {
mUwbVendorUciCallbackListener.register(executor, callback);
}
public void unregisterUwbVendorUciCallback(@NonNull UwbVendorUciCallback callback) {
mUwbVendorUciCallbackListener.unregister(callback);
}
//...
@NonNull
@RequiresPermission(allOf = {
permission.UWB_PRIVILEGED,
permission.UWB_RANGING
})
public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
@NonNull @CallbackExecutor Executor executor,
@NonNull RangingSession.Callback callbacks) {
return openRangingSessionInternal(parameters, executor, callbacks, /* chipId= */ null);
}
/* 用户可调用禁止或使能UWB */
@RequiresPermission(permission.UWB_PRIVILEGED)
public void setUwbEnabled(boolean enabled) {
mAdapterStateListener.setEnabled(enabled);
}
/* 返回UWB Chip的信息,通过HAL接口来获取 */
@RequiresPermission(permission.UWB_PRIVILEGED)
@NonNull
public List<PersistableBundle> getChipInfos() {
try {
return mUwbAdapter.getChipInfos();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/* 注册UWB服务profile */
@RequiresPermission(permission.UWB_PRIVILEGED)
@NonNull
public PersistableBundle addServiceProfile(@NonNull PersistableBundle parameters) {
try {
return mUwbAdapter.addServiceProfile(parameters);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* 发送供应商定义UCI消息
* UCI消息格式参考UCI规范,如有必要,平台需负责对有效载荷的分包(fragment)。
*/
@NonNull
@RequiresPermission(permission.UWB_PRIVILEGED)
public @SendVendorUciStatus int sendVendorUciMessage(
@IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload) {
Objects.requireNonNull(payload, "Payload must not be null");
try {
return mUwbAdapter.sendVendorUciMessage(MESSAGE_TYPE_COMMAND, gid, oid, payload);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
MESSAGE_TYPE_COMMAND,
MESSAGE_TYPE_TEST_1,
MESSAGE_TYPE_TEST_2,
})
@interface MessageType {}
/**
* 自定义类型供应商定义UCI消息
* 注意:消息类型(mt)是在方法参数的开头添加的,因此比其他参数更独特,且是供应商要求的。
*/
@NonNull
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@RequiresPermission(permission.UWB_PRIVILEGED)
public @SendVendorUciStatus int sendVendorUciMessage(@MessageType int mt,
@IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload) {
Objects.requireNonNull(payload, "Payload must not be null");
try {
return mUwbAdapter.sendVendorUciMessage(mt, gid, oid, payload);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private static class OnUwbActivityEnergyInfoProxy
extends IOnUwbActivityEnergyInfoListener.Stub {
//AIDL接口实现
}
}
????????从注释上我们可以看到,UwbManager提供了一种执行超宽带(UWB)操作的方法,例如查询设备的能力,以及确定本地设备和远程设备的距离以及角度。
????????API surface使用不透明的参数。这些参数将使用所提供的UWB支持库创建。支持库在AOSP:package/modules/Uwb/service/support_lib
。
????????要获取UwbManager,可以通过Context.getSystemServie(UwbManager.class)
来实现。
openRangingSession
如果会话使用FiRa定义的配置文件(而不是自定义配置文件),则会触发:
permission.BLUETOOTH_ADVERTISE
permission.BLUETOOTH_SCAN
permission.BLUETOOTH_CONNECT
若会话不能打开,则会触发适当的原因。RangingSession.Callback.Reason
关于参数限定为PersistableBundle
,必须使用UWB支持库,以构造对应参数,定义测距会话。
根据前文介绍的Android-UWB技术框架,在UwbManager之后,就是UWB Service,将陆续在后续的文章中进行分析。