我试图在4.3中使用新的BTLE API在Nexus 7上实现BTLE SERVER.我遇到了几个问题.首先,SDK没有示例.唯一的例子是客户.其次,文档实际上告诉你做错了.它声明必须使用该BluetoothAdapter.getProfileProxy() with a BluetoothProfile.GATT_SERVER参数来获取BluetoothGattServer对象.这种方法可行,但是人们无法将其实现BluetoothGattServerCallback与BLE堆栈相关联.(此回调是人们如何响应客户端读取和写入请求等.)但是,在问题58582上遇到绊脚石后,开发人员指出了一个新BluetoothManager.openGattServer()方法,它将您的回调作为参数并返回一个BluetoothGattServer对象.好吧,一个问题解决了.
下一个问题更成问题.该BluetoothGattServer文档指出,可以使用此类来创建和宣传蓝牙LE服务和特征.创建服务等不是问题,但他们忽略了如何开始做广告.类本身或我可以找到的任何其他类中没有方法.
有谁知道如何做到这一点?目前我所能看到的是使用客户端使用的相同方法,但这种方法涉及扫描(不是广告).所有文档进一步表明,BluetoothAdapter.startLeScan()IS确实只是用于扫描.
那么一旦我的所有服务,特征和描述符到位,我该如何调用广告?
设置一个请求客户端身份验证的嵌入式Jetty服务器非常容易:只需要添加语句SslContextFactory.setNeedClientAuth(true); 配置服务器时的ssl上下文.在服务器的信任库中拥有其证书的任何客户端都将能够与服务器建立TLS连接.
但是,我需要知道所有可能的可信客户端的哪个客户端正在发出请求; 换句话说,我需要知道此连接中使用的客户端证书,特别是在处理程序中.有谁知道如何访问此证书或甚至可能?
我的目标是让Android设备重新连接到之前连接的BLE设备而无需用户干预,就像它对经典BT配对设备一样(甚至可以通过电源循环工作).
BTLE设备的一个想法是节省服务,绑定和启用状态,使得重新连接非常快并且在外围设备上消耗非常少的功率.
我所做的似乎有效,但效果不佳.
第一步是连接或配对并连接到新设备,将'autoconnect'参数设置为'true'.当设备断开连接时,请不要调用 gatt.close().无论我到哪里,我都会看到应该调用gatt.close().但如果我打电话给gatt.close(),Android中心应用程序永远不会重新连接.我已经多次测试过了.
如果我没有调用gatt.close()并且没有重启Android,则通常会发生自动连接.有时它可能需要很长时间,特别是在5.0版之后.然而,它是不可靠的并且由于非常低的扫描周期而且在扫描周期实际检测到广告之前设备退出广告可能是不可靠的.我不确定,因为没有办法像广告那样检测扫描操作!扫描也可能在一定时间后停止,但没有相关文档.
因此,我认为我需要做的就是以某种方式设置使用的是Android,以更高的占空比后台扫描速度(仅在5.0可能高达)时自动连接已定,但我不知道如何做到这一点.我不想开始自己的扫描,但不知何故设置了Android用于重新连接的后台扫描速率.有谁知道如何做到这一点?有谁真的知道autoconnect和gatt.close()是如何工作的?
也许自动连接并不意味着重新连接,如上所述?
在 Android 11 SDK 30 中,在每个活动开始时我都会得到如下堆栈跟踪:
2020-12-30 10:08:00.175 1417-1436/? D/EventSequenceValidator: IntentStarted during UNKNOWN. Intent { cmp=com.lampreynetworks.ahd.health.at.home/.DebugLogActivity }
java.lang.Throwable: EventSequenceValidator#getStackTrace
at com.google.android.startop.iorap.EventSequenceValidator.logWarningWithStackTrace(EventSequenceValidator.java:260)
at com.google.android.startop.iorap.EventSequenceValidator.onIntentStarted(EventSequenceValidator.java:106)
at com.android.server.wm.LaunchObserverRegistryImpl.handleOnIntentStarted(LaunchObserverRegistryImpl.java:139)
at com.android.server.wm.LaunchObserverRegistryImpl.lambda$veRn_GhgLZLlOHOJ0ZYT6KcfYqo(Unknown Source:0)
at com.android.server.wm.-$$Lambda$LaunchObserverRegistryImpl$veRn_GhgLZLlOHOJ0ZYT6KcfYqo.accept(Unknown Source:10)
at com.android.internal.util.function.pooled.PooledLambdaImpl.doInvoke(PooledLambdaImpl.java:292)
at com.android.internal.util.function.pooled.PooledLambdaImpl.invoke(PooledLambdaImpl.java:201)
at com.android.internal.util.function.pooled.OmniFunction.run(OmniFunction.java:97)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.os.HandlerThread.run(HandlerThread.java:67)
at com.android.server.ServiceThread.run(ServiceThread.java:44)
Run Code Online (Sandbox Code Playgroud)
所有活动都有效,如果我不查看 Logcat,我永远不会知道。然而,我不明白它,它一定是某种问题的迹象,(最终)会回来咬我。有人了解这种行为并知道如何解决它吗?
从 4.0.3 开始,我就已经在许多版本中使用过这段代码,但直到现在才见过它。请注意,每个活动都会发生这种情况。
我不明白 Android Studio 中的此错误消息。查看源代码,这个错误是由小图标为空引起的。但我设置了图标(大和小)并且通知与我的图标一起出现。我什至使用 Asset Studio 专门为通知创建了这个图标。
关于这个主题还有很多其他帖子,但它们似乎都与那些试图以某种方式隐藏通知的人有关。我想要它,这样我的服务就不会被 Android 杀死!
这是完整的错误
Attempted to start a foreground service (ComponentInfo{com.lni.pchademophg/com.lni.pchademophg.BaseManager}) with a broken notification (no icon: Notification(pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE secFlags=0x0 secPriority=0))
Run Code Online (Sandbox Code Playgroud)
为什么会出现错误?(我想我不应该抱怨,一切都按照我需要的方式工作......至少看起来如此,但错误令人不安,我想理解它。)此错误发生在 6.0.1 设备上(还没试过10)
这是我的代码,位于服务的“onsStartCommand()”方法中:
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
createNotificationChannel();
Notification.Builder builder = new Notification.Builder(context, mChannel.getId())
.setContentTitle(getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_stat_name)
.setContentText("Pcha Personal Health Gateway")
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
R.drawable.ic_stat_name))
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(NOTIFICATION_ID, notification);
}
else
{ …Run Code Online (Sandbox Code Playgroud) 这也许是一个愚蠢的问题,但是我在谷歌上搜索了“ Service Moniker”的定义。关于WCF,我到处都看到它。首先,我认为它可能是某种工具,然后是某些对象,现在我开始相信它只是描述WCF通道的一组参数。
在过去的两周中,我有一个简单的WCF服务(带有回调),并且客户端使用命名管道通信通道进行工作,而且我所知道的我都在“使用”“服务绰号”。
有人可以告诉我什么是服务绰号吗?这可能有助于我尝试解决下一个问题,即从UNMANAGED C ++客户端访问WCF服务。在与C ++ / WCF问题有关的文章中,我经常看到该术语。
非常感谢!!
我试图从非托管代码调用托管方法.但是,托管代码要求我使用'(__ clrcall)调用约定,而我的非托管C++代码拒绝让我使用__clrcall调用约定而不使用/ clr选项.我不相信我想这样做,因为非托管项目不是我可以改为托管的.
正如我在CodeGuru和MSDN上看到的那样,我已经完成了在托管端构建所有这些委托和函数指针编组,但是除非我使用不能成为ref类成员的__stdcall约定调用静态函数,否则此错误仍然会弹出.该方法需要是ref类的实例.
我能解决这个问题的唯一方法是从程序集中的非托管代码执行我的方法调用,在调用之后跳过ESP寄存器(添加4)的弹出(调用在参数中有一个参数,因此'4 ").这让我有效地做了__clrcall.那个选项很难找到.
有人对如何解决这个问题有任何想法?肯定是可能的.我遗漏了一些简单而重要的信息.
这是我的委托定义(所有这些都属于单个ref类ManagedSensor):
delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes);
Run Code Online (Sandbox Code Playgroud)
这是我想要调用的实例方法
void LocalOxpMeasurementCallback(std::vector<OBX> *obxes);
Run Code Online (Sandbox Code Playgroud)
这里是ref类函数对ref class构造函数中完成的非托管函数的编组:
// Now to make the 'delegate' unmanaged function pointer usable for unmanged code
// The argument is the unmanaged callback.
OxpOnReceivedMeasurement ^oxpMeasurementCallbackFP = gcnew OxpOnReceivedMeasurement(this, &ManagedSensor::LocalOxpMeasurementCallback);
// Lock it so the garbage collector doesnt get rid of it or move it
gch = GCHandle::Alloc(oxpMeasurementCallbackFP);
// Pass the marshaled function pointer to the unmanaged code
IntPtr ip = Marshal::GetFunctionPointerForDelegate(oxpMeasurementCallbackFP);
// fnOnReceiveMeasurement is defined …Run Code Online (Sandbox Code Playgroud)