I want to send message from phone to wear (android watch). I dont want to send Notification. So I am using MessageApi to send the message. For some reason, my watch is not getting it. I used the same code in reverse order (wear to mobile), it works perfectly fine. From the phone end, its correctly recognizing the watch and display its name but in watch the message is not reached (onMessageReceived is not called).
Any help would be greatly appreciated.
The code in Mobile to send data:
private void resolveNode() {
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient)
.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(#NonNull NodeApi.GetConnectedNodesResult connectedNodes) {
for(Node connectedNode : connectedNodes.getNodes()) {
mNode = connectedNode;
Log.d(TAG,"Message Sender connected node"+mNode.getDisplayName());
sendMessage("Hello Hello");
}
}
});
}
private void sendMessage(final String message) {
if(mGoogleApiClient != null &&
mGoogleApiClient.isConnected() &&
mNode != null) {
Log.d(TAG,"Message is going to be sent to watch");
Wearable.MessageApi.sendMessage(mGoogleApiClient,
mNode.getId(),
"/mobile_data",
message.getBytes())
.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(#NonNull MessageApi.SendMessageResult sendMessageResult) {
if(sendMessageResult.getStatus().isSuccess()) {
Log.e(TAG,"Message Succesfully sent to watch=>"+message);
} else {
Log.e(TAG,"Message FAILED TO BE SENT to watch=>"+message);
}
}
});
}
}
Code on the wearable side
public class MessageReceiver extends WearableListenerService {
private static final String TAG = "MessageReceiver";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
Log.d(TAG,"pathpathpathpath");
}
}
Registered my Message Receiver in AndroidManifest of wearable side
<service android:name=".MessageReceiver">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/mobile_data"
android:scheme="mobile" />
</intent-filter>
</service>
Related
public class ReadNotifications extends NotificationListenerService {
Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
for (StatusBarNotification sbm : ReadNotifications.this.getActiveNotifications()) {
String title = sbm.getNotification().extras.getString("android.title");
String text = sbm.getNotification().extras.getString("android.text");
String package_name = sbm.getPackageName();
Log.v("Notification title is:", title);
Log.v("Notification text is:", text);
Log.v("Package Name is:", package_name);
}
}
}
<service android:name=".ReadNotifications"
android:label="#string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
Previously I was able to get NotificationListenerService to work, but now I can't figure out why it isn't working. I've tried running it as it is, trying to start the service from the main activity, creating notifications from the same app, sending notifications from another app, changing emulators, but no logs are being sent.
You should grant the special permission in the android settings, you can open them like this (requires API level 22):
if (!NotificationManagerCompat.getEnabledListenerPackages(this).contains(getPackageName())) {
startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
}
Data sent through Data API from mobile app is not received in ondatachange of listenerservice in wearable emulator.I can send a notification though, which indicates both are connected.Below my code,
DataAPI call (mobile)
PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(SharedConstants.START_FREE_RUN);
putDataMapRequest.getDataMap().putString(SharedConstants.PROGRAM_TYPE,totalCountUpTimer);
PutDataRequest request = putDataMapRequest.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, request)
.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
#Override
public void onResult(DataApi.DataItemResult dataItemResult) {
if (!dataItemResult.getStatus().isSuccess()) {
Log.e(TAG, "buildWatchOnlyNotification(): Failed to set the data, "
+ "status: " + dataItemResult.getStatus().getStatusCode());
} else {
Log.d(TAG,"SuccessFully sent notification");
}
}
});
After which I am getting "successfully sent" log message.
Below is ListenerService in wear,
public class ListenerService extends WearableListenerService {
private static final String TAG = ListenerService.class.getSimpleName();
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
super.onDataChanged(dataEvents);
Log.d(TAG, "dchanged" + dataEvents);
}
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.v(TAG, "onMessageReceivedWear: " + messageEvent);
if (SharedConstants.START_FREE_RUN.equals(messageEvent.getPath())) {
// Request for this device open the attraction detail screen
// to a specific tourist attraction
String Distance = new String(messageEvent.getData());
Log.d("ListenerService",Distance);
}
}
}
and my service declaration in Android manifest,
<service android:name=".services.ListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="*" />
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Did not add any permissions in wearable module.Do suggest.
Use android:pathPattern=".*" instead of android:pathPrefix="*"
I have looked more than 2 hours for a solution, but no chance.
I have installed parse into my application android and I have installed it in my phone (android s4 mini, using wifi currently).
Here is how my parse is setup in my project:
Parse.initialize(mInstance, App.parseAppId, App.parseAppKey);
// Specify an Activity to handle all pushes by default.
PushService.setDefaultPushCallback(mInstance, MainActivity.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
I see that parse logged my installation
http://awesomescreenshot.com/0865kofmd9
But when I send a push, my app crash "Unfortunately Application has stopped working"
Here is my androidmanifest:
http://pastebin.com/UySbvP8P
Any advise please?
Thanks
Please try to replace the default parse push receiver with this: :
remove:
PushService.setDefaultPushCallback(mInstance, MainActivity.class);
AndroidManifest.xml:
<receiver
android:name="ParsePushReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE"/>
<action android:name="com.parse.push.intent.DELETE"/>
<action android:name="com.parse.push.intent.OPEN"/>
</intent-filter>
</receiver>
ParsePushReceiver.java:
import android.content.Context;
import android.content.Intent;
import com.parse.ParsePushBroadcastReceiver;
public class ParsePushReceiver extends ParsePushBroadcastReceiver {
#Override
public void onPushOpen(Context context, Intent intent) {
Intent newIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
newIntent.putExtras(intent.getExtras());
context.startActivity(newIntent);
}
}
App.java
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, parseAppId, parseAppKey);
if (ParseInstallation.getCurrentInstallation() != null && ParseInstallation.getCurrentInstallation().getCreatedAt() == null) {
ParseInstallation.getCurrentInstallation().saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e != null) {
//track error
}
}
});
}
mInstance = this;
if (isOnline()) {
makeJsonObjectRequest();
}
}
I want to send message from Watch to my phone.
I can send a message using MessageAPI to my phone, and the result is successful too by looking at the log message. However, the message is not received on the phone's side.
Wearable.MessageApi.sendMessage(mGoogleApiClient, mNode.getId(),
MY_DATA_PATH, null).setResultCallback(
new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(
MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.d("TAG",
"sendMessageResult NOT successful");
} else {
Log.d("TAG",
"sendMessageResult successful");
}
}
});
However, on my phone's listener service, onMessageReceived and onPeerConnected are not called.
public class ListenerServiceFromWear extends WearableListenerService {
private static final String My_DATA_PATH = "/my-data-path";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.d("TAG", "onMessageReceived");
/*
* Receive the message from wear
*/
if (messageEvent.getPath().equals(MY_DATA_PATH)) {
Intent startIntent = new Intent(this, ContactActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startIntent);
}
}
#Override
public void onPeerConnected(Node node){
Log.d("TAG", "onPeerConnected");
}
}
Here is the phone app's Manifest declaration for the ListenerService:
<service android:name="com.mobile.rbc.services.ListenerServiceFromWear" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
Found the answer.
The problem is that the Android Wear's apk is signed and the Phone's apk is not signed.
I was debugging it using Eclipse, that's why the phone's app is not signed.
Usually you will see something in your log if the two apks are not signed with the same key.
ensureBindStarted: app does not match record's app key: AppKey
Im trying to subscribe the notification+control sample to Google Cloud Messaging in order to recieve push notification directly to the watch.
i have add the permisions:
<permission android:name="com.example.myapp.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.sonymobile.smartconnect.extension.notificationsample.permission.C2D_MESSAGE" />
Added the receiver update and service:
<receiver android:name=".MyReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.sonymobile.smartconnect.extension.notificationsample" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.sonymobile.smartconnect.extension.notificationsample" />
</intent-filter>
</receiver>
And implemented the MyReceiver class with methods as in this link
The onReceive method is just called the first time it register. It gives me back the tokenID but neither it recieve the notification nor is called when I activate the sample app.
I've tested the Sender Server with a normal Android app and it sends the notification succesfully
Any hint on sending push notifications to the smartwatch?
Thx!
UPDATE:Now i have move forward in my issue, I've changed the MyReceiver.java to:
public class MyReceiver extends GCMBroadcastReceiver{
#Override
protected String getGCMIntentServiceClassName(Context context)
{
return RemoteNotificationIntentService.class.getName();
}
}
And I have implemented the RemoteNotificationIntentService class:
public class RemoteNotificationIntentService extends GCMBaseIntentService {
public static enum RemoteNotificationFields{
RN_TITLE, RN_BODY, RN_TICKER, RN_SOUND, RN_SMALL_ICON, RN_LARGE_ICON, RN_LED_COLOR_ARGB
};
private static HashMap FIELD_MAP;
private static final String APPLICATION_NAME = "Appverse Bank 4 Sw2";
public RemoteNotificationIntentService(String senderId) {
super(senderId);
System.out.println("init");
// TODO Auto-generated constructor stub
}
public RemoteNotificationIntentService() {
super("PUSH_NOTIFICATION_SERVICE");
// TODO Auto-generated constructor stub
System.out.println("init");
}
private HashMap<String, String> storeIntentExtras(Context context, Intent intent) {
try{
HashMap<String, String> returnValue = new HashMap<String, String>();
HashMap<String, String> JSONSerializable = new HashMap<String, String>();
for(String sFieldName:intent.getExtras().keySet()){
if(FIELD_MAP.containsKey(sFieldName)){
String sFieldType = FIELD_MAP.get(sFieldName);
returnValue.put(sFieldType, intent.getStringExtra(sFieldName));
JSONSerializable.put(sFieldType, intent.getStringExtra(sFieldName));
}else{
JSONSerializable.put(sFieldName, intent.getStringExtra(sFieldName));
}
}
//fill mandatory fields
if(!returnValue.containsKey(RemoteNotificationFields.RN_TITLE.toString())||returnValue.get(RemoteNotificationFields.RN_TITLE.toString()).trim().equals("")){returnValue.put(RemoteNotificationFields.RN_TITLE.toString(), APPLICATION_NAME);}
if(!returnValue.containsKey(RemoteNotificationFields.RN_TICKER.toString())||returnValue.get(RemoteNotificationFields.RN_TICKER.toString()).trim().equals("")){returnValue.put(RemoteNotificationFields.RN_TICKER.toString(), returnValue.get(RemoteNotificationFields.RN_TITLE.toString()));}
if(!returnValue.containsKey(RemoteNotificationFields.RN_SMALL_ICON.toString())||returnValue.get(RemoteNotificationFields.RN_SMALL_ICON.toString()).trim().equals("")){returnValue.put(RemoteNotificationFields.RN_SMALL_ICON.toString(), "icon");}
if(!returnValue.containsKey(RemoteNotificationFields.RN_LED_COLOR_ARGB.toString())||returnValue.get(RemoteNotificationFields.RN_LED_COLOR_ARGB.toString()).trim().equals("")){returnValue.put(RemoteNotificationFields.RN_LED_COLOR_ARGB.toString(), String.valueOf(Color.BLUE));}
JSONSerializable = null;
return returnValue;
}catch(Exception ex){}
return null;
}
#Override
protected void onMessage(Context context, Intent intent) {
try{
System.out.println("message!!!");
}catch(Exception ex){/*CANNOT LOG CAUSE CALLING LOGGER WILL PROMPT NULL POINTER EXCEPTION*/}
}
#Override
protected void onRegistered(Context context, String registrationId) {
try{
System.out.println("Register K");
}catch(Exception ex){
System.out.println("onRegistered "+ex.getMessage());
}
}
#Override
protected void onUnregistered(Context context, String registrationId) {
try{
System.out.println("Unregister K");
} catch(Exception ex){
System.out.println("onUnregistered "+ex.getMessage());
}
}
#Override
protected void onError(Context context, String error) {
System.out.println("error");
}
}
but it doesnt enter in any method this method and i get this message:
V/GCMBroadcastReceiver(4052): onReceive: com.google.android.c2dm.intent.RECEIVE
V/GCMBroadcastReceiver(4052): GCM IntentService class: com.sonymobile.smartconnect.extension.notificationsample.RemoteNotificationIntentService
V/GCMBaseIntentService(1825): Acquiring wakelock
UPDATE 2
I finnally achieve to get the data in my class, I need to add the service to the manifest
In your normal Android app are you able to receive the C2DM messages successfully? Receiving C2DM notifications should be the same whether you are creating a standard Android app or a Control extension for SW2. The only difference is that for the SW2 after you receive the C2DM notification you then add it to the Content Provider for SW2 to push the notification from your phone to the watch.