我想尽可能在后台使用BLE宣传UUID。如果一个用例有帮助,想象我的应用程序是一个无钥匙进入应用程序,其中手机是一个外围设备,锁是一个中心,因此必须始终在BLE打开时做广告。我的应用程序包含响应BroadcastReceiver
事件的ACTION_STATE_CHANGED
,并在当前状态为STATE_ON
时开始做广告。我的问题是坚持不懈。
如果我在没有打开应用程序的情况下打开蓝牙,广告就会开始,但会在一段时间后停止。如果我在广告正在运行的任何时候打开应用程序,然后强行关闭它,广告就会停止,引用:
04-16 15:03:11.815 19411-19424/? D/BtGatt.GattService﹕ Binder is dead - unregistering client (5)!
04-16 15:03:11.815 19411-19425/? D/BtGatt.GattService﹕ Binder is dead - unregistering server (6)!
04-16 15:03:11.815 19411-19425/? D/BtGatt.GattService﹕ unregisterServer() - serverIf=6
04-16 15:03:11.816 19411-19425/? D/BtGatt.GattService﹕ deleteServices() - serverIf=6
04-16 15:03:11.816 19411-19425/? D/BtGatt.btif﹕ btif_gatts_delete_service
04-16 15:03:11.816 19411-19432/? D/BtGatt.btif﹕ btgatts_handle_event: Event 2010
04-16 15:03:11.817 19411-19446/? E/bt-att﹕ Active Service Found
04-16 15:03:11.817 19411-19432/? D/BtGatt.btif﹕ btapp_gatts_handle_cback: Event 11
04-16 15:03:11.817 19411-19432/? D/BtGatt.GattService﹕ onServiceDeleted() srvcHandle=40, status=0
04-16 15:03:11.817 19411-19425/? D/BtGatt.btif﹕ btif_gatts_unregister_app
04-16 15:03:11.817 19411-19432/? D/BtGatt.btif﹕ btgatts_handle_event: Event 2001
04-16 15:03:11.820 19411-19432/? D/BtGatt.btif﹕ btapp_gatts_handle_cback: Event 6
04-16 15:03:11.821 19411-19444/? D/BtGatt.AdvertiseManager﹕ message : 1
04-16 15:03:11.821 19411-19444/? D/BtGatt.AdvertiseManager﹕ stop advertise for client 5
04-16 15:03:11.822 19411-19444/? D/BtGatt.AdvertiseManager﹕ app died - unregistering client : 5
04-16 15:03:11.822 19411-19444/? D/BtGatt.GattService﹕ unregisterClient() - clientIf=5
04-16 15:03:11.828 19411-19432/? D/BtGatt.GattService﹕ onAdvertiseInstanceDisabled() - clientIf=255, status=0
因此,似乎蓝牙管理器以调用应用程序组件的方式绑定。为了解决这个问题,我创建了一个由Service
启动的BroadcastReceiver
,具有以下特征:
stopSelf()
onStartCommand()
的多次通话。START_STICKY
onStartCommand()
因此,如果收到服务,它将清除onDestroy()
中的蓝牙代码并稍后重新启动。如果应用程序被强制关闭,则会发生同样的事情。
有没有办法可以强制蓝牙运行而不关心它的内容?如果没有,这看起来像一个可行的结构?请戳一下洞。编辑:我担心的一件事就是让这个Service
对象永远存在并对电池寿命产生影响。应该只需要激活BLE命令,然后不消耗系统资源(除了蓝牙芯片的电源)
答案 0 :(得分:0)
这是Android应用程序的常见设计问题 使用永远在线服务的问题在于,如果资源不足,操作系统可以将其终止。如果发生这种情况,您的广播将有效停止 永远在线服务也可能对电池消耗造成损失,具体取决于其中发生的动作。
一个可能但不完美的解决方案是将您的服务作为前台服务 - 这将阻止操作系统停止它,但它会带来惩罚,您必须始终在状态栏中为您的应用设置一个图标,如果您正在使用Lollipop,也可以在锁定屏幕上。
我通过不同的设计解决了这个问题 - 我有一个服务,每X秒唤醒一次,查询它需要的东西(而不是等待广播),处理数据,注册自己在X秒内唤醒并停止。如果这个解决方案适合您,它肯定会解决死机服务问题,并可能解决电池耗尽问题。
在任何情况下,看起来您的服务应该与应用程序分离以保持持久性,也许在操作系统启动时启动它,就像WhatsApp那样