ios 蓝牙后台

2018-11-19 11:21:26 guoke1203 阅读数 689

情景:iOS 前台可以扫描蓝牙,切到后台扫描失效

1.允许蓝牙后台常驻,appDelegate向系统申请后台时间

2.如果iOS 经过1步骤,能扫描到其他外设,目标外设扫描不到,基本可以确定是目标外设的广播包有问题,

可以和嵌入式工程师沟通,让广播服务放到广播包里面,别放扫描包里    

原因:

1. iOS 在前台时,可以扫描广播包和扫描包里面的内容

2.iOS 在后台时,只能扫描到广播包里面的内容

 

2019-06-17 12:00:41 qq_32117417 阅读数 907

相信大家在开发蓝牙应用的过程中会遇到需要连接蓝牙获取实时数据,然而我们不可能让应用一直保持在前台运行,所以需要设置权限让APP进入后台还继续运行蓝牙模块。

1、首先我们会想到xcode的设置,如下图

2、然而这样设置了,APP进入后台后,如果蓝牙连接着就会一直通讯,如果没有通讯,系统也会将进程挂起,所以需要进行心跳包,保证数据通讯不断。

但假如进入后台后蓝牙断开了,APP就被挂起来了,所以需要申请一段时间让蓝牙有重新连接的机会。

我们可以申请短暂的时间(300秒左右),让定时器不停跑搜索蓝牙的方法。为了保证app不会被系统回收,超过时间就把定时器关闭,APP将进入悬挂状态,直至下次重新进入app,之前收集的数据则可以操作保存。

    var backTask :UIBackgroundTaskIdentifier?
    var backTimer: Timer?
    var backCounter: Int = 0
    var isenterBackground = false
    
    //APP进入后台
    func applicationDidEnterBackground(_ application: UIApplication) {
       backTask = UIApplication.shared.beginBackgroundTask(expirationHandler: nil)
        self.isenterBackground = true
        if connectedPeripheral?.state == .disconnected && isOnForBLE{
            self.scanTimerStart()
        }
    }
    //普通申请后台时间
    func scanTimerStart(){
        if backTimer != nil {
            backTimer?.invalidate()
        }
        backCounter = 0
        backTimer = Timer(timeInterval: 2, target: self, selector: #selector(backgroundScan), userInfo: nil, repeats: true)
        RunLoop.current.add(self.backTimer!, forMode: RunLoop.Mode.default)
    }


    //蓝牙扫描
    @objc func backgroundScan(){
        discoveredPeripherals.removeAll(keepingCapacity: false)
        AppCache.shared.deviceArray.removeAll()
        LWBluetoothManager.sharedInstance.startScanPeripherals()
        if connectedPeripheral != nil && connectedPeripheral?.state != .connected && AppCache.shared.ishandleDisconnect == false{
            LWBluetoothManager.sharedInstance.connectPeripheral(connectedPeripheral!, valuableUUID: [kServiceUUID: [kCCharacteristicUUID]])
        }
        backCounter += 2
        
        if #available(iOS 10.0, *) {
            
            if backCounter >= 298 {
                backCounter = 0
                backTimer?.invalidate()
            }
        }else{
            if backCounter >= 180 {
                backCounter = 0
                backTimer?.invalidate()
            }
            if backTask != nil {
                UIApplication.shared.endBackgroundTask(backTask!)
            }
        }
    }

3.关于定时器分298秒和180秒,是针对iOS版本不同设定的,由于公司有部iOS9的iPad,测试中发现蓝牙断开时间超过了3分钟,APP就被系统回收了,所以设置成180秒。

以下是蓝牙断开时启动定时器:

4.上面所述的情况只是适合公司的项目开发,如果发现有什么不妥,请留言讨论。

 

 

 

 

2015-06-11 10:40:54 IOS_dashen 阅读数 662

打开x-code,展开项目的upporting Files文件。在xxx-info.plist文件中, 新建一行 Required background modes , 点击Value分区最右边的三角展开按钮,加入下面两项。
App shares data using CoreBluetooth 和 App communicates using CoreBluetooth
如图所示:


加入这个项后, 你会发现, 当应用进入后台后, 蓝牙还是保持连接的。


2017-03-05 21:29:59 BianHuanShiZhe 阅读数 1012
我们蓝牙开发为了能使app在后台运行时依旧保持与外设的连接,就需要在工程目录下的 info.plist 文件中,
iOS9及其以前的做法:新建一行 Required background modes , 加入下面两项。
App shares data using CoreBluetooth 和 App communicates using CoreBluetooth
iOS10的做法:直接添加 Privacy - Bluetooth Peripheral Usage Description 是否许允此App使用蓝牙?
2014-06-11 17:48:45 zhuzhihai1988 阅读数 19953

轻松一刻  

http://t.cn/RhfSa04


最近在做一个蓝牙相关的项目, 需要在应用进入后台, 或者手机属于锁屏状态的情况下, 仍然保持蓝牙连接, 并且能正常接收数据。

本来以后会很麻烦, 但是学习了下..发现就2步而已。简单的不能再简单了。


好了。下面是具体实现办法。


1.在xxx-info.plist文件中, 新建一行  Required background modes , 加入下面两项。

App shares data using CoreBluetooth 和 App communicates using CoreBluetooth

如图所示:



加入这个项后, 你会发现, 当应用进入后台后, 蓝牙还是保持连接的。

但是, 进入后台后, 虽然应用还挂着, 能够正常接收数据。但是,  来数据了, 如果需要我们实时响应, 那就要用到推送了。

也就是, 当数据来的时候, 弹出一个提示框, 提示用户来数据了。


2. 设置本地推送

这里的方法写在AppDelegate.m中。  receiveData对应你接收到数据的响应函数。

  1. -(void)receiveData:(NSData*)data  
  2. {  
  3.     NSLog(@"收到数据了");  
  4.       
  5.     //收到数据, 设置推送  
  6.     UILocalNotification *noti = [[UILocalNotification alloc] init];  
  7.     if (noti)  
  8.     {  
  9.         //设置时区  
  10.         noti.timeZone = [NSTimeZone defaultTimeZone];  
  11.         //设置重复间隔  
  12.         noti.repeatInterval = NSWeekCalendarUnit;  
  13.         //推送声音  
  14.         noti.soundName = UILocalNotificationDefaultSoundName;  
  15.         //内容  
  16.         noti.alertBody = @"接收到数据了";  
  17.         noti.alertAction = @"打开";  
  18.         //显示在icon上的红色圈中的数子  
  19.         noti.applicationIconBadgeNumber = 1;  
  20.         //设置userinfo 方便在之后需要撤销的时候使用  
  21.         NSDictionary *infoDic = [NSDictionary dictionaryWithObject:@"name" forKey:@"key"];  
  22.         noti.userInfo = infoDic;  
  23.         //添加推送到uiapplication  
  24.         UIApplication *app = [UIApplication sharedApplication];  
  25.         [app scheduleLocalNotification:noti];  
  26.     }  
  27. }  

  1. #pragma mark - 接收到推送  
  2. - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification*)notification  
  3. {  
  4.     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"来电提示"  
  5.                                                     message:notification.alertBody  
  6.                                                    delegate:nil  
  7.                                           cancelButtonTitle:@"接听"  
  8.                                           otherButtonTitles:@"挂断",nil];  
  9.     [alert show];  
  10.     //这里,你就可以通过notification的useinfo,干一些你想做的事情了  
  11.     application.applicationIconBadgeNumber -= 1;  
  12. }