You're getting this error because you didn't explicitly ask user for permissions, which you must do in order to use the Nearby API. Here's one way to do this:
// GoogleApiClient connection callback. Initiate permission check here.
@Override
public void onConnected(Bundle connectionHint) {
Nearby.Messages.getPermissionStatus(mGoogleApiClient).setResultCallback(
new ErrorCheckingCallback("getPermissionStatus", new Runnable() {
@Override
public void run() {
publishAndSubscribe();
}
})
);
}
// This is called in response to a button tap in the Nearby permission dialog.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_RESOLVE_ERROR) {
mResolvingError = false;
if (resultCode == RESULT_OK) {
// Permission granted or error resolved successfully then we proceed
// with publish or subscribe..
publishAndSubscribe();
} else {
// This may mean that user had rejected to grant nearby permission.
showToast("Failed to resolve error with code " + resultCode);
}
}
}
/**
* A simple ResultCallback that displays a toast when errors occur.
* It also displays the Nearby opt-in dialog when necessary.
*/
private class ErrorCheckingCallback implements ResultCallback<Status> {
private final String method;
private final Runnable runOnSuccess;
private ErrorCheckingCallback(String method) {
this(method, null);
}
private ErrorCheckingCallback(String method, @Nullable Runnable runOnSuccess) {
this.method = method;
this.runOnSuccess = runOnSuccess;
}
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Log.i(TAG, method + " succeeded.");
if (runOnSuccess != null) {
runOnSuccess.run();
}
} else {
// Currently, the only resolvable error is that the device is not opted
// in to Nearby. Starting the resolution displays an opt-in dialog.
if (status.hasResolution()) {
if (!mResolvingError) {
try {
status.startResolutionForResult(MainActivity.this,
REQUEST_RESOLVE_ERROR);
mResolvingError = true;
} catch (IntentSender.SendIntentException e) {
showToastAndLog(Log.ERROR, method + " failed with exception: " + e);
}
} else {
// This will be encountered on initial startup because we do
// both publish and subscribe together. So having a toast while
// resolving dialog is in progress is confusing, so just log it.
Log.i(TAG, method + " failed with status: " + status
+ " while resolving error.");
}
} else {
showToastAndLog(Log.ERROR, method + " failed with : " + status
+ " resolving error: " + mResolvingError);
}
}
}
}
You can find a complete example in the documentation.
Also, remember about the guidelines:
Don’t surprise the user. Require the user to perform an explicit
action (a button tap, going to a section in your app, a special
switch, etc) to activate Nearby.
On both iOS and Android, calling
Nearby for the first time will trigger a permission dialog. Waiting
for an explicit user action before invoking Nearby will help the user
contextualize the dialog and associate it with your app's
proximity-based feature.