Aracılığıyla paylaş


İzlenecek yol - Xamarin.iOS'ta Arka Plan Konumu

Bu örnekte, geçerli konumumuzla ilgili bilgileri yazdıran bir iOS Konum uygulaması oluşturacağız: enlem, boylam ve diğer parametreler ekrana. Bu uygulama, uygulama Etkin veya Arka Planlı durumdayken konum güncelleştirmelerinin düzgün bir şekilde nasıl gerçekleştirileceğini gösterir.

Bu kılavuzda, bir uygulamayı arka planda gerekli bir uygulama olarak kaydetme, uygulama arka planlandığında kullanıcı arabirimi güncelleştirmelerini askıya alma ve ve WillEnterForegroundAppDelegate yöntemleriyle WillEnterBackground çalışma gibi bazı temel arka plan kavramları açıklanmaktadır.

Uygulama kurulumu

  1. İlk olarak yeni bir iOS > Uygulaması > Tek Görünüm Uygulaması (C#) oluşturun. Konum olarak adlandırın ve hem iPad hem de i Telefon'nin seçildiğinden emin olun.

  2. Konum uygulaması, iOS'ta arka plan için gerekli bir uygulama olarak niteler. Projenin Info.plist dosyasını düzenleyerek uygulamayı Konum uygulaması olarak kaydedin.

    Çözüm Gezgini altında Info.plist dosyasına çift tıklayarak açın ve listenin en altına kaydırın. Hem Arka Plan Modlarını Etkinleştir hem de Konum Güncelleştirmeler onay kutularına onay işareti yerleştirin.

    Mac için Visual Studio aşağıdakine benzer olacaktır:

    Hem Arka Plan Modlarını Etkinleştir hem de Konum Güncelleştirmeler onay kutularına göre onay işareti yerleştirin

    Visual Studio'da Info.plist dosyasının aşağıdaki anahtar/değer çifti eklenerek el ile güncelleştirilmesi gerekir:

    <key>UIBackgroundModes</key>
    <array>
      <string>location</string>
    </array>
    
  3. Uygulama artık kayıtlı olduğuna göre cihazdan konum verilerini alabilir. iOS'ta, CLLocationManager sınıf konum bilgilerine erişmek için kullanılır ve konum güncelleştirmeleri sağlayan olaylar oluşturabilir.

  4. Kodda, çeşitli ekranlar ve kodlar için konum güncelleştirmelerine abone olmak için tek bir yer sağlayan adlı LocationManager yeni bir sınıf oluşturun. LocationManager sınıfında adlı LocMgröğesinin CLLocationManager bir örneğini oluşturun:

    public class LocationManager
    {
        protected CLLocationManager locMgr;
    
        public LocationManager () {
            this.locMgr = new CLLocationManager();
            this.locMgr.PausesLocationUpdatesAutomatically = false;
    
            // iOS 8 has additional permissions requirements
            if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
                locMgr.RequestAlwaysAuthorization (); // works in background
                //locMgr.RequestWhenInUseAuthorization (); // only in foreground
            }
    
            if (UIDevice.CurrentDevice.CheckSystemVersion (9, 0)) {
                locMgr.AllowsBackgroundLocationUpdates = true;
            }
        }
    
        public CLLocationManager LocMgr {
            get { return this.locMgr; }
        }
    }
    

    Yukarıdaki kod CLLocationManager sınıfında bir dizi özellik ve izin ayarlar:

    • PausesLocationUpdatesAutomatically – Bu, sistemin konum güncelleştirmelerini duraklatma izni olup olmadığına bağlı olarak ayarlanabilen bir Boole değeridir. Bazı cihazlarda varsayılan olarak truedeğeri olur. Bu, cihazın yaklaşık 15 dakika sonra arka plan konumu güncelleştirmelerini almayı durdurmasına neden olabilir.
    • RequestAlwaysAuthorization - Uygulama kullanıcısına konumun arka planda erişilmesine izin verme seçeneği vermek için bu yöntemi geçirmelisiniz. RequestWhenInUseAuthorization ayrıca, kullanıcıya yalnızca uygulama ön planda olduğunda konuma erişim izni verme seçeneği vermek isterseniz de geçirilebilir.
    • AllowsBackgroundLocationUpdates – Bu, iOS 9'da kullanıma sunulan ve bir uygulamanın askıya alındığında konum güncelleştirmelerini almasına izin verecek şekilde ayarlanabilen bir Boole özelliğidir.

    Önemli

    iOS 8 (ve üzeri), kullanıcıyı yetkilendirme isteğinin bir parçası olarak göstermek için Info.plist dosyasında bir giriş gerektirir.

  5. Uygulamanın gerektirdiği NSLocationAlwaysUsageDescriptionizin türleri (, NSLocationWhenInUseUsageDescription, ve/veya NSLocationAlwaysAndWhenInUseUsageDescription ) için Info.plist anahtarlarını, konuma veri erişimi isteyen uyarıda kullanıcıya görüntülenecek bir dizeyle ekleyin.

  6. iOS 9, Info.plist kullanılırken AllowsBackgroundLocationUpdates değerini locationiçeren anahtarı UIBackgroundModes içermesini gerektirir. Bu kılavuzun 2. adımını tamamladıysanız, bu zaten Info.plist dosyanızda olmalıdır.

  7. sınıfının içinde LocationManager , aşağıdaki kodla adlı StartLocationUpdates bir yöntem oluşturun. Bu kod, konumundan konum güncelleştirmelerini almaya nasıl başlayacağını CLLocationManagergösterir:

    if (CLLocationManager.LocationServicesEnabled) {
        //set the desired accuracy, in meters
        LocMgr.DesiredAccuracy = 1;
        LocMgr.LocationsUpdated += (object sender, CLLocationsUpdatedEventArgs e) =>
        {
            // fire our custom Location Updated event
            LocationUpdated (this, new LocationUpdatedEventArgs (e.Locations [e.Locations.Length - 1]));
        };
        LocMgr.StartUpdatingLocation();
    }
    

    Bu yöntemde gerçekleşen birkaç önemli şey vardır. İlk olarak, uygulamanın cihazdaki konum verilerine erişimi olup olmadığını görmek için bir denetim gerçekleştiririz. Bunu, üzerinde arayarak LocationServicesEnabled doğrularız CLLocationManager. Kullanıcı konum bilgilerine uygulama erişimini reddettiyse bu yöntem false döndürür.

  8. Ardından konum yöneticisine ne sıklıkta güncelleştirileceklerini söyleyin. CLLocationManager , güncelleştirme sıklığı dahil olmak üzere konum verilerini filtrelemek ve yapılandırmak için birçok seçenek sağlar. Bu örnekte, konum ölçüme göre her değiştiğinde öğesini güncelleştirilecek şekilde ayarlayın DesiredAccuracy . Konum güncelleştirme sıklığını ve diğer tercihleri yapılandırma hakkında daha fazla bilgi için Apple belgelerindeki CLLocationManager Sınıf Başvurusu'na bakın.

  9. Son olarak örnekte çağrısında StartUpdatingLocation bulunur CLLocationManager . Bu, konum yöneticisine geçerli konumla ilgili ilk düzeltmeyi almalarını ve güncelleştirmeleri göndermeye başlamalarını söyler

Şu ana kadar konum yöneticisi oluşturuldu, almak istediğimiz veri türleriyle yapılandırıldı ve ilk konumu belirledi. Şimdi kodun konum verilerini kullanıcı arabirimine işlemesi gerekiyor. Bunu bağımsız değişken olarak alan özel bir CLLocation olayla yapabiliriz:

// event for the location changing
public event EventHandler<LocationUpdatedEventArgs>LocationUpdated = delegate { };

Bir sonraki adım, konumundan CLLocationManagerkonum güncelleştirmelerine abone olmak ve yeni konum verileri kullanılabilir olduğunda özel LocationUpdated olayı tetikleyerek konumu bağımsız değişken olarak geçirmektir. Bunu yapmak için yeni bir sınıf LocationUpdateEventArgs.cs oluşturun. Bu koda ana uygulama içinden erişilebilir ve olay tetiklendiğinde cihaz konumunu döndürür:

public class LocationUpdatedEventArgs : EventArgs
{
    CLLocation location;

    public LocationUpdatedEventArgs(CLLocation location)
    {
       this.location = location;
    }

    public CLLocation Location
    {
       get { return location; }
    }
}

Kullanıcı Arabirimi

  1. Konum bilgilerini görüntüleyecek ekranı oluşturmak için Xcode Arabirim Oluşturucusu'nu kullanın. Başlamak için Main.storyboard dosyasına çift tıklayın.

    Görsel taslakta, konum bilgileri için yer tutucu görevi görmesi için birkaç etiketi ekrana sürükleyin. Bu örnekte enlem, boylam, rakım, kurs ve hız etiketleri vardır.

    Daha fazla bilgi için bkz . Xcode ile kullanıcı arabirimleri tasarlama.

  2. Çözüm Bölmesi'nde dosyaya ViewController.cs çift tıklayın ve dosyayı düzenleyerek LocationManager'ın yeni bir örneğini oluşturun ve dosyayı arayın StartLocationUpdates. Kodu aşağıdaki gibi görünecek şekilde değiştirin:

    #region Computed Properties
    public static bool UserInterfaceIdiomIsPhone {
        get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; }
    }
    
    public static LocationManager Manager { get; set;}
    #endregion
    
    #region Constructors
    public ViewController (IntPtr handle) : base (handle)
    {
    // As soon as the app is done launching, begin generating location updates in the location manager
        Manager = new LocationManager();
        Manager.StartLocationUpdates();
    }
    
    #endregion
    

    Bu, uygulama başlatmada konum güncelleştirmelerini başlatır, ancak hiçbir veri görüntülenmez.

  3. Konum güncelleştirmeleri alındığına göre, ekranı konum bilgileriyle güncelleştirin. Aşağıdaki yöntem olayımızdan LocationUpdated konumu alır ve kullanıcı arabiriminde gösterir:

    #region Public Methods
    public void HandleLocationChanged (object sender, LocationUpdatedEventArgs e)
    {
        // Handle foreground updates
        CLLocation location = e.Location;
    
        LblAltitude.Text = location.Altitude + " meters";
        LblLongitude.Text = location.Coordinate.Longitude.ToString ();
        LblLatitude.Text = location.Coordinate.Latitude.ToString ();
        LblCourse.Text = location.Course.ToString ();
        LblSpeed.Text = location.Speed.ToString ();
    
        Console.WriteLine ("foreground updated");
    }
    #endregion
    

Yine de AppDelegate'imizdeki olaya abone LocationUpdated olmamız ve kullanıcı arabirimini güncelleştirmek için yeni yöntemi çağırmamız gerekir. Aramadan hemen sonra StartLocationUpdates içine ViewDidLoad, aşağıdaki kodu ekleyin:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    // It is better to handle this with notifications, so that the UI updates
    // resume when the application re-enters the foreground!
    Manager.LocationUpdated += HandleLocationChanged;

}

Şimdi, uygulama çalıştırıldığında şuna benzer olmalıdır:

Örnek bir uygulama çalıştırması

Etkin ve Arka Plan durumlarını işleme

  1. Uygulama, ön planda ve etkinken konum güncelleştirmeleri çıkışı yapıyor. Uygulama arka plana girdiğinde ne olduğunu göstermek için, uygulama ön plan ile arka plan arasında geçiş yaparken uygulamanın konsola yazması için uygulama durumunu izleyen yöntemleri geçersiz kılın AppDelegate :

    public override void DidEnterBackground (UIApplication application)
    {
        Console.WriteLine ("App entering background state.");
    }
    
    public override void WillEnterForeground (UIApplication application)
    {
        Console.WriteLine ("App will enter foreground");
    }
    

    Konum bilgilerinin arka planda hala kullanılabilir olduğunu doğrulamak için, güncelleştirilmiş konum verilerini sürekli olarak uygulama çıkışına yazdırmak için öğesine aşağıdaki kodu LocationManager ekleyin:

    public class LocationManager
    {
        public LocationManager ()
        {
        ...
        LocationUpdated += PrintLocation;
        }
        ...
    
        //This will keep going in the background and the foreground
        public void PrintLocation (object sender, LocationUpdatedEventArgs e) {
        CLLocation location = e.Location;
        Console.WriteLine ("Altitude: " + location.Altitude + " meters");
        Console.WriteLine ("Longitude: " + location.Coordinate.Longitude);
        Console.WriteLine ("Latitude: " + location.Coordinate.Latitude);
        Console.WriteLine ("Course: " + location.Course);
        Console.WriteLine ("Speed: " + location.Speed);
        }
    }
    
  2. Kodla ilgili bir sorun daha var: Uygulama arka planlandığında kullanıcı arabirimini güncelleştirmeye çalışmak iOS'un sonlandırmasına neden olur. Uygulama arka plana geçtiğinde kodun konum güncelleştirmelerinin aboneliğini kaldırması ve kullanıcı arabirimini güncelleştirmeyi durdurması gerekir.

    iOS, uygulama farklı bir uygulama durumuna geçmek üzere olduğunda bize bildirimler sağlar. Bu durumda Bildirime ObserveDidEnterBackground abone olabilirsiniz.

    Aşağıdaki kod parçacığı, görünümün kullanıcı arabirimi güncelleştirmelerini ne zaman durdurduğunu bildirmek için bir bildirimin nasıl kullanılacağını gösterir. Bu, içinde ViewDidLoadyer alır:

    UIApplication.Notifications.ObserveDidEnterBackground ((sender, args) => {
        Manager.LocationUpdated -= HandleLocationChanged;
    });
    

    Uygulama çalışırken çıkış şuna benzer olacaktır:

    Konsoldaki konum çıkışı örneği

  3. Uygulama, ön planda çalışırken konum güncelleştirmelerini ekrana yazdırır ve arka planda çalışırken verileri uygulama çıktı penceresine yazdırmaya devam eder.

Yalnızca bir bekleyen sorun kaldı: Uygulama ilk yüklendiğinde ekran kullanıcı arabirimi güncelleştirmelerini başlatır, ancak uygulamanın ön plana yeniden ne zaman girdiğini öğrenmenin bir yolu yoktur. Arka plandaki uygulama ön plana geri getirilirse, kullanıcı arabirimi güncelleştirmeleri devam etmez.

Bunu düzeltmek için, kullanıcı arabirimi güncelleştirmelerini başlatmak için bir çağrıyı başka bir Bildirim içinde iç içe yerleştirerek uygulama Etkin duruma girdiğinde tetiklenir:

UIApplication.Notifications.ObserveDidBecomeActive ((sender, args) => {
  Manager.LocationUpdated += HandleLocationChanged;
});

Artık uygulama ilk başlatıldığında kullanıcı arabirimi güncelleştirmeyi başlatır ve uygulama ön plana geri döndüğünde güncelleştirmeyi sürdürür.

Bu kılavuzda, konum verilerini hem ekrana hem de uygulama çıkış penceresine yazdıran iyi davranmış, arka plana duyarlı bir iOS uygulaması oluşturdunuz.