Измерение силы сигнала соты
Я разрабатываю приложение non-appstore для iOS. Я хочу прочитать уровень сотового сигнала в моем коде.
Я знаю, что Apple не предоставляет API, с помощью которого мы можем достичь этого.
Есть ли какой-либо частный API, который можно использовать для достижения этого? Я рассмотрел различные темы, касающиеся этой проблемы, но не смог найти соответствующую информацию.
Это возможно, потому что в app-store есть приложение для обнаружения уровня несущего сигнала.
Ответы
Ответ 1
Я кратко рассмотрел проект VAFieldTest, расположенный в Github.
Кажется, что в классах /VAFieldTestViewController.m есть функции getSignalStrength()
и register_notification()
, которые могут быть вам интересны, поскольку они звонят в CoreTelephony.framework
.
Я довольно уверен, что некоторые из используемых вызовов недокументированы в документации CoreTelephony от Apple и, следовательно, являются частным - любое приложение в AppStore должен был пройти проверку.
Ответ 2
Получить сигнал: 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);
Ответ 3
Это не очень сложно.
- Ссылка CoreTelephony.framework в проекте Xcode
- Добавьте следующие строки, в которых вы нуждаетесь.
код:
int CTGetSignalStrength(); // private method (not in the header) of Core Telephony
- (void)aScanMethod
{
NSLog(@"%d", CTGetSignalStrength()); // or do what you want
}
И все готово.
Обновление май 2016
Apple удалила эту возможность.
Ответ 4
Чтобы получить сигнал в iOS 9 или выше в Swift 3, без использования частного API от CoreTelephony - CTGetSignalStrength()
. Просто очистите представление 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
}
Внимание. Если строка состояния скрыта, ключ "statusBar" будет возвращать нуль.
Ответ 5
Я не тестировал его, но, по-видимому, теперь это метод CTTelephonyNetworkInfo
вместо глобальной/статической функции.
Тип возврата id
, поэтому я думаю, что вы получаете либо NSDictionary
(как подразумевает _cachedSignalStrength
ivar), либо NSNumber
(как подразумевает старая функция).
id signalStrength = [[CTTelephonyNetworkInfo new] signalStrength];
Это изменилось в iOS 8.3, как вы можете видеть из commit.
Обратите внимание, что это все еще не документировано! Поэтому, если ваше приложение поступит в App Store, примите меры предосторожности.
Ответ 6
Здесь ответ Лукаса преобразован в Xamarin и протестирован на 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;