0

機内モード、WiFi、SSHなど、SBSettingsトグルを使用してオンまたはオフにしようとしていますが、コードがこれらのトグルのすべてではなく一部で機能する理由がわかりません。確かに、私は「単純な」トグルについて話しているだけです。音量や明るさなどの独自のコントロールで独自のウィンドウを表示するトグルではありません。3G、データ、着信音、mywiトグルなどを正常にオン/オフできましたが、機内モード、Bluetooth、WiFiなどのトグルの一部がオンになっている理由がわかりません。私の電話は、上記の他のもので動作する同じコードに応答しません。

これが私が使用しているコードの一部です:

//.h
#import <UIKit/UIKit.h>
#import <sys/stat.h>
#include "/usr/include/dlfcn.h"

typedef enum toggleTypes
{
    SIMPLE,
    NOT_SIMPLE
} ToggleTypes;

typedef bool (*BoolFn)();
typedef void (*VoidBoolFn)(bool b);

@interface Toggle : NSObject
@property (strong, nonatomic) NSString *toggleName;
@property (nonatomic) ToggleTypes toggleType;

- (Toggle *) initWithFullPath:(NSString *) togglePath;
- (BOOL) isEnabled;
- (BOOL) isCapable;
- (BOOL) getStateFast;
- (void) setState:(BOOL) state;

@end
//.m
@implementation Toggle {
    @private
    void *_dylibHandle;
    BoolFn _isCapable;
    BoolFn _isEnabled;
    BoolFn _getStateFast;
    VoidBoolFn _setState;
}

@synthesize toggleName = _toggleName;
@synthesize toggleType = _toggleType;

- (Toggle *) initWithFullPath:(NSString *) togglePath
{
    self.toggleName = [[togglePath stringByDeletingLastPathComponent] lastPathComponent];
    const char *fullName = [togglePath UTF8String];
    struct stat fstat;
    if( stat(fullName, &fstat) != 0 )
    {
        NSLog(@"Reading error for file %s", fullName);
        return nil;
    }
    dlerror();

    _dylibHandle = dlopen(fullName, RTLD_LAZY | RTLD_LOCAL );
    if( !_dylibHandle)
    {
        NSLog(@"dlopen encountered an error and did not open file: %s", fullName);
        return nil;
    }

    dlerror();
    _isCapable = dlsym(_dylibHandle, "isCapable");
    char *error = dlerror();
    if( !_isCapable )
    {
        NSLog(@"An error was encountered while loading symbol \"isCapable\"\nFile: %s\nError: %s", fullName, error);
        return nil;
    }

    _isEnabled = dlsym(_dylibHandle, "isEnabled");
    error = dlerror();
    if( !_isCapable )
    {
        NSLog(@"An error was encountered while loading symbol \"isEnabled\"\nFile: %s\nError: %s", fullName, error);
        return nil;
    }

    _getStateFast = dlsym(_dylibHandle, "getStateFast");
    error = dlerror();
    if( !_isCapable )
    {
        NSLog(@"An error was encountered while loading symbol \"getStateFast\"\nFile: %s\nError: %s", fullName, error);
        return nil;
    }

    _setState = dlsym(_dylibHandle, "setState");
    error = dlerror();
    if( !_isCapable )
    {
        NSLog(@"An error was encountered while loading symbol \"getStateFast\"\nFile: %s\nError: %s", fullName, error);
        return nil;
    }

    NSArray *windowsBefore = [[[[UIApplication sharedApplication] windows] objectAtIndex:0] subviews];
    [self setState:[self isEnabled]];
    NSArray *windowsAfter = [[[[UIApplication sharedApplication] windows] objectAtIndex:0] subviews];

    if( [windowsAfter count] > [windowsBefore count] ) {
        self.toggleType = NOT_SIMPLE;
        for (UIView *view in windowsAfter) {
            if( ![windowsBefore containsObject:view] )
                [view removeFromSuperview];
        }
    } else { 
        self.toggleType = SIMPLE;
    }

    return self;
}

- (BOOL) isEnabled
{
    return _isEnabled();
}

- (BOOL) isCapable
{
    return _isCapable();
}

- (BOOL) getStateFast
{
    return _getStateFast();
}

- (void) setState:(BOOL) state
{
    _setState(state);
}

- (void) dealloc
{
    dlclose(_dylibHandle);
}
@end

を呼び出すコード initWithFullPath

if( [directoryToggleNames objectForKey:toggleName] == nil ) {
    if ((strlen(SBTOGGLES_PATH) + strlen([toggleName UTF8String] + strlen("/Toggle.dylib")) + 1) > _POSIX_PATH_MAX) {
        NSLog(@"Toggle %@ has a path name that is too long", toggleName);
        return nil;
    }
    char fullName[_POSIX_PATH_MAX + 1];
    strcpy(fullName, SBTOGGLES_PATH);
    strcat(fullName, [toggleName UTF8String]);
    strcat(fullName, "/Toggle.dylib");

    NSString *fullPath = [NSString stringWithUTF8String:fullName];
    return [[OSToggle alloc] initWithFullPath:fullPath];
}

return [[OSToggle alloc] initWithFullPath:[directoryToggleNames objectForKey:toggleName]];

上記のコードとトグルクラス自体を使用するコード:

ToggleScanner *scanner = [ToggleScanner getInstance];
NSDictionary *toggleDict = [self getToggleDictionary];
for (ToggleBase *t in [toggleDict allValues] ) {
    OSToggle *toggle = [scanner getToggleByName:t.name];
    if( [t.type isEqualToString:@"simple"] ) {
        NSLog(@"isCapable: %@; isEnabled: %@", ( [toggle isCapable] ? @"YES" : @"NO" ),  ( [toggle isEnabled] ? @"YES" : @"NO" ));

        [toggle setState:t.state.boolValue];
        NSLog(@"Set toggle, %@, to %@; result isEnabled: %@", t.name, ( t.state.boolValue ? @"YES" : @"NO" ), ( [toggle isEnabled] ? @"YES" : @"NO" ) );
    } else {
        NSLog(@"Toggle is not a simple type");
    }
}

ToggleScannerは、SBSettingsトグルディレクトリを調べ、そこで見つかったトグルに基づいて辞書を作成します。getToggleDictは、CoreDataからNSDataオブジェクトを取り出し、それを一連のトグルと状態に変換して、実行できるようにするメソッドです。ToggleBaseは単なる情報保持クラスです。メソッドはありません。

ラフですが、一部のトグルで機能します。問題は、私がここで間違っていることはありますか?機内モードと3Gトグルはどちらも単純なオン/オフスイッチですが、このコードは3Gトグルでは機能しますが、機内モードでは機能しません。これがなぜであるかについてのアイデア、コメント、および/または提案はありますか?


編集1:トグルクラスを呼び出すコードとその説明を追加しました。

4

2 に答える 2

1

私のアイデアはあなたの元のアイデアに似ています。SBSettingの各toggle.dylibに接続して、3G、Wi-Fi、MyFiをオン/オフにしようとしています。しかし、私はそれを3Gトグルでしか機能させることができませんでした。MyFiトグルでも機能させる方法がわかりませんでした。どのバージョンのMyFiを使用しましたか?

于 2012-09-22T13:46:57.173 に答える
0

ちなみに、場所、データなどの他のトグルもテストしましたが、すべて機能しました。ロケーショントグルのソースコードを確認したところ、単に locationd.plist ファイルのプロパティを変更するだけでしたが、WiFi トグルの場合は、プライベートフレームワーク SBWiFimanager を利用する必要があるため、問題が発生する可能性があります。SB フレームワークを使用する場合、踏み台コンテキストが必要です。したがって、トグルのメソッドをアプリから呼び出す場合、踏み台コンテキストはありません。WiFiと飛行機のトグルが機能しないのはそれが理由だと思います。

于 2012-09-23T11:22:38.847 に答える