重大位置更改不会在设备上触发

土豆

我正在使用重要的位置更改监控。当我在模拟器中运行代码并选中Freeway选项时,我会得到定期的位置更新。我获取这些更新并将其保存在NSUserDefaults中,然后每隔10s更新一次tableview,这样我就可以查看是否有任何更新。如果我在真实设备上运行该应用程序,则会得到零更新。我把手机放在口袋里,走了80多公里,去了两个城市。零更新。不知道我是否搞砸了。我正在附上代码。该代码是复制粘贴,随时可以测试。只要确保在情节提要中使用TableViewController并将单元格ID设置为ID即可。我想念什么?我正在iPhone 5上进行测试。

info.plist:

在此处输入图片说明

编辑:在苹果文档中找到了这个。我的locationManager创作方式是否应与众不同?

当由于位置更新而重新启动应用程序时,启动选项字典传递给您的应用程序:willFinishLaunchingWithOptions:或application:didFinishLaunchingWithOptions:方法包含UIApplicationLaunchOptionsLocationKey键。该键的存在表明新的位置数据正在等待传递到您的应用程序。要获取该数据,必须创建一个新的CLLocationManager对象并重新启动在终止应用程序之前运行的位置服务。重新启动这些服务时,位置管理器会将所有未决的位置更新传递给其委托。

编辑2:

基于此,应该至少每15分钟更新一次位置。我的代码中的错误已确认。

如果GPS级别的精度对您的应用不是很关键,并且您不需要连续跟踪,则可以使用重大变化的位置服务。正确使用重要更改位置服务至关重要,因为即使没有发生位置更改,它也至少每15分钟唤醒一次系统和您的应用,并且该服务会连续运行直到您停止它为止。

edit3:将此代码添加到AppDelegate中,didFinishLaunchingWithOptions:以查看应用是否被唤醒。它不会被唤醒-我在表视图中看不到200200条目。可疑的事情正在发生。

 if let options = launchOptions {
            print("options")
            if (launchOptions![UIApplicationLaunchOptionsLocationKey] != nil){
                locationManager.startUpdatingLocation()
                self.lat.append(Double(200))
                self.lon.append(Double(200))
                self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle))
                NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
                NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
                NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")
            }

代码:// AppDelegate:

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {

    var lat:[CLLocationDegrees]!
    var lon:[CLLocationDegrees]!
    var times:[String]!
    var distances: [String]!

    var window: UIWindow?
    var locationManager: CLLocationManager!


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        locationManager=CLLocationManager()
        locationManager.delegate=self
        locationManager.requestAlwaysAuthorization()

        let isFirstLaunch = NSUserDefaults.standardUserDefaults().objectForKey("lat")
        if isFirstLaunch == nil{
            lat = [CLLocationDegrees]()
            lon = [CLLocationDegrees]()
            times = [String]()
            NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
            NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
            NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")
        }else{
            lat = NSUserDefaults.standardUserDefaults().arrayForKey("lat") as! [CLLocationDegrees]
            lon = NSUserDefaults.standardUserDefaults().arrayForKey("lon") as! [CLLocationDegrees]
            times = NSUserDefaults.standardUserDefaults().objectForKey("time") as! [String]
//            distances = NSUserDefaults.standardUserDefaults().objectForKey("distance") as! [String]

        }  
        return true
    }



    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("location updated")

        self.lat.append(locations[0].coordinate.latitude)
        self.lon.append(locations[0].coordinate.longitude)
        self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle))

        NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
        NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
        NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")

        print("Location: \(locations[0].coordinate.latitude)   \(locations[0].coordinate.longitude)")
    }

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        print("did change AS")
        switch status {
        case .AuthorizedWhenInUse:
            locationManager.startMonitoringSignificantLocationChanges()
        case .AuthorizedAlways:
            print("to always")
            locationManager.startMonitoringSignificantLocationChanges()
            if lat.count==0{
                self.lat.append((locationManager.location?.coordinate.latitude)!)
                self.lon.append((locationManager.location?.coordinate.longitude)!)

                self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle))

                NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
                NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
                NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")


            }

//            locationManager.startUpdatingLocation()
            break
        default:
            locationManager.stopMonitoringSignificantLocationChanges()
            break
        }
    }
}

//视图控制器

import UIKit

class TableViewController: UITableViewController {

    let appDel = UIApplication.sharedApplication().delegate as! AppDelegate

    override func viewDidLoad() {
        super.viewDidLoad()

        NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: "updateTableView", userInfo: nil, repeats: true)
    }



    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return appDel.lon.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("ID", forIndexPath: indexPath)
        cell.textLabel?.text = "\(appDel.lat[indexPath.row])   \(appDel.lon[indexPath.row])    \(appDel.times[indexPath.row])"
        cell.textLabel?.font = UIFont.systemFontOfSize(9)


        return cell
    }

    func updateTableView(){
    self.tableView.reloadData()
    }
}
位字节狗

该代码有几个问题:

  1. 当iOS启动应用程序时,位置更新不会启动。
  2. 不要求后台位置更新。
  3. 该代码依赖于授权状态的更改来开始位置更新
  4. didChangeAuthorizationStatus方法中缺少丢失的break语句

以下是相关文件:

第一个文档说,iOS启动应用程序时必须完全配置位置管理器对象,以便可以将位置事件传递给应用程序。

重新启动后,您仍然必须配置位置管理器对象并调用此方法[startMonitoringSignificantLocationChanges]以继续接收位置事件。

我通常这样做是为了确保位置管理器完全启动,而不管它是从图标启动还是通过iOS启动(对不起,我使用ObjectiveC)。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

  NSLog(@"app launching");
  bgTask = UIBackgroundTaskInvalid;

  locationMgr = [[CLLocationManager alloc] init];
  [locationMgr setDelegate:self];
  if([locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
    [locationMgr setAllowsBackgroundLocationUpdates:YES];
  CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];

  if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) {
    NSLog(@"relaunching because of significant location change - restarting SLC");
    [locationMgr startMonitoringSignificantLocationChanges];
  }
  else
  {
    if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
        NSLog(@"launching with authorization to always use location - starting SLC");
        [locationMgr startMonitoringSignificantLocationChanges];
    }
    else
    {
        NSLog(@"launching with no authorization to always use location - requesting authorization");
        if([locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)])
            [locationMgr requestAlwaysAuthorization];
    }
  }

  return YES;
}

请注意对setAllowsBackgroundLocationUpdates的调用这是iOS9中的新功能,如果您想在后台接收位置更新,则必须在每次启动应用程序时进行。(这就像“我不是在开玩笑,我知道我在后台模式下要它们,但我确实想要它们”)。

希望在挂起时接收位置更新的应用程序必须在其应用程序的Info.plist文件中包含UIBackgroundModes键(具有位置值),并将此属性的值设置为YES。

最后,您不能依靠didChangeAuthorizationStatus被调用。如果您具有授权kCLAuthorizationStatusAuthorizedAlways,则调用[locationMgr requestAlwaysAuthorization]不会导致授权状态发生更改,因此不会调用ChangeAuthorizationStatus

如果在调用requestWhenInUseAuthorization或requestAlwaysAuthorization方法时已经知道授权状态,则位置管理器不会向此方法报告当前授权状态。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Bootstrap Select不会在移动设备上触发更改事件

OnLongClickListener不会在ViewPager上触发

Android上的Cordova File API:window.requestFileSystem永远不会在设备上触发

CoreLocation“重大位置更改”与“区域监视”

Angularfire2身份验证订阅不会在移动设备上触发

Javascript 单击 Svg/object 元素不会在移动设备上触发

Xcode / iOS模拟器:手动触发重大位置更改

为什么更改输入不会在更改事件上触发?

jQuery-不会在下拉菜单上触发更改功能

引导程序ICheck-Helper不会在更改的事件上触发

为什么iPhone的Safari不会在输入type = file上触发更改的事件?

Angular onChange不会在数据更改时触发

$ scope。$ watch不会在每次更改时触发

componentDidMount 不会在道具更改时触发

共享的偏好值不会在触发时更改

React useEffect不会在路线更改时触发

某些设备不会在Google Play上显示APK

翻转卡不会在移动设备上翻转

网站不会在移动设备上向右或向左滚动

Wordpress 不会在移动设备上显示部分 css

react-native android 不会在设备上运行

Pointermove不会在IE上触发触摸

不会在TextInputEditText android上触发onClick事件

OnPageIndexChanging事件永远不会在GridView上触发

音频事件不会在播放事件上触发jquery

WebRTC永远不会在IceCandidate上触发

Ionic:Touchstart 和 Touchend 不会在 Android 上触发

fcitx不会在超空间上触发IME

不显眼的验证不会在单选按钮上触发