I want to send a messsage to two different Android Smart-Watches.
On the mobile side the Wearable.MessageApi.sendMessage gets called and the sendMessageResult.getStatus().isSuccess() is true, so the sending of the message should work.
The problem now is, that the onMessageReceived method of the MyWearableListenerService never receives a message. What am I doing wrong?
This is the code I'm using:
MainActivity of the Android App.
The left/right methods are sending the messages
public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener {
private static final String TAG_CONNECTION = "Connection";
private static final String TAG_NODES = "Nodes";
private static final String START_ACTIVITY_PATH = "/start_MainActivity";
private String leftWatch;
private String rightWatch;
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Setting up the Wearable API Client
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Wearable.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.e(TAG_CONNECTION, "Connection established");
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG_CONNECTION, "Connection suspended");
}
})
.build();
mGoogleApiClient.connect();
// Find the connected watches and store their UUIDs to distinguish at a later moment
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(#NonNull NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
List<Node> nodes = getConnectedNodesResult.getNodes();
if (nodes.isEmpty()) {
Log.e(TAG_NODES, "No Nodes found");
return;
}
rightWatch = nodes.get(0).getId();
Log.e(TAG_NODES,"Node is nearby: "+nodes.get(0).isNearby());
Log.e(TAG_NODES, rightWatch);
leftWatch = nodes.get(1).getId();
Log.e(TAG_NODES,"Node is nearby: "+nodes.get(1).isNearby());
Log.e(TAG_NODES, leftWatch);
}
});
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Executed upon failed connection to Wearable API
// e.g. when Android Wear App is missing
Log.e(TAG_CONNECTION, "Connection failed");
}
public void left(View view) {
Log.e(TAG_CONNECTION, "Trying to send message to: " + leftWatch);
if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect();
Wearable.MessageApi.sendMessage(mGoogleApiClient, leftWatch, START_ACTIVITY_PATH, new byte[0]).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e(TAG_CONNECTION, "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
return;
}
Log.e(TAG_CONNECTION, "Message successfully sent");
}
});
}
public void right(View view) {
Log.e(TAG_CONNECTION, "Trying to send message to: " + rightWatch);
if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect();
Wearable.MessageApi.sendMessage(mGoogleApiClient, rightWatch, START_ACTIVITY_PATH, new byte[0]).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e(TAG_CONNECTION, "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
return;
}
Log.e(TAG_CONNECTION, "Message successfully sent");
}
});
}
public void both(View view) {
Log.e(TAG_CONNECTION, "Trying to send message to: All currently connected watches");
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(#NonNull NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
List<Node> nodes = getConnectedNodesResult.getNodes();
for (final Node node : nodes) {
Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), START_ACTIVITY_PATH, new byte[0]).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e(TAG_CONNECTION, "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
return;
}
Log.e(TAG_CONNECTION, "Message successfully sent to: " + node.getId());
}
});
}
}
});
}
#Override
protected void onDestroy() {
mGoogleApiClient.disconnect();
super.onDestroy();
}
}
MyWearableListenerService
public class MyWearableListenerService extends WearableListenerService {
private static final String TAG_SIGNAL = "Signal";
private static final String TAG_CONNECTION = "Connection";
private static final String START_ACTIVITY_PATH = "/start_MainActivity";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.e(TAG_SIGNAL, "Message received: " + messageEvent.getPath());
if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) {
Intent intent = new Intent(this, MainWearActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else super.onMessageReceived(messageEvent);
}
#Override
public void onPeerConnected(Node node) {
Log.e(TAG_CONNECTION, "Peer connected: " + node.getId());
super.onPeerConnected(node);
}
#Override
public void onPeerDisconnected(Node node) {
Log.e(TAG_CONNECTION, "Peer disconnected: " + node.getId());
super.onPeerDisconnected(node);
}
}
AndroidManifest on the wear side
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="laufnavigation.awp.hska.de.androidwearapp">
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault">
<uses-library
android:name="com.google.android.wearable"
android:required="false" />
<activity android:name=".MainWearActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyWearableListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" />
</intent-filter>
</service>
</application>
</manifest>
I believe you should add a path prefix to you intent filter. In your case in the android manifest of your wearable:
<service
android:name=".MyWearableListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" android:pathPrefix:"/start_MainActivity" />
</intent-filter>
</service>
Let me know if it works!
Related
I'm trying to get the user's locations in real time using service. The problem happens when I try to do this below Android 8.0 because of the foreground service, I looked for several ways to do this but I didn't find any that work below Android 8.0.
Code that i used:
MainActivity
public class MainActivity extends AppCompatActivity {
#BindView(R.id.btn_start_tracking)
Button btnStartTracking;
#BindView(R.id.btn_stop_tracking)
Button btnStopTracking;
#BindView(R.id.txt_status)
TextView txtStatus;
public BackgroundService gpsService;
public boolean mTracking = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
final Intent intent = new Intent(this.getApplication(), BackgroundService.class);
this.getApplication().startService(intent);
this.getApplication().startForegroundService(intent);
this.getApplication().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
#OnClick(R.id.btn_start_tracking)
public void startLocationButtonClick() {
Dexter.withActivity(this)
.withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse response) {
gpsService.startTracking();
mTracking = true;
toggleButtons();
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response.isPermanentlyDenied()) {
openSettings();
}
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
#OnClick(R.id.btn_stop_tracking)
public void stopLocationButtonClick() {
mTracking = false;
gpsService.stopTracking();
toggleButtons();
}
private void toggleButtons() {
btnStartTracking.setEnabled(!mTracking);
btnStopTracking.setEnabled(mTracking);
txtStatus.setText( (mTracking) ? "TRACKING" : "GPS Ready" );
}
private void openSettings() {
Intent intent = new Intent();
intent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
String name = className.getClassName();
if (name.endsWith("BackgroundService")) {
gpsService = ((BackgroundService.LocationServiceBinder) service).getService();
btnStartTracking.setEnabled(true);
txtStatus.setText("GPS Ready");
}
}
public void onServiceDisconnected(ComponentName className) {
if (className.getClassName().equals("BackgroundService")) {
gpsService = null;
}
}
};
}
Background service class
public class BackgroundService extends Service {
private final LocationServiceBinder binder = new LocationServiceBinder();
private final String TAG = "BackgroundService";
private LocationListener mLocationListener;
private LocationManager mLocationManager;
private NotificationManager notificationManager;
private final int LOCATION_INTERVAL = 500;
private final int LOCATION_DISTANCE = 10;
#Override
public IBinder onBind(Intent intent) {
return binder;
}
private class LocationListener implements android.location.LocationListener {
private Location lastLocation = null;
private final String TAG = "LocationListener";
private Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
Log.i(TAG, "LocationChanged: "+location);
}
#Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + status);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate() {
Log.i(TAG, "onCreate");
startForeground(12345678, getNotification());
}
#Override
public void onDestroy() {
super.onDestroy();
if (mLocationManager != null) {
try {
mLocationManager.removeUpdates(mLocationListener);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
public void startTracking() {
initializeLocationManager();
mLocationListener = new LocationListener(LocationManager.GPS_PROVIDER);
try {
mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListener);
} catch (java.lang.SecurityException ex) {
// Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
// Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
public void stopTracking() {
this.onDestroy();
}
private Notification getNotification() {
NotificationChannel channel = new NotificationChannel("channel_01", "My Channel", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Notification.Builder builder = new Notification.Builder(getApplicationContext(), "channel_01").setAutoCancel(true);
return builder.build();
}
public class LocationServiceBinder extends Binder {
public BackgroundService getService() {
return BackgroundService.this;
}
}
}
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ac.myapp">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".maps"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:enabled="true"
android:name=".BootUpReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name=".BackgroundService"/>
</application>
</manifest>
I use quickblox for create video call
Start call work, but incoming service not work for opponent user
VideoActivity
public class VideoActivity extends E implements QBRTCClientSessionCallbacks,QBRTCClientVideoTracksCallbacks {
private int userid;
private Boolean isOutgoing,micE=true,vidE=true;
private QBRTCSurfaceView surfaceView,remoteview;
private MediaPlayer mp;
private QBRTCSession currentsession;
private QBMediaStreamManager mediaStreamManager;
private ImageView mic,video;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video);
userid=getIntent().getIntExtra("user", 1);
userid = 39753771;
isOutgoing=getIntent().getBooleanExtra("isoutgoing",false);
isOutgoing = true;
ProcessCalls();
InitSignalling();
if (isOutgoing) {
//CallUser();
SetCallerName(userid);
}
Log.i("errorCheck", "Nz: " + userid);
Log.i("errorCheck", "Na: " + isOutgoing);
if(getIntent().getBooleanExtra("service",false)){
Log.i("errorCheck", "x");
}
mic=(ImageView)findViewById(R.id.mic);
mic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (micE) {
micE = false;
AudioManage();
} else {
micE = true;
AudioManage();
}
}
});
video=(ImageView)findViewById(R.id.video);
video.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (vidE) {
vidE = false;
VideoManage();
} else {
vidE = true;
VideoManage();
}
}
});
surfaceView =(QBRTCSurfaceView)findViewById(R.id.localView);
surfaceView.setMirror(true);
surfaceView.requestLayout();
remoteview=(QBRTCSurfaceView)findViewById(R.id.opponentView);
remoteview.requestLayout();
}
private void SetCallerName(Integer callerID) {
TextView callerName=(TextView)findViewById(R.id.callername);
TextView callertime=(TextView)findViewById(R.id.callTime);
callerName.setText(callerID + " , You:");
if(isOutgoing){
callertime.setText("Calling...");
}
}
private void InitSignalling() {
final QBChatService chatService = QBChatService.getInstance();
Log.i("errorCheck", "ERR1: " + G.userQB);
chatService.login(G.userQB, new QBEntityCallback() {
#Override
public void onSuccess(Object result, Bundle params) {
Log.i("errorCheck", "R0: " + result);
Log.i("errorCheck", "R1: " + params);
chatService.getVideoChatWebRTCSignalingManager().addSignalingManagerListener(new QBVideoChatSignalingManagerListener() {
#Override
public void signalingCreated(QBSignaling qbSignaling, boolean createdLocally) {
Log.i("errorCheck", "Q1: " + qbSignaling);
Log.i("errorCheck", "Q2: " + createdLocally);
if (!createdLocally) {
QBRTCClient.getInstance(VideoActivity.this).addSignaling((QBWebRTCSignaling) qbSignaling);
}
}
});
QBRTCClient.getInstance(G.currentActivity).addSessionCallbacksListener((QBRTCSessionEventsCallback) G.currentActivity);
QBRTCConfig.setDebugEnabled(true);
QBRTCClient.getInstance(getApplicationContext()).prepareToProcessCalls();
Log.i("errorCheck", "chatService1: " + chatService);
if(G.userMobile.equals("09139479548")) {
CallUser();
}
}
#Override
public void onError(QBResponseException errors) {
Log.i("errorCheck", "E1: " + errors);
}
});
}
private void ProcessCalls() {
QBRTCClient.getInstance(this).prepareToProcessCalls();
}
private void CallUser() {
List<Integer> opponents = new ArrayList<Integer>();
opponents.add(userid);
Map<String, String> userInfo = new HashMap<>();
userInfo.put("key", "value");
QBRTCTypes.QBConferenceType qbConferenceType = QBRTCTypes.QBConferenceType.QB_CONFERENCE_TYPE_VIDEO;
QBRTCSession session = QBRTCClient.getInstance(G.currentActivity).createNewSessionWithOpponents(opponents, qbConferenceType);
session.addVideoTrackCallbacksListener(this);
session.startCall(userInfo);
Log.i("errorCheck", "QR1: " + session);
SetCallButtonsDialing(session,userInfo);
StartDialRinging();
}
#Override
public void onReceiveNewSession(QBRTCSession qbrtcSession) {
Log.i("errorCheck","x");
qbrtcSession.addVideoTrackCallbacksListener(this);
Map<String,String> userInfo = qbrtcSession.getUserInfo();
SetLayoutForReceiveCall(qbrtcSession,userInfo);
}
private void SetLayoutForReceiveCall(final QBRTCSession qbrtcSession,final Map<String, String> userInfo) {
final FrameLayout receive=(FrameLayout)findViewById(R.id.answerlayout);
receive.setVisibility(View.VISIBLE);
qbrtcSession.addVideoTrackCallbacksListener(this);
final ImageView calll=(ImageView)findViewById(R.id.answerCall);
calll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Accept incoming call
qbrtcSession.acceptCall(userInfo);
receive.setVisibility(View.GONE);
SetCallButtonsDialing(qbrtcSession, userInfo);
StartTimer();
if (mp != null && mp.isPlaying()) {
mp.stop();
}
}
});
findViewById(R.id.rejectcall).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
qbrtcSession.rejectCall(userInfo);
VideoActivity.this.finish();
if(mp!=null&&mp.isPlaying())
{
mp.stop();
}
}
});
}
#Override
public void onUserNoActions(QBRTCSession qbrtcSession, Integer integer) {
Toast.makeText(this, "no action by user", Toast.LENGTH_SHORT).show();
if(mp!=null&&mp.isPlaying())
{
mp.stop();
}
}
#Override
public void onSessionStartClose(QBRTCSession qbrtcSession) {
qbrtcSession.addVideoTrackCallbacksListener(this);
try {
qbrtcSession.getMediaStreamManager().setVideoCapturer(new QBRTCCameraVideoCapturer(this, null));
mediaStreamManager = qbrtcSession.getMediaStreamManager();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onUserNotAnswer(QBRTCSession qbrtcSession, Integer integer) {
Toast.makeText(this, "No answer", Toast.LENGTH_SHORT).show();
if(mp!=null&&mp.isPlaying())
{
mp.stop();
}
finish();
}
#Override
public void onCallRejectByUser(QBRTCSession qbrtcSession, Integer integer, Map<String, String> map) {
Toast.makeText(this, "Call rejected", Toast.LENGTH_SHORT).show();
if(mp!=null&&mp.isPlaying())
{
mp.stop();
}
finish();
}
#Override
public void onCallAcceptByUser(QBRTCSession qbrtcSession, Integer integer, Map<String, String> map) {
qbrtcSession.addVideoTrackCallbacksListener(this);
if(mp!=null&&mp.isPlaying())
{
mp.stop();
}
StartTimer();
}
#Override
public void onReceiveHangUpFromUser(QBRTCSession qbrtcSession, Integer integer, Map<String, String> map) {
if(mp!=null&&mp.isPlaying())
{
mp.stop();
}
Toast.makeText(this, "Call ended by user", Toast.LENGTH_SHORT).show();
finish();
}
#Override
public void onSessionClosed(QBRTCSession qbrtcSession) {
if(mp!=null&&mp.isPlaying())
{
mp.stop();
}
}
#Override
public void onLocalVideoTrackReceive(QBRTCSession qbrtcSession, QBRTCVideoTrack qbrtcVideoTrack) {
Log.i("errorCheck", "WW1: " + qbrtcSession);
qbrtcVideoTrack.addRenderer(new VideoRenderer(surfaceView));
surfaceView.setMirror(true);
surfaceView.requestLayout();
}
#Override
public void onRemoteVideoTrackReceive(QBRTCSession qbrtcSession, QBRTCVideoTrack qbrtcVideoTrack, Integer integer) {
Log.i("errorCheck", "WW2: " + qbrtcSession);
qbrtcVideoTrack.addRenderer(new VideoRenderer(remoteview));
mediaStreamManager = qbrtcSession.getMediaStreamManager();
remoteview.requestLayout();
}
public void StartDialRinging(){
try {
mp = MediaPlayer.create(getApplicationContext(), R.raw.beep);
mp.setLooping(true);
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
VideoCallService
public class VideoCallService extends Service implements QBRTCClientSessionCallbacks {
private Timer mTimer = null;
private Handler mHandler = new Handler();
public static final int notify = 300000;
public VideoCallService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
Log.wtf("service", "start");
if (mTimer != null) {
Log.wtf("service", "All ready started");
} else {
mTimer = new Timer(); //recreate new
mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify);
LoginChatService();
ProcessCalls();
InitSignalling();
QBRTCClient.getInstance(this).addSessionCallbacksListener(this);
}
}catch (Exception e){
Log.wtf("ex",""+e);
}
return START_NOT_STICKY;
}
private void InitSignalling() {
QBChatService.getInstance().getVideoChatWebRTCSignalingManager()
.addSignalingManagerListener(new QBVideoChatSignalingManagerListener() {
#Override
public void signalingCreated(QBSignaling qbSignaling, boolean createdLocally) {
if (!createdLocally) {
QBRTCClient.getInstance(VideoCallService.this).addSignaling((QBWebRTCSignaling) qbSignaling);
}
}
});
}
private void ProcessCalls() {
QBRTCClient.getInstance(this).prepareToProcessCalls();
}
#Override
public void onReceiveNewSession(QBRTCSession qbrtcSession) {
//DataHolder.getInstance().setServiceData(qbrtcSession,qbrtcSession.getUserInfo());
startActivity(new Intent(this,VideoActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("service",true));
}
}
Manifest
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service android:name=".VideoCallService" />
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.quickblox.sample.groupchatwebrtc" />
</intent-filter>
</receiver>
<service
android:name=".GcmPushListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name="com.quickblox.messages.services.gcm.QBGcmPushInstanceIDService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<meta-data android:name="com.quickblox.messages.TYPE" android:value="GCM" />
<meta-data android:name="com.quickblox.messages.SENDER_ID" android:value="1" />
<meta-data android:name="com.quickblox.messages.QB_ENVIRONMENT" android:value="DEVELOPMENT" />
After start Call, session created for opponent
This my log for user caller
I/org.webrtc.Logging: SurfaceViewRenderer: localView: onMeasure(). New size: 200x200
I/org.webrtc.Logging: EglRenderer: localView: setLayoutAspectRatio: 1.0
I/org.webrtc.Logging: EglRenderer: opponentView: setLayoutAspectRatio: 0.58536583
D/QBASDK: register network listener
D/QBASDK: Connected. Login to chat, currentUser JID: 39753009-65649, resource: android_ffffffff-ac04-0c2d-ffff-ffffd173e4c0
I/errorCheck: R0: null
I/errorCheck: R1: Bundle[{}]
D/RTCClient.: Added session CALLBACK listenerapp.x.y.VideoActivity#4288e7f8
I/errorCheck: chatService1: com.quickblox.chat.QBChatService#42f6b478
D/RTCClient.: Call createNewSessionWithOpponents[39753771]conference type=QBConferenceType{value='1'}
D/RTCClient.QBRTCSession: Create new session
I/errorCheck: Q1: com.quickblox.chat.QBWebRTCSignaling#43156ce0
I/errorCheck: Q2: true
D/RTCClient.: New signalling was added for participant39753771
D/RTCClient.QBRTCSession: Make new channel for oppoennt:39753771com.quickblox.videochat.webrtc.QBPeerChannel#42f23c00
D/RTCClient.QBRTCSession: isInitiator=true
D/RTCClient.QBRTCSession: ADD VideoTrackCallbacksListener app.x.y.VideoActivity#4288e7f8
D/RTCClient.QBRTCSession: startCall
D/RTCClient.PeerFactoryManager: Creating Peer connection factory
D/RTCClient.QBRTCSession.SessionWaitingTimers: Stop WaitTimer
But for opponent not set log ( not incoming notification or ... )
How can I solve this problem?
You may refer with this thread. Check the video-sample. There is implementation of opening IncomingCallFragment by receiving push in this sample. Also, if you have successful subscription, but do not receive pushes, you always can check the following:
Check certificates for pushes: Admin panel ->Push Notification ->Settings -> APNS, GCM etc.
Send push from Admin Panel - > Push notifications - > Send (link)
Also you can check Push Notifications Queue tab in Admin panel, there should be a log of your push. It will help you to understand what's going on with your devices.
Hope this helps!
I am trying to send messages between my phone and wearable using the Wearable message API. Both the phone(physical One plus one) and the smartwatch(physical sony smartwatch 3) will connect to each other. Sending a message also reports back as sent. But neither the Mobile nor the wearable Application's WearableServiceListener will respond to these messages.
I have checked:
ApplicationID
Package Names
Manifest
What else can i check to find the problem?
Thank you
public class MainActivityPhone extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private Node connectedPhone;
private static String WEAR_PATH = "/from_phone";
private final String TAG = MainActivityPhone.class.getSimpleName();
GoogleApiClient googleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Wearable.API)
.build();
googleApiClient.connect();
}
public void phoneButtonHandler(View view){
sendMessage();
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG,"connection suspended");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG,"connection failed");
}
#Override
public void onConnected(Bundle bundle) {
Wearable.NodeApi.getConnectedNodes(googleApiClient)
.setResultCallback(new ResultCallbacks<NodeApi.GetConnectedNodesResult>() {
#Override
public void onSuccess(#NonNull NodeApi.GetConnectedNodesResult nodes) {
for (Node node : nodes.getNodes()) {
if (node != null && node.isNearby()) {
connectedPhone = node;
Log.i(TAG, "Connected to " + connectedPhone.getDisplayName());
}
}
}
#Override
public void onFailure(#NonNull Status status) {
if (connectedPhone == null) {
Log.i(TAG, "not connected!");
}
}
});
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
googleApiClient.disconnect();
}
private void sendMessage(){
if(connectedPhone != null && googleApiClient != null) {
Wearable.MessageApi.sendMessage(googleApiClient, connectedPhone.getId(), WEAR_PATH, "alarm".getBytes()).setResultCallback(new ResultCallbacks<MessageApi.SendMessageResult>() {
#Override
public void onSuccess(#NonNull MessageApi.SendMessageResult sendMessageResult) {
Log.e(TAG, "message sent");
}
#Override
public void onFailure(#NonNull Status status) {
Log.e(TAG, "connection failed!" + status.getStatusMessage());
}
});
}
else{
Toast.makeText(this,"failed to send, no connection",Toast.LENGTH_SHORT).show();
}
}
.
<service android:name=".ListenerFromWear">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
</intent-filter>
</service>
and for both modules:
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "com.leon_wolf.bigpresenter.connectphoneandwatch"
minSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "1.0"
Change your service definition to be:
<service android:name=".ListenerFromWear">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:host="*" android:scheme="wear" />
</intent-filter>
</service>
You need to specify the wear scheme as detailed here:
https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService
Also make sure your Service extends WearableListenerService
I am trying to send a message from my mobile app to a service in the wearable app.
The message needs to be send from a BroadcastReceiver. In the BroadcastReceiver the message is sent successfully, at least that is what is said in the log, but the method onMessageReceive is not triggered.
I am not quite sure what the problem might be, I have the same applicationId in both build.gradle files, but packages names are different.
In mobile manifest the receiver has the following declaration:
<receiver android:name="com.app.mobile.NewAlarm"
android:exported="false">
<intent-filter>
<action android:name="com.example.android.support.wearable.notifications.ACTION_EXAMPLE" />
</intent-filter>
</receiver>
the BroadcastReceiver class:
public class TimeAlarm extends BroadcastReceiver {
public static final String TAP_ACTION_PATH = "/tap";
private static final String TAG = "NotificationReceiver";
public void onReceive(Context context, Intent paramIntent) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int cause) {
}
}).build();
mGoogleApiClient.connect();
sendMessage();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
private void getNodes() {
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(
new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
HashSet<String> results = new HashSet<String>();
for (Node node : getConnectedNodesResult.getNodes()) {
results.add(node.getId());
Log.d(TAG,node.getId().toString());
}
Log.d(TAG,results.toString());
sendMessageApi(results);
}
}
);
}
private void sendMessageApi(Collection<String> nodes) {
for (String node : nodes) {
Wearable.MessageApi.sendMessage(
mGoogleApiClient, node, TAP_ACTION_PATH, null).setResultCallback(
new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e(TAG, "ERROR: failed to send Message: " + sendMessageResult.getStatus());
} else {
Log.e(TAG, "Success!");
}
}
}
);
}
}
private void sendMessage() {
getNodes();
}
}
The WearableListenerService is declared this way in wear app manifest:
<service android:name=".DataLayerListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
and finally the DataLayerListenerService:
public class DataLayerListenerService extends WearableListenerService {
public static final String START_ACTIVITY_PATH = "/notice";
public static final String TAP_ACTION_PATH = "/tap";
private static final String TAG = "DataLayerListenerService";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
Log.d(TAG, "Message Received !!");
if (START_ACTIVITY_PATH.equals(messageEvent.getPath())) {
Log.d(TAG, "Message Received !!");
int vibeTime = 5000;
String strVibeTime = new String(messageEvent.getData());
if (!strVibeTime.equals("") && !strVibeTime.equals("0")) {
vibeTime = (Integer.parseInt(strVibeTime)) * 1000;
}
sleep(1000);
vibrator.vibrate(vibeTime);
} else if (TAP_ACTION_PATH.equals(messageEvent.getPath())) {
Log.d(TAG, "Tapping Received !!");
vibrator.cancel();
}
}
public synchronized void sleep(long msec) {
try
{
wait(msec);
}catch(InterruptedException e){
Log.e(TAG, e.getMessage());
}
}
}
You're trying to send the message before the client is connected, so getConnectedNodesResult.getNodes() is returning an empty list.
Try this instead:
public void onReceive(Context context, Intent paramIntent) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
sendMessage();
}
#Override
public void onConnectionSuspended(int cause) {
}
}).build();
mGoogleApiClient.connect();
}
I use estimote android sdk for becan detaction or scan but i did not get beacons and there list call. i setup my code according to Readme file shows on lib and complie code but not get becons.
https://github.com/Estimote/Android-SDK
private static final String ESTIMOTE_PROXIMITY_UUID = "B9407F30-F5F8-466E-AFF9-25556B57FE6D";
private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId", ESTIMOTE_PROXIMITY_UUID, null, null);
private BeaconManager beaconManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_signup);
beaconManager = new BeaconManager(SignupActivity.this);
// Should be invoked in #onCreate.
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region arg0, List<Beacon> beacons) {
Log.d("TAG", "Ranged beacons: " + beacons);
}
});
}
#Override
protected void onStart() {
super.onStart();
// Should be invoked in #onStart.
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
try {
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS);
} catch (RemoteException e) {
Log.e("TAG", "Cannot start ranging", e);
}
}
});
}
#Override
protected void onStop() {
super.onStop();
try {
beaconManager.stopRanging(ALL_ESTIMOTE_BEACONS);
} catch (RemoteException e) {
Log.e("TAG", "Cannot stop but it does not matter now", e);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
beaconManager.disconnect();
}
Change
private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId", ESTIMOTE_PROXIMITY_UUID, null, null);
to
private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId", null, null, null);
And also Change
beaconManager = new BeaconManager(SignupActivity.this);
// Should be invoked in #onCreate.
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region arg0, List<Beacon> beacons) {
Log.d("TAG", "Ranged beacons: " + beacons);
}
});
to
beaconManager = new BeaconManager(SignupActivity.this);
// Should be invoked in #onCreate.
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region arg0, List<Beacon> beacons) {
Log.d("TAG", "Ranged beacons: " + beacons.size());
}
});
Here you can see the size of near by beacons
Download jar file.
https://github.com/Estimote/Android-SDK
https://github.com/Estimote/Android-SDK/blob/master/EstimoteSDK/estimote-sdk-preview.jar
Mainifeast code.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.user.TempActivity"
android:configChanges="orientation|screenSize"
android:label="#string/app_name"
android:windowSoftInputMode="stateHidden|adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.estimote.sdk.service.BeaconService"
android:exported="false" >
</service>
</application>
</manifest>
// Example activity
public class TempActivity extends Activity {
private static final String ESTIMOTE_PROXIMITY_UUID = "B9407F30-F5F8-466E-AFF9-25556B57FE6D";
private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId", ESTIMOTE_PROXIMITY_UUID, null, null);
private BeaconManager beaconManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.temp_activity);
startBeaconDetectionService();
WebAsynk mWebAsynk= new WebAsynk();
mWebAsynk.execute(BEACON_WEB_SERVICE);
}
#Override
protected void onStart() {
super.onStart();
// Should be invoked in #onStart.
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
try {
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS);
} catch (RemoteException e) {
Log.e("TAG", "Cannot start ranging", e);
}
}
});
}
#Override
protected void onStop() {
super.onStop();
try {
beaconManager.stopRanging(ALL_ESTIMOTE_BEACONS);
} catch (RemoteException e) {
Log.e("TAG", "Cannot stop but it does not matter now", e);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
beaconManager.disconnect();
}
/**
* Beacon Detection Service response handle here
*/
private void startBeaconDetectionService(){
beaconManager = new com.estimote.sdk.BeaconManager(TempActivity.this);
beaconManager.setForegroundScanPeriod(2000,2000);
// Should be invoked in #onCreate.
beaconManager.setRangingListener(new com.estimote.sdk.BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region arg0, final List<Beacon> beacons) {
Log.d("TAG", "Ranged beacons: " + beacons);
Log.e("TAG", "Ranged beacons: " + beacons);
runOnUiThread(new Runnable() {
#Override
public void run() {
int test=0;
if(beacons.size()<=0){
Toast.makeText(TempActivity.this, "No beacon found",
Toast.LENGTH_SHORT).show();
}else{
for (int i = 0; i < beacons.size(); i++) {
String beac=beacons.get(i).getProximityUUID();
String macAddress=beacons.get(i).getMacAddress();
int major=beacons.get(i).getMajor();
int minor=beacons.get(i).getMinor();
int rssi=beacons.get(i).getRssi();
// Filter for right beacon detection
Toast.makeText(TempActivity.this, "I found a beacon with UUID; "+beac+" M-"+major,
Toast.LENGTH_SHORT).show();
}
}
}
});
}
});
}
}