ios 检测设备是否支持通话?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5094928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting whether or not device support phone calls?
提问by aryaxt
Is the below code reliable to be used to determine whether a device can support phone calls or not? My concern is if apple changes the iphone string to anything else let's say they decide to have "iphone 3g", "iphone 4" etc.
以下代码是否可靠用于确定设备是否支持电话?我担心的是,如果苹果将 iphone 字符串更改为其他任何内容,假设他们决定拥有“iphone 3g”、“iphone 4”等。
[[UIDevice currentDevice].model isEqualToString:@"iPhone"]
回答by Tommy
The iPhone supports the tel:// URI scheme. So you could use:
iPhone 支持 tel:// URI 方案。所以你可以使用:
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];
canOpenURL: explicitly checks whether there's an application capable of opening that URL scheme, not that the URL is correct. So it doesn't matter that no phone number is specified. The method returns a BOOL, so check that for YES or NO.
canOpenURL:明确检查是否有能够打开该 URL 方案的应用程序,而不是 URL 是否正确。所以没有指定电话号码也没有关系。该方法返回一个 BOOL,因此请检查 YES 或 NO。
That should literally answer whether there's any application present capable of making a telephone call. So it should be okay against any future changes in device segmentation.
这应该从字面上回答是否存在任何能够拨打电话的应用程序。因此,未来设备细分的任何变化都应该没问题。
回答by AlBeebe
Simply checking if a device "supports" phone calls might not be the best way to go about things depending on what your trying to accomplish. Believe it or not, some people use old iPhones without service as if they were an iPod Touch. Sometimes people don't have SIM cards installed in their iPhones. In my app I wanted to dial a phone number if the users device was able to, otherwise I wanted to display the phone number and prompt the user to grab a phone and dial it. Here is a solution I came up with that has worked so far. Feel free to comment and improve it.
简单地检查设备是否“支持”电话可能不是解决问题的最佳方式,具体取决于您要完成的工作。信不信由你,有些人使用没有服务的旧 iPhone,就好像他们是 iPod Touch。有时人们的 iPhone 中没有安装 SIM 卡。在我的应用程序中,如果用户设备能够拨打电话号码,我想拨打电话号码,否则我想显示电话号码并提示用户拿起电话并拨打电话。这是我想出的一个解决方案,到目前为止已经奏效。随意评论并改进它。
// 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;
}
}
You'll notice I check if the mobileNetworkCode is 65535. In my testing, it appears that when you remove the SIM card, then the mobileNetworkCode is set to 65535. Not 100% sure why that is.
您会注意到我检查了 mobileNetworkCode 是否为 65535。在我的测试中,似乎当您移除 SIM 卡时,mobileNetworkCode 设置为 65535。不是 100% 确定这是为什么。
回答by flo von der uni
I need to make sure that incoming phone calls cannot interrupt the recordings that my clients make, so I prompt them to go to airplane mode but still turn on wifi. The method above from AlBeebe didn't work for me on iOS 8.1.3, but If found this solution which should work in iOS 7 and later:
我需要确保来电不会中断我客户的录音,所以我提示他们进入飞行模式但仍然打开 wifi。上面来自 AlBeebe 的方法在 iOS 8.1.3 上对我不起作用,但是如果找到这个应该在 iOS 7 及更高版本中工作的解决方案:
You must add and import the CoreTelephony.framework.
您必须添加并导入 CoreTelephony.framework。
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
Define the property on your class if you want to track changes
如果要跟踪更改,请定义类的属性
@property (strong, nonatomic) CTTelephonyNetworkInfo* networkInfo;
Init the CTTelephonyNetworkInfo
:
初始化CTTelephonyNetworkInfo
:
self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];
And then you will receive callback when it changes:
然后你会在它改变时收到回调:
- (void)radioAccessChanged {
NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology);
}
The values for currentRadioAccessTechnology
are defined in
CTTelephonyNetworkInfo.h and you'll get back null / nil when there is no cell tower connection.
的值currentRadioAccessTechnology
在 CTTelephonyNetworkInfo.h 中定义,当没有蜂窝塔连接时,您将返回 null/nil。
This is where I found it: http://www.raywenderlich.com/48001/easily-overlooked-new-features-ios-7
这是我找到它的地方:http: //www.raywenderlich.com/48001/easily-overlooked-new-features-ios-7
回答by Campbell_Souped
Based on @the-guardian's response, I have come up with the following (in swift):
根据@the-guardian 的回复,我提出了以下内容(迅速):
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
}
This code has been tested on an iPad Air 2 Wifi, an iPad Air 2 Simulator, an iPhone 6S Plus, and seems to work appropriately. Will determine on an iPad with mobile data soon.
这段代码已经在 iPad Air 2 Wifi、iPad Air 2 Simulator、iPhone 6S Plus 上进行了测试,似乎可以正常工作。很快将在具有移动数据的 iPad 上确定。
回答by Julio Gorgé
I don't think your method is reliable, as device names may change in the future. If your concern is to prevent the app from running on non-iPhone devices, you may add the 'telephony' to the UIRequiredDeviceCapabilitiesdictionary in your Info.plist. That will disallow devices other than the iPhone to download your app from the App Store.
我认为您的方法不可靠,因为设备名称将来可能会更改。如果您担心阻止应用在非 iPhone 设备上运行,您可以将“电话”添加到Info.plist 中的UIRequiredDeviceCapabilities字典中。这将禁止 iPhone 以外的设备从 App Store 下载您的应用程序。
Alternatively, if what you need is checking for 3G connectivity at a particular moment, you can use Apple's Reachabilityutility class to ask about current 3G/WIFI connection status.
或者,如果您需要在特定时刻检查 3G 连接,您可以使用 Apple 的Reachability实用程序类来询问当前的 3G/WIFI 连接状态。
回答by Nick Toumpelis
I think that generally it is. I would go for a more generic string comparison (just to be safer in case of a future update). I've used it with no problems (so far...).
我认为一般是这样。我会进行更通用的字符串比较(只是为了在将来更新时更安全)。我已经使用它没有问题(到目前为止......)。
If you want to be more certain about whether the device can actually make calls, you should also take advantage of the Core Telephony API. The CTCarrier class can tell you whether you can actually make a call at any particular moment.
如果您想更确定设备是否真的可以拨打电话,您还应该利用 Core Telephony API。CTCarrier 类可以告诉您是否可以在任何特定时刻实际拨打电话。
回答by Nick Toumpelis
This UIApplication.shared.openURL((URL(string: "tel://\(phoneNumber)")!))
will not say if it has SIM or Not this will just say, if the device has options to make a call. For example: A iPhone with or without SIM it'll return true, but in iPod Touch it will always return false, like wise if an ipad doesn't have sim option it will return false.
这UIApplication.shared.openURL((URL(string: "tel://\(phoneNumber)")!))
不会说明它是否有 SIM 卡,这只会说明设备是否有拨打电话的选项。例如:带有或不带有 SIM 卡的 iPhone 将返回 true,但在 iPod Touch 中它将始终返回 false,同样明智的是,如果 ipad 没有 SIM 选项,它将返回 false。
Here is the code that checks everything comprehensively !(Using Swift 3.0)
这是全面检查所有内容的代码!(使用 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()
}
By this way, we can make sure, device supports calling or not.
通过这种方式,我们可以确定设备是否支持呼叫。
回答by Anton Tropashko
In case you are asking in order to call a phone number and show an error on devices that have no telephony:
如果您要求拨打电话号码并在没有电话的设备上显示错误:
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);
}
}
}
usage
用法
p97openURL(phoneURL, ^(BOOL success) {
if(!success) {
show message saying there is no telephony on device
}
}
回答by user1107173
Based on @TheGuardian's answer, I think this might be a simpler approach:
根据@TheGuardian 的回答,我认为这可能是一种更简单的方法:
private final func canMakePhoneCall() -> Bool {
guard UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Phone else {
return false
}
let mobileNetworkCode = CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode
let isInvalidNetworkCode = mobileNetworkCode == nil || mobileNetworkCode?.characters.count <= 0
|| mobileNetworkCode == "65535"
//When sim card is removed, the Code is 65535
return !isInvalidNetworkCode
}