Je développe une application non-appstore pour iOS. Je veux lire la force du signal cellulaire dans mon code.
Je sais qu'Apple ne fournit aucune API permettant d'atteindre cet objectif.
Existe-t-il une API privée pouvant être utilisée pour cela? J'ai parcouru les différents sujets concernant ce problème, mais je n'ai trouvé aucune information pertinente.
Cela est tout à fait possible car il y a un app dans le magasin d'applications pour détecter l'intensité du signal de la porteuse.
J'ai brièvement examiné le projet VAFieldTest situé à l'adresse Github .
Il semble y avoir dans les classes/VAFieldTestViewController.m des fonctions getSignalStrength()
et register_notification()
qui pourraient vous intéresser lorsqu’elles appellent dans CoreTelephony.framework
.
Je suis assez confiant que certains des appels utilisés ne sont pas documentés dans la documentation du framework CoreTelephony d'Apple et sont donc privés - toute application de l'AppStore doit avoir passé avec succès l'inspection.
Obtenez le signalStreght IOS9:
UIApplication *app = [UIApplication sharedApplication];
NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
NSString *dataNetworkItemView = nil;
for (id subview in subviews) {
if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]])
{
dataNetworkItemView = subview;
break;
}
}
int signalStrength = [[dataNetworkItemView valueForKey:@"signalStrengthRaw"] intValue];
NSLog(@"signal %d", signalStrength);
Ce n'est pas très difficile.
Code:
int CTGetSignalStrength(); // private method (not in the header) of Core Telephony
- (void)aScanMethod
{
NSLog(@"%d", CTGetSignalStrength()); // or do what you want
}
Et vous avez terminé.
Mise à jour mai 2016
Apple a supprimé cette opportunité.
Pour obtenir une résolution du signal sous iOS 9 ou supérieur dans Swift 3, sans utiliser l'API privée de CoreTelephony - CTGetSignalStrength()
. Il suffit de parcourir la vue statusBar.
func getSignalStrength() -> Int {
let application = UIApplication.shared
let statusBarView = application.value(forKey: "statusBar") as! UIView
let foregroundView = statusBarView.value(forKey: "foregroundView") as! UIView
let foregroundViewSubviews = foregroundView.subviews
var dataNetworkItemView:UIView!
for subview in foregroundViewSubviews {
if subview.isKind(of: NSClassFromString("UIStatusBarSignalStrengthItemView")!) {
dataNetworkItemView = subview
break
} else {
return 0 //NO SERVICE
}
}
return dataNetworkItemView.value(forKey: "signalStrengthBars") as! Int
}
Attention : Si la barre d'état est masquée, la clé "statusBar" retournera nil.
Je ne l'ai pas testée, mais apparemment, il s'agit maintenant d'une méthode de CTTelephonyNetworkInfo
au lieu d'une fonction globale/statique.
Le type de retour est id
, je pense donc que vous obtenez soit une NSDictionary
(comme le suggère le code _cachedSignalStrength
ivar), soit un NSNumber
(comme le suggère l'ancienne fonction).
id signalStrength = [[CTTelephonyNetworkInfo new] signalStrength];
Cela a changé dans iOS 8.3, comme vous pouvez le constater avec le commit .
Notez que ceci n'est toujours pas documenté! Donc, si votre application va dans l'App Store, prenez vos précautions.
Voici la réponse de Lucas convertie en Xamarin et testée sur iOS 10.2.1:
var application = UIApplication.SharedApplication;
var statusBarView = application.ValueForKey(new NSString("statusBar")) as UIView;
var foregroundView = statusBarView.ValueForKey(new NSString("foregroundView")) as UIView;
UIView dataNetworkItemView = null;
foreach (UIView subview in foregroundView.Subviews)
{
if ("UIStatusBarSignalStrengthItemView" == subview.Class.Name)
{
dataNetworkItemView = subview;
break;
}
}
if (null == dataNetworkItemView)
return false; //NO SERVICE
int bars = ((NSNumber)dataNetworkItemView.ValueForKey(new NSString("signalStrengthBars"))).Int32Value;