title: Google Nearby ultrasonic messages between iOS and Android
body: <p>I'm trying to use Google Nearby to send messages using exactly ultrasound (not BLE or WiFi). I have no idea why it doesn't work.
  I haven't found any additional steps for get this work.</p>
  
  <p>No errors. Log says that publishing is successful. But subscriber doesn't react at all </p>
  
  <p>Should apps request microphone permissions?
  Should app check anything else?
  Is there any ready working sample of ultrasonic messages between iOS and Android?</p>
  
  <p>iOS part:</p>
  
  <pre><code>@implementation ViewController {
      GNSMessageManager *_messageManager;
  }
  
  - (void)viewDidLoad {
      [super viewDidLoad];
      _messageManager = [[GNSMessageManager alloc]
              initWithAPIKey:@"MY_API_KEY"
                 paramsBlock:^(GNSMessageManagerParams *params) {
                     params.microphonePermissionErrorHandler = ^(BOOL hasError) {
                         NSLog(@"Microphone Permission Error:%@", hasError ? @"YES" : @"NO");
  
                     };
                     params.bluetoothPowerErrorHandler = ^(BOOL hasError) {
                         NSLog(@"Bluetooth Power Error:%@", hasError ? @"YES" : @"NO");
  
                     };
                     params.bluetoothPermissionErrorHandler = ^(BOOL hasError) {
                         NSLog(@"Bluetooth Permission Error:%@", hasError ? @"YES" : @"NO");
                     };
                 }];
      [GNSMessageManager setDebugLoggingEnabled:YES];
      [GNSPermission setGranted:YES];
      GNSPermission *nearbyPermission = [[GNSPermission alloc] initWithChangedHandler:^(BOOL granted) {
          NSLog(@"Nearby Permission:%@", granted ? @"YES" : @"NO");
      }];
  
      id &lt;GNSSubscription&gt; subscription = [_messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
                  NSLog(@"subscriptionWithMessageFoundHandler");
  
                  UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Google Nearby Message" message:[[NSString alloc] initWithData:message.content encoding:NSUTF8StringEncoding] preferredStyle:UIAlertControllerStyleAlert];
                  [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]];
                  [self presentViewController:alertController animated:YES completion:nil];
              }
                                                                            messageLostHandler:^(GNSMessage *message) {
                                                                                // Remove the name from the list
                                                                            }
                                                                                   paramsBlock:^(GNSSubscriptionParams *subscriptionParams) {
                                                                                       subscriptionParams.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
                                                                                           params.discoveryMediums = kGNSDiscoveryMediumsAudio;
                                                                                           params.discoveryMode = kGNSDiscoveryModeScan;
                                                                                       }];
                                                                                   }
      ];
  
  
  }
  
  
  - (void)didReceiveMemoryWarning {
      [super didReceiveMemoryWarning];
      // Dispose of any resources that can be recreated.
  }
  
  - (IBAction)publishDidClick:(id)sender {
      NSString *string = self.publisherField.text;
      if (string == nil || string.length == 0) {
          UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Google Nearby" message:@"Please put some text into field before publishing" preferredStyle:UIAlertControllerStyleAlert];
          [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]];
          [self presentViewController:alertController animated:YES completion:nil];
  
      } else {
          @try {
              GNSMessage *gnsMessage = [GNSMessage messageWithContent:[string dataUsingEncoding:NSUTF8StringEncoding]];
              id &lt;GNSPublication&gt; publication = [_messageManager publicationWithMessage:gnsMessage
                                                                            paramsBlock:^(GNSPublicationParams *params) {
                                                                                params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
                                                                                    params.discoveryMediums = kGNSDiscoveryMediumsAudio;
                                                                                }];
                                                                            }];
  
          }
          @catch (NSException *exception) {
              NSLog(@"Exception occurred: %@, %@", exception, [exception userInfo]);
          }
      }
  
  
  }
  </code></pre>
  
  <p>iOS logs:</p>
  
  <pre><code>2017-02-17 22:33:33.701925 GoogleNearbySample[5727:1608902] Nearby Permission:YES
  2017-02-17 22:33:35.842523 GoogleNearbySample[5727:1608902] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
  2017-02-17 22:33:35.853836 GoogleNearbySample[5727:1608902] [MC] Reading from public effective user settings.
  2017-02-17 22:33:40.630279 GoogleNearbySample[5727:1608902] Publish (mediums: 1, broadcast/scan: 3, beacons: 0/0/0, background: 0)
  2017-02-17 22:33:40.677551 GoogleNearbySample[5727:1608902] Unpublish
  2017-02-17 22:33:40.681520 GoogleNearbySample[5727:1608902] Tokens: 0 good, 0 bad, 0 broadcast
  2017-02-17 22:33:40.681663 GoogleNearbySample[5727:1608902] Report RPC request: 0 token(s), 0 beacon(s), 0 directive(s)
  2017-02-17 22:33:40.705243 GoogleNearbySample[5727:1608902] Report RPC request: Publish: 1
  2017-02-17 22:33:40.705933 GoogleNearbySample[5727:1608902] Report RPC request: Unpublish: 1
  2017-02-17 22:33:41.625510 GoogleNearbySample[5727:1608902] Report RPC response: Success
  2017-02-17 22:33:41.626823 GoogleNearbySample[5727:1608902] Report RPC response: 6 directive(s), 0 token(s), 0 message(s), 1 publication results(s), 0 subscription results(s)
  2017-02-17 22:33:41.641955 GoogleNearbySample[5727:1608902] Tokens: 0 good, 0 bad, 0 broadcast
  2017-02-17 22:33:41.642170 GoogleNearbySample[5727:1608902] Report RPC request: 0 token(s), 0 beacon(s), 0 directive(s)
  2017-02-17 22:33:41.889006 GoogleNearbySample[5727:1608902] Report RPC response: Success
  2017-02-17 22:33:41.889370 GoogleNearbySample[5727:1608902] Report RPC response: 0 directive(s), 0 token(s), 0 message(s), 0 publication results(s), 0 subscription results(s)
  2017-02-17 22:33:46.337377 GoogleNearbySample[5727:1608902] Publish (mediums: 1, broadcast/scan: 3, beacons: 0/0/0, background: 0)
  2017-02-17 22:33:46.342647 GoogleNearbySample[5727:1608902] Unpublish
  2017-02-17 22:33:46.350383 GoogleNearbySample[5727:1608902] Tokens: 0 good, 0 bad, 0 broadcast
  2017-02-17 22:33:46.350746 GoogleNearbySample[5727:1608902] Report RPC request: 0 token(s), 0 beacon(s), 0 directive(s)
  2017-02-17 22:33:46.351382 GoogleNearbySample[5727:1608902] Report RPC request: Publish: 1
  2017-02-17 22:33:46.351675 GoogleNearbySample[5727:1608902] Report RPC request: Unpublish: 1
  2017-02-17 22:33:46.937869 GoogleNearbySample[5727:1608902] Report RPC response: Success
  2017-02-17 22:33:46.938223 GoogleNearbySample[5727:1608902] Report RPC response: 6 directive(s), 0 token(s), 0 message(s), 1 publication results(s), 0 subscription results(s)
  2017-02-17 22:33:46.951400 GoogleNearbySample[5727:1608902] Tokens: 0 good, 0 bad, 0 broadcast
  2017-02-17 22:33:46.951618 GoogleNearbySample[5727:1608902] Report RPC request: 0 token(s), 0 beacon(s), 0 directive(s)
  2017-02-17 22:33:47.174414 GoogleNearbySample[5727:1608902] Report RPC response: Success
  2017-02-17 22:33:47.174676 GoogleNearbySample[5727:1608902] Report RPC response: 0 directive(s), 0 token(s), 0 message(s), 0 publication results(s), 0 subscription results(s)
  </code></pre>
  
  <p>Android part: </p>
  
  <pre><code>public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
      private static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 12341;
      private GoogleApiClient mGoogleApiClient;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          View view = findViewById(R.id.button);
          view.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  PublishOptions publishOptions = new PublishOptions.Builder().setStrategy(new Strategy.Builder().setDiscoveryMode(Strategy.DISCOVERY_MODE_SCAN)
                          .setDistanceType(Strategy.DISTANCE_TYPE_EARSHOT).build()).build();
                  Nearby.Messages.publish(mGoogleApiClient, new Message("Hello Artur".getBytes()), publishOptions).setResultCallback(new ResultCallback&lt;Status&gt;() {
                      @Override
                      public void onResult(@NonNull Status status) {
                          Log.i("Nearby", status.getStatusMessage());
                      }
                  });
  
              }
          });
          int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
          if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
              mGoogleApiClient = new GoogleApiClient.Builder(this)
                      .addApi(Nearby.MESSAGES_API)
                      .addConnectionCallbacks(this)
                      .enableAutoManage(this, this)
                      .build();
  
          } else {
              ActivityCompat.requestPermissions(this,
                      new String[]{Manifest.permission.RECORD_AUDIO},
                      MY_PERMISSIONS_REQUEST_READ_CONTACTS);
          }
      }
  
      @Override
      public void onConnected(@Nullable Bundle bundle) {
          SubscribeOptions subscribeOptions = new SubscribeOptions.Builder()
                  .setStrategy(new Strategy.Builder().setDiscoveryMode(Strategy.DISCOVERY_MODE_SCAN)
                          .setDistanceType(Strategy.DISTANCE_TYPE_EARSHOT).build()).build();
          Nearby.Messages.subscribe(mGoogleApiClient, new MessageListener() {
              @Override
              public void onFound(Message message) {
                  super.onFound(message);
                  Log.i("Nearby", "Subscribed found.");
                  Toast.makeText(getApplicationContext(), new String(message.getContent()), Toast.LENGTH_LONG).show();
  
              }
          }, subscribeOptions).setResultCallback(new ResultCallback&lt;Status&gt;() {
              @Override
              public void onResult(Status status) {
                  if (status.isSuccess()) {
                      Log.i("Nearby", "Subscribed successfully.");
                  } else {
                      Log.i("Nearby", "Could not subscribe.");
                      // Check whether consent was given;
                      // if not, prompt the user for consent.
                      handleUnsuccessfulNearbyResult(status);
                  }
              }
          });
      }
  
      private void handleUnsuccessfulNearbyResult(Status status) {
          Log.i("Nearby", "Processing error, status = " + status);
  
      }
  
      @Override
      public void onConnectionSuspended(int i) {
          Log.d("onConnectionSuspended", String.valueOf(i));
      }
  
      @Override
      public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
          Log.d("onConnectionFailed", connectionResult.getErrorMessage());
  
      }
  }
  </code></pre>
  
  <p>Android logs:</p>
  
  <pre><code>02-17 22:32:56.158 11325-11325/? I/Nearby: Subscribed successfully.
  02-17 22:32:59.929 11325-11325/? D/NearbyMessagesClient: Emitting client lifecycle event ACTIVITY_STOPPED
  02-17 22:32:59.930 11325-11325/? D/NearbyMessagesClient: Emitting client lifecycle event CLIENT_DISCONNECTED
  02-17 22:33:28.890 11325-11325/? I/Nearby: Subscribed successfully.
  02-17 22:33:45.867 11325-11325/? I/Nearby: SUCCESS
  02-17 22:33:46.542 11325-11325/? I/Nearby: SUCCESS
  02-17 22:33:47.137 11325-11325/? I/Nearby: SUCCESS
  02-17 22:33:47.779 11325-11325/? I/Nearby: SUCCESS
  02-17 22:33:48.422 11325-11325/? I/Nearby: SUCCESS
  02-17 22:33:49.053 11325-11325/? I/Nearby: SUCCESS
  02-17 22:34:18.477 11325-11325/? D/NearbyMessagesClient: Emitting client lifecycle event ACTIVITY_STOPPED
  02-17 22:34:18.479 11325-11325/? D/NearbyMessagesClient: Emitting client lifecycle event CLIENT_DISCONNECTED
  02-17 22:36:47.996 11325-11325/? D/NearbyMessagesClient: Failed to emit client lifecycle event ACTIVITY_STOPPED due to GmsClient being disconnected
  02-17 22:36:47.997 11325-11325/? D/NearbyMessagesClient: Failed to emit client lifecycle event CLIENT_DISCONNECTED due to GmsClient being disconnected
  </code></pre>