webentwicklung-frage-antwort-db.com.de

Erkennen, ob das Gerät Telefonanrufe unterstützt?

Ist der unten stehende Code zuverlässig, um zu bestimmen, ob ein Gerät Telefonanrufe unterstützen kann oder nicht? Meine Sorge ist, wenn Apple den iPhone-String in etwas anderes ändert. usw.

[[UIDevice currentDevice].model isEqualToString:@"iPhone"]
43
aryaxt

Das iPhone unterstützt das tel: // URI-Schema. Sie könnten also Folgendes verwenden:

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];

canOpenURL: Überprüft explizit, ob es eine Anwendung gibt, die das URL-Schema öffnen kann, nicht, ob die URL korrekt ist. Es ist also egal, dass keine Telefonnummer angegeben ist. Die Methode gibt eine BOOL zurück, also prüfen Sie diese auf JA oder NEIN.

Dies sollte buchstäblich beantworten, ob eine Anwendung vorhanden ist, die einen Telefonanruf tätigen kann. Es sollte also gegen zukünftige Änderungen in der Gerätesegmentierung in Ordnung sein.

96
Tommy

Einfach zu prüfen, ob ein Gerät Telefonanrufe "unterstützt", ist möglicherweise nicht die beste Methode, um je nach dem zu versuchen, was Sie erreichen wollen. Ob Sie es glauben oder nicht, manche Menschen nutzen alte iPhones ohne Service wie einen iPod Touch. In den iPhones sind manchmal keine SIM-Karten installiert. In meiner App wollte ich eine Telefonnummer wählen, wenn das Gerät des Benutzers dies tun konnte, ansonsten wollte ich die Telefonnummer anzeigen und den Benutzer auffordern, ein Telefon zu ergreifen und es zu wählen. Hier ist eine Lösung, die ich mir ausgedacht habe und die bisher funktioniert hat. Fühlen Sie sich frei zu kommentieren und zu verbessern.

// You must add the CoreTelephony.framework
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

-(bool)canDevicePlaceAPhoneCall {
    /*

     Returns YES if the device can place a phone call

     */

    // Check if the device can place a phone call
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]]) {
        // Device supports phone calls, lets confirm it can place one right now
        CTTelephonyNetworkInfo *netInfo = [[[CTTelephonyNetworkInfo alloc] init] autorelease];
        CTCarrier *carrier = [netInfo subscriberCellularProvider];
        NSString *mnc = [carrier mobileNetworkCode]; 
        if (([mnc length] == 0) || ([mnc isEqualToString:@"65535"])) {
            // Device cannot place a call at this time.  SIM might be removed.
            return NO;
        } else {
            // Device can place a phone call
            return YES;
        }
    } else {
        // Device does not support phone calls
        return  NO;
    }
}

Sie werden feststellen, dass ich überprüfe, ob der mobileNetworkCode 65535 ist. Während meines Tests scheint es, dass der mobileNetworkCode beim Entfernen der SIM-Karte auf 65535 gesetzt ist.

62
AlBeebe

Ich muss sicherstellen, dass eingehende Telefonanrufe die von meinen Kunden durchgeführten Aufzeichnungen nicht unterbrechen können. Daher fordere ich sie auf, in den Flugzeugmodus zu wechseln, aber trotzdem WLAN zu aktivieren. Die obige Methode von AlBeebe hat für mich unter iOS 8.1.3 nicht funktioniert, aber wenn gefunden, diese Lösung, die unter iOS 7 und höher funktionieren sollte:

Sie müssen das CoreTelephony.framework hinzufügen und importieren.

#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

Definieren Sie die Eigenschaft für Ihre Klasse, wenn Sie Änderungen nachverfolgen möchten

@property (strong, nonatomic) CTTelephonyNetworkInfo* networkInfo;  

Init CTTelephonyNetworkInfo

self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];

Und dann erhalten Sie einen Rückruf, wenn sich das ändert:

- (void)radioAccessChanged {
    NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology);
}

Die Werte für currentRadioAccessTechnology sind in CTTelephonyNetworkInfo.h definiert und Sie erhalten null/null zurück, wenn keine Cell Tower-Verbindung besteht.

Hier habe ich es gefunden: http://www.raywenderlich.com/48001/einfach-überblick-neue-merkmale-ios-7

11
flo von der uni

Basierend auf der Antwort von @ the-guardian habe ich folgendes gefunden (in Swift):

import CoreTelephony

/**
 Indicates if the device can make a phone call.

 - seealso: [Source](http://stackoverflow.com/a/11595365/3643020)

 - returns: `true` if the device can make a phone call. `false` if not.
 */
final class func canMakePhoneCall() -> Bool {
    guard let url = URL(string: "tel://") else {
        return false
    }

    let mobileNetworkCode = CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode

    let isInvalidNetworkCode = mobileNetworkCode == nil
        || mobileNetworkCode?.count == 0
        || mobileNetworkCode == "65535"

    return UIApplication.shared.canOpenURL(url)
        && !isInvalidNetworkCode
}

Dieser Code wurde auf einem iPad Air 2 Wifi, einem iPad Air 2 Simulator und einem iPhone 6S Plus getestet und scheint ordnungsgemäß zu funktionieren. Wird auf einem iPad mit mobilen Daten bald feststellen. 

10
Campbell_Souped

Diese UIApplication.shared.openURL((URL(string: "tel://\(phoneNumber)")!)) sagt nicht aus, ob SIM oder Nicht vorhanden ist. Dies bedeutet lediglich, wenn das Gerät die Möglichkeit hat, einen Anruf zu tätigen. Zum Beispiel : Ein iPhone mit oder ohne SIM-Karte gibt den Wert "true" zurück. In iPod Touch wird jedoch immer "false" zurückgegeben. Wenn ein iPad keine SIM-Option hat, wird "false" zurückgegeben.

Hier ist der Code, der alles umfassend überprüft! (mit Swift 3.0)

if UIApplication.shared.canOpenURL(URL(string: "tel://\(phoneNumber)")!) {
            var networkInfo = CTTelephonyNetworkInfo()
            var carrier: CTCarrier? = networkInfo.subscriberCellularProvider
            var code: String? = carrier?.mobileNetworkCode
            if (code != nil) {
                UIApplication.shared.openURL((URL(string: "tel://\(phoneNumber)")!))
            }
            else {
                var alert = UIAlertView(title: "Alert", message: "No SIM Inserted", delegate: nil, cancelButtonTitle: "ok", otherButtonTitles: "")
                alert.show()
            }
        }
        else {
            var alert = UIAlertView(title: "Alert", message: "Device does not support phone calls.", delegate: nil, cancelButtonTitle: "ok", otherButtonTitles: "")
            alert.show()
        }

Auf diese Weise können wir sicherstellen, dass das Gerät das Anrufen unterstützt oder nicht.

2
user5886755

Ich glaube nicht, dass Ihre Methode zuverlässig ist, da sich die Gerätenamen in der Zukunft ändern können. Wenn Sie die App nicht auf Geräten ausführen möchten, die nicht auf einem iPhone ausgeführt werden, können Sie dem UIRequiredDeviceCapabilities - Wörterbuch in Ihrer Info.plist die 'Telefonie' hinzufügen. Dadurch können andere Geräte als das iPhone Ihre App nicht aus dem App Store herunterladen.

Wenn Sie zu einem bestimmten Zeitpunkt nach 3G-Konnektivität suchen, können Sie alternativ die Apple-Dienstprogrammklasse Reachability verwenden, um den aktuellen 3G/WIFI-Verbindungsstatus abzufragen.

2
Julio Gorgé

Ich denke das ist es im Allgemeinen. Ich würde mich für einen generischen String-Vergleich entscheiden (um im Falle eines zukünftigen Updates sicherer zu sein). Ich habe es ohne Probleme benutzt (bisher ...). 

Wenn Sie sicherer sein möchten, ob das Gerät tatsächlich Anrufe tätigen kann, sollten Sie auch die Core-Telefonie-API nutzen. Die CTCarrier-Klasse kann Ihnen sagen, ob Sie zu einem bestimmten Zeitpunkt tatsächlich einen Anruf tätigen können.

2
Nick Toumpelis

Wenn Sie gefragt werden, ob Sie eine Telefonnummer anrufen und showan einen Fehler auf Geräten ohne Telefonie anzeigen möchten:

void openURL(NSURL *url, void (^ __nullable completionHandler). (BOOL success))
{
    if (@available(iOS 10.0, *)) {
        [application openURL:url options:@{} completionHandler:^(BOOL success) {
            completionHandler(success);
        }];
    } else
    {
        if([application openURL:url]) {
            completionHandler(YES);
        } else {
            completionHandler(NO);
        }
    }
}

verwendungszweck

        p97openURL(phoneURL, ^(BOOL success) {
            if(!success) {
                  show message saying there is no telephony on device

            }
        }
0
Anton Tropashko