-1

I am developing an iOs app which required to send and received message from Android Host app.

Android host app create Wifi Hotpot programatically, iOS device will join it from setting.

First, I tried with Apple's NSOutputStream class to write to host. But no luck. Now, I am running ConnectionTest example of GCDAsyncSocket. But android host can't read data written by iOS client.

CODE TO ESTABLISH CONNECTION

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

dispatch_queue_t mainQueue = dispatch_get_main_queue();

    asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];

NSString *host = HOST;
        uint16_t port = PORT;

        DDLogInfo(@"Connecting to \"%@\" on port %hu...", host, port);
        self.viewController.label.text = @"Connecting...";

        NSError *error = nil;
        if (![asyncSocket connectToHost:host onPort:port error:&error])
        {
            DDLogError(@"Error connecting: %@", error);
            self.viewController.label.text = @"Oops";
        }
// Add the view controller's view to the window and display.
    [self.window addSubview:self.viewController.view];
    [self.window makeKeyAndVisible];

    return YES;
}

CODE TO WRITE DATA WHEN CONNECTION IS ESTABLISHED

  - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
    {
        DDLogInfo(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
        self.viewController.label.text = @"Connected";

        NSString *requestStr = @"girsh:";
            NSMutableData *requestData = [[NSMutableData alloc] initWithData:[requestStr dataUsingEncoding:NSUTF8StringEncoding]];

            [requestData appendData:[GCDAsyncSocket CRLFData]];

            [sock writeData:requestData withTimeout:1 tag:1];
}

***** ANDROID CODE ********

 private void startHotspot() {
//////////////////
        if (wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(false);
        }
        Method[] wmMethods = wifiManager.getClass().getDeclaredMethods();
        boolean methodFound = false;
        for (Method method : wmMethods) {
            if (method.getName().equals("setWifiApEnabled")) {
                methodFound = true;
                Calendar calendar = Calendar.getInstance();

                WifiConfiguration netConfig = new WifiConfiguration();
                netConfig.SSID = "AISTT" + "What_Next" + calendar.get(Calendar.MINUTE) + "." + calendar.get(Calendar.SECOND);
                netConfig.preSharedKey = "DataAnywhere";//getString(R.string.password);  //// Password
                netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                try {
                    boolean apstatus = (Boolean) method.invoke(wifiManager, netConfig, true);

                    for (Method isWifiApEnabledmethod : wmMethods) {
                        if (isWifiApEnabledmethod.getName().equals("isWifiApEnabled")) {
                            while (!(Boolean) isWifiApEnabledmethod.invoke(wifiManager)) {
                            }

                            for (Method method1 : wmMethods) {
                                if (method1.getName().equals("getWifiApState")) {
                                    int apstate;
                                    apstate = (Integer) method1.invoke(wifiManager);
                                    Log.i(this.getClass().toString(), "Apstate ::: " + apstate);
                                }
                            }
                        }
                    }
                    if (apstatus) {
                        Log.d("Splash Activity", "Access Point created");
                    } else {
                        Log.d("Splash Activity", "Access Point creation failed");
                    }

                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        if (!methodFound) {
            Log.d("Splash Activity",
                    "cannot configure an access point");
        }

        ///////////////////
    }
girish_pro
  • 838
  • 9
  • 18

1 Answers1

1

I've seen a couple of mistakes in your code.

First part is this:

dispatch_queue_t mainQueue = dispatch_get_main_queue();

asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];

You are running the connection in the main queue, which is not a good way. Because in some way, you might block the main thread. Or other operations going in the main thread will block you.

What I will do is, I will put the connection in a thread other than the main.

_asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

Second part is this:

[sock writeData:requestData withTimeout:1 tag:1];

You just set the timeout to 1. That's too short, at least set it to 30, or just set it to -1(What I would normally do), for no timeout. Because there might be a case that the write was not successful then the connection will not rewrite the data again because the timeout is reached.

You can also check if the write is successful or not through this callback:

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag

If everything is OK in your iOS part. Then I suggest you check the coding on Android part.

JLT
  • 3,052
  • 9
  • 39
  • 86