在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Delphi IOS 后台运行 同样的程序,编译成android,锁屏后继续运行正常,蓝牙通讯正常,但在IOS下锁屏后程序的蓝牙就中断通讯了? IOS的机制就是这样,锁屏就关闭了。 音乐播放器是怎么做到的?锁屏还能继续工作? 查看iPhone手机,关闭后台刷新,依然可以播放音乐。 另外还有系统设置里的后台刷新打开还是关闭状态。
写个单独的循环累加,显示结果值的程序,加上audio、 delphi的例子MusicPlayer,加上audio选项,锁屏播放正常。不加audio选项,锁屏即停止!如果不加audio,加上bluetooth-central锁屏后报错了。让music支持后台运行正常,主界面上加载一个循环累计变量,锁屏后也是停止运行了, 但是进度条tbProgress是解锁后恢复正常,显示准确的进度,但是我的iii循环累计变量停止接着上次值开始累计了。 只能是后台(线程)运行了。
线程也不行,调试跟踪music,锁屏后,线程所有函数都不执行了。停止了。回复后才读取最新的进度,信息。但是
UIBackgroundModes Delphi>Project Options>Version>UIBackgroundModes http://docwiki.embarcadero.com/RADStudio/Seattle/en/Version_Info http://community.embarcadero.com/blogs/blog-menu/entry/background-modes-in-ios 蓝牙Background http://docwiki.embarcadero.com/RADStudio/Seattle/en/Using_Bluetooth_Low_Energy
Information Property List Key Referencehttps://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/plist/info/UIBackgroundModes Background Executionhttps://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
music background run http://community.embarcadero.com/blogs/blog-menu/blogger/listings/miguel-oliver-embarcadero-com Communicating with a Bluetooth AccessoryApps that work with Bluetooth peripherals can ask to be woken up if the peripheral delivers an update when the app is suspended. This support is important for Bluetooth-LE accessories that deliver data at regular intervals, such as a Bluetooth heart rate belt. You enable support for using bluetooth accessories from the Background modes section of the Capabilities tab in your Xcode project. (You can also enable this support by including the In iOS 6, an app can also operate in peripheral mode with Bluetooth accessories. To act as a Bluetooth accessory, you must enable support for that mode from the Background modes section of the Capabilities tab in your Xcode project. (You can also enable this support by including the Any app that supports the background processing of Bluetooth data must be session-based and follow a few basic guidelines:
CBCentralManagerDelegate
自己要写代码 https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html delphi CBCentralManager CBCentralManagerDelegate
Core Bluetooth Programming Guidehttps://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html#//apple_ref/doc/uid/TP40013257-CH7-SW1
https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html fetch模式
函数定义: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:performFetchWithCompletionHandler:
delphi Fetch example http://stackoverflow.com/questions/32348081/delphi-firemonkey-ios-background-processing http://qc.embarcadero.com/wc/qcmain.aspx?d=128968 unit uBackgroundiOS; interface uses fmx.platform.iOS,iOSapi.CocoaTypes, Macapi.ObjCRuntime, Macapi.ObjectiveC, iOSapi.UIKit; const UIBackgroundFetchResultNewData:NSUInteger = 0; UIBackgroundFetchResultNoData:NSUInteger = 1; UIBackgroundFetchResultFailed:NSUInteger = 2; UIApplicationBackgroundFetchIntervalMinimum:NSTimeInterval = 0; UIApplicationBackgroundFetchIntervalNever:NSTimeInterval = -1; type // copied from fmx.platform.iOS as it's on private declaration id = Pointer; SEL = Pointer; PUIApplication = Pointer; IMP = function( self : id; cmd : SEL; Param1 : NSUInteger ) : id; cdecl; function imp_implementationWithBlock( block :id ) : IMP; cdecl; external libobjc name _PU + 'imp_implementationWithBlock'; function imp_removeBlock( anImp : IMP ) : integer; cdecl; external libobjc name _PU + 'imp_removeBlock'; procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id ); procedure initializeBackgroundFetch; function objc_msgSend(theReceiver: Pointer; theSelector: Pointer): Pointer; cdecl; varargs; external libobjc name _PU + 'objc_msgSend'; //to test if procedure is called in background var fecth_string_test: string; implementation procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id ); var ahandlerimp: IMP; begin //Code to perform fetch HERE!!!! fecth_string_test := 'entered background code!!'; ahandlerimp := imp_implementationWithBlock( handler ); //Create c function for block ahandlerimp(self,_cmd, UIBackgroundFetchResultNewData); //Call c function, _cmd is ignored imp_removeBlock(ahandlerimp); //Remove the c function created two lines up end; procedure initializeBackgroundFetch; Var UIApp: UIApplication; begin UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication); objc_msgSend((UIApp as ILocalObject).GetObjectId, sel_getUid('setMinimumBackgroundFetchInterval:'), UIApplicationBackgroundFetchIntervalMinimum); class_addMethod(objc_getClass('DelphiAppDelegate') , sel_getUid('application:performFetchWithCompletionHandler:'), @performFetchWithCompletionHandler, 'v@:@?'); end; end. delphi10里 unit Macapi.Bluetooth; TCBCentralManager = class(TOCGenericImport<CBCentralManagerClass, CBCentralManager>) end; CBCentralManagerDelegate = interface(IObjectiveC) ['{1337817E-92DE-4FA9-8CF2-E00E89125A0F}'] procedure centralManagerDidUpdateState(central: CBCentralManager); cdecl; [MethodName('centralManager:willRestoreState:')] procedure centralManagerWillRestoreState(central: CBCentralManager; dict: NSDictionary); cdecl; [MethodName('centralManager:didRetrievePeripherals:')] procedure centralManagerDidRetrievePeripherals(central: CBCentralManager; peripherals: NSArray); cdecl; [MethodName('centralManager:didRetrieveConnectedPeripherals:')] procedure centralManagerDidRetrieveConnectedPeripherals(central: CBCentralManager; peripherals: NSArray); cdecl; [MethodName('centralManager:didDiscoverPeripheral:advertisementData:RSSI:')] procedure centralManagerDidDiscoverPeripheral(central: CBCentralManager; peripheral: CBPeripheral; advertisementData: NSDictionary; RSSI: NSNumber); cdecl; [MethodName('centralManager:didConnectPeripheral:')] procedure centralManagerDidConnectPeripheral(central: CBCentralManager; peripheral: CBPeripheral); cdecl; [MethodName('centralManager:didFailToConnectPeripheral:error:')] procedure centralManagerDidFailToConnectPeripheral(central: CBCentralManager; peripheral: CBPeripheral; error: NSError); cdecl; [MethodName('centralManager:didDisconnectPeripheral:error:')] procedure centralManagerdidDisconnectPeripheral(central: CBCentralManager; peripheral: CBPeripheral; error: NSError); cdecl; end; unit System.Mac.Bluetooth; TInternalBluetoothLEManager = class(TOCLocal, CBCentralManagerDelegate) private FCentralManager: CBCentralManager; FOnDeviceDiscovered: TDeviceDiscoveredEvent; FWaitingToDiscover: Boolean; FIsDiscovering: Boolean; FTimer: TInternalTimer; FConnected: Boolean; FOnDeviceDiscoveryTimeout: TNotifyEvent; FLastError: Integer; FFilterUUIDList: NSMutableArray; FScanOptions: NSMutableDictionary; FOnDeviceConnect: TDeviceConnectionChangeEvent; FOnDeviceDisconnect: TDeviceConnectionChangeEvent; procedure CreateTimer(Interval: Integer); public constructor Create; destructor Destroy; override; procedure centralManagerDidUpdateState(central: CBCentralManager); cdecl; [MethodName('centralManager:willRestoreState:')] procedure centralManagerWillRestoreState(central: CBCentralManager; dict: NSDictionary); cdecl; [MethodName('centralManager:didRetrievePeripherals:')] procedure centralManagerDidRetrievePeripherals(central: CBCentralManager; peripherals: NSArray); cdecl; [MethodName('centralManager:didRetrieveConnectedPeripherals:')] procedure centralManagerDidRetrieveConnectedPeripherals(central: CBCentralManager; peripherals: NSArray); cdecl; [MethodName('centralManager:didDiscoverPeripheral:advertisementData:RSSI:')] procedure centralManagerDidDiscoverPeripheral(central: CBCentralManager; peripheral: CBPeripheral; advertisementData: NSDictionary; RSSI: NSNumber); cdecl; [MethodName('centralManager:didConnectPeripheral:')] procedure centralManagerDidConnectPeripheral(central: CBCentralManager; peripheral: CBPeripheral); cdecl; [MethodName('centralManager:didFailToConnectPeripheral:error:')] procedure centralManagerDidFailToConnectPeripheral(central: CBCentralManager; peripheral: CBPeripheral; error: NSError); cdecl; [MethodName('centralManager:didDisconnectPeripheral:error:')] procedure centralManagerdidDisconnectPeripheral(central: CBCentralManager; peripheral: CBPeripheral; error: NSError); cdecl; procedure StartDiscovery(Timeout: Cardinal; const FilterUUIDList: TBluetoothUUIDsList = nil); procedure StopDiscovery; function ConnectTo(const APeripheral: CBPeripheral): Boolean; function CancelConnectionTo(const APeripheral: CBPeripheral): Boolean; procedure OnDiscoveryTimeout(Sender: TObject); property OnDeviceDiscovered: TDeviceDiscoveredEvent read FOnDeviceDiscovered write FOnDeviceDiscovered; property OnDeviceDiscoveryTimeout: TNotifyEvent read FOnDeviceDiscoveryTimeout write FOnDeviceDiscoveryTimeout; property OnDeviceConnect: TDeviceConnectionChangeEvent read FOnDeviceConnect write FOnDeviceConnect; property OnDeviceDisconnect: TDeviceConnectionChangeEvent read FOnDeviceDisconnect write FOnDeviceDisconnect; end; 可见也用到了TInternalBluetoothLEManager和CBCentralManagerDelegate unit System.Bluetooth; {$IFDEF IOS}
http://stackoverflow.com/questions/19916513/bluetooth-central-region-monitoring-in-background-and-or-locked-no-display
2016.1.2测试,锁屏后蓝牙保持连接,为断开,就是不发送接受数据了。是不是timer停止了,给外设发送请求数据的命令移动到蓝牙接受事件里,处理完成后发送请求数据命令,而不是在timer里不停的发送,试试这种方式!!! http://blog.csdn.net/zhuzhihai1988/article/details/30081991 Required background modes App shares data using CoreBluetooth App communicates using CoreBluetooth
<key>Required background modes</key>
不选bluetooth central 锁屏后蓝牙未断开连接,解锁后继续通讯,以前的曲线还在,只是锁屏后timer事件不再触发,所以停止运行了。 经过测试验证TApplicationEvent.EnteredBackground事件里, FCurrentDevice.IsConnected连接着呢。
选中bluetooth central 当蓝牙连接成功后,监测数据中,锁屏后,蓝牙断开连接了,android设备可以连接证明蓝牙确实断开了。解锁后弹出连接信息。相当于程序重新运行了,以前的曲线图也没有了。 蓝牙未连接成功,锁屏后解锁没有区别,不会自动连接。
经过测试验证TApplicationEvent.EnteredBackground事件里, FCurrentDevice.IsConnected连接着呢。 再测试,选中bluetooth central,在EnteredBackground 事件蓝牙保持了吗;不选中,进入EnteredBackground 是否断开了?如果这样就解决问题啦,结果是一样的。 FCurrentDevice.IsConnected就是true。 蓝牙连接,未监测数据,unlock screen it not restore connection.
通过TApplicationEvent事件,EnteredBackground停止计时器,WillBecomeForeground开始计时器,可以连续测试了。唯一的就是处理锁屏后数据接收的问题。以前的问题是从后台切换到前台重新连接蓝牙,现在这个问题好了,平滑切换!!不论选择bluetooth central与否,都好了。
如果在进入EnteredBackground事件里,不停止timer,不断的执行,就报错了,所以切换回来的时候会重新运行,触发oncreate和onshow事件,导致调用research方法发现设备。!!
connection,sending data,lock screen. debug mode application,see error below. osx\Macapi.ObjectiveC.pas class procedure TOCGenericImport<C,T>.Init(O: T; P: Pointer); {$IFDEF DEBUGUTILS} 两种可能,一种是代码写的有问题,一种是delphi的bug
DidEnterBackground 测试一下System.Mac.Bluetooth屏蔽此单元,delphi用了此单元的什么组件,屏蔽后BLE控件工程依然可以编译成功!没没用到啊。 TBluetoothLEManager TBluetoothLE = class(TComponent) class constructor TBluetoothLEManager.Create; TPlatformBluetoothLEManager就是System.Mac.Bluetooth里的了。最终还是用到了。 http://community.embarcadero.com/index.php/blogs/entry/spelunking-delphi-rtl-new-features-since-xe2 http://community.embarcadero.com/index.php/blogs/entry/bluetooth-le-support-in-rad-studio-xe7
UIBackgroundModes 就是XCode里的 “Required background modes”
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论