Android Wear: Custom Page on Notification - android

I'm very new to Android Wear (development). I started reading and implementing the documentation.
However I'm not sure if what I want to implement is "überhaupt" possible.
I can attach custom "actions" on the push notifications I receive, but it seems it can only open a phone-activity. Why can't I open a wear-activity?
The push notifications contains text, which is initially displayed, and data about a soccer match (second page?). I want to display the names of the teams and the score without an intervention of the phone.
So is it possible?
Plus what is the default behaviour? Do I attach this to an action or via an extra page on the notification?
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification_icon3)
.setContentTitle(this.getString(R.string.notifications_title))
.setContentText(message)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentIntent(matchDetailPendingIntent)
.setAutoCancel(true)
.extend(new NotificationCompat.WearableExtender()
.addPage(CustomDesignedPage) //Is this possible?
.addAction(action)
.setBackground(BitmapFactory.decodeResource(getResources(), R.drawable.soccer_background_big))
);
EDIT
Looking at the Messenger wear-app it seems possible?
The second screen shows a list of messages for example.

I was having the same problem. My solution was to implement an Activity and add to this activity the custom layout. Follow this step.
Step 1: Create a custom layout in your wear module. Example: customlayout.xml
Step 2: Create an Activity in the wear module:
public class WearNotificationActivity extends Activity{
private ImageView mSomeButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.customlayout);
mSomeButton= (ImageView) this.findViewById(R.id.somebutton);
mSomeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//do something here
}
});
}
}
Step 3. Send the data you want from your phone to your wear:
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private GoogleApiClient mGoogleApiClient;
private Button mSomeButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
mSomeButton=(Button) findViewById(R.id.somebutton);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(AppIndex.APP_INDEX_API)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mSomeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
sendToWear("title","description");
}
});
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
if(!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if(mGoogleApiClient!=null) {
mGoogleApiClient.disconnect();
}
}
public void sendToWear(String title, String description){
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/wear");
putDataMapReq.getDataMap().putString("title", title);
putDataMapReq.getDataMap().putString("description", description);
Wearable.DataApi.putDataItem(mGoogleApiClient, putDataRequest);
}
}
Step 4. Receive the data in your wear and make the notification. For do this you have to create a class in the wear module that extends for WearableListenerService and add this class to your wear manifest.
public class NotificationUpdateService extends WearableListenerService
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
ResultCallback<DataApi.DeleteDataItemsResult> {
private GoogleApiClient mGoogleApiClient;
#Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent dataEvent : dataEvents) {
if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
DataItem item = dataEvent.getDataItem();
if (item.getUri().getPath().compareTo("/wear") == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
String title = dataMap.getString("title");
String description=dataMap.getString("description");
buildWearableOnlyNotification(title, description)
}
} else if (dataEvent.getType() == DataEvent.TYPE_DELETED) {
}
}
}
/**
* Builds a simple notification on the wearable.
*/
private void buildWearableOnlyNotification(String title, String content) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVibrate(new long[]{10, 10, 10, 10, 10})
.setContentTitle(title)
.setContentText(content);
Intent notificationIntent = new Intent(this, WearNotificationActivity.class);
PendingIntent pendingNotificationIntent =
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder secondpage =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.extend(new NotificationCompat.WearableExtender()
.setDisplayIntent(pendingNotificationIntent)
.setCustomSizePreset(NotificationCompat.WearableExtender.SIZE_FULL_SCREEN)
);
mNotificationBuilder = new NotificationCompat.WearableExtender()
.addPage(secondpage.build()).extend(builder);
Notification notification=mNotificationBuilder.build();
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.notify(Constants.WATCH_ONLY_ID, notification);
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
And in your manifest:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault" >
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".WearNotificationActivity"
android:exported="true"
android:allowEmbedded="true"
android:taskAffinity=""
android:theme="#android:style/Theme.DeviceDefault.Light"
>
</activity>
<service android:name=".NotificationUpdateService">
<intent-filter>
<action
android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
</application>
Finally you need to add all the dependencies in your phone and wear gradle.
Phone:
compile 'com.google.android.gms:play-services-wearable:7.5.0'
compile 'com.android.support:support-v4:23.1.0'
wearApp project(':wearmodule')
Wear:
compile 'com.google.android.support:wearable:1.3.0'
provided 'com.google.android.wearable:wearable:+'
compile 'com.google.android.gms:play-services-wearable:8.1.0'
I hope this was useful to you.

Related

Service not starting in Android from AlarmManager after app is closed

Can anyone please correct my approach or suggest me the right ways for doing it.I have tried using broadcast receivers in place of services but that approach is not working for it.i.e I used getBroadcast() in place of getService() but didnt work.
It is working when the app is not closed from the application window but as soon as it is closed , the phone doesnt show notifications and ring as it was working in the case when the app wasn't closed.
MainActivity.class
`public class MainActivity extends AppCompatActivity {
TimePicker timePicker;
Button button;
AlarmManager alarmManager;
PendingIntent alarmIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timePicker = findViewById(R.id.timePicker);
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Calendar calendar = Calendar.getInstance();
if (Build.VERSION.SDK_INT >= 23) {
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
timePicker.getHour(),
timePicker.getMinute(),
0
);
} else {
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
timePicker.getCurrentHour(),
timePicker.getCurrentMinute(),
0
);
}
Intent intent = new Intent(MainActivity.this,MyIntentService.class);
//This is the intent which will be fired
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = PendingIntent.getService(getApplicationContext(), 0, intent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
Log.e("TAG:","AlarmSet.");
// Log is showing the right statement i.e the alarm was set but it wasnt triggered when the app was closed from the application window
}
});
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onPause() {
super.onPause();
Log.e("TAG","OnPause.");
}
#Override
protected void onStop() {
super.onStop();
Log.e("TAG","OnStop.");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.e("TAG","OnDestroy.");
}
}`
IntentService.class
`public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Log.e("TAG", "Starting service for notification and song");
Random random = new Random();
final Notification notification = new NotificationCompat.Builder(getApplicationContext(), "notify")
.setContentTitle("New Notification")
.setContentText("TIme for task.")
.setSmallIcon(R.mipmap.ic_launcher_round)
.setPriority(Notification.PRIORITY_MAX)
.build();
final NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(random.nextInt(), notification);
MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);
mediaPlayer.start();
}
}`
Manifest file
`
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyIntentService"
android:enabled="true"
android:exported="true" />
</application>
</manifest>`

Oreo Scheduling a Notification in an hour

In Android Oreo, I'm trying to schedule notifications at known future times. I wrote a small piece of code to test if I can schedule a notification in an hour when the app might be closed. When I try to do this, nothing happens. I really appreciate the help.
public class MainActivity extends AppCompatActivity {
private NotificationManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NotificationChannel notificationChannel = new NotificationChannel("default",
"primary", NotificationManager.IMPORTANCE_DEFAULT);
manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
Intent notifyIntent = new Intent(this, MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
long milisInFuture = 1000 * 60 * 60;
alarmManager.set(AlarmManager.RTC_WAKEUP, milisInFuture, pendingIntent);
}
public class MyNewIntentService extends JobIntentService {
#Override
protected void onHandleWork(#NonNull Intent intent) {
Notification notification = new Notification.Builder(getApplicationContext(), "default")
.setContentTitle("title")
.setContentText("body")
.setSmallIcon(android.R.drawable.stat_notify_chat)
.setAutoCancel(true)
.build();
manager.notify(123, notification);
}
}
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyNewIntentService.class);
context.startService(intent1);
}
}
}
Here is the manifest if that helps.
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MainActivity$MyNewIntentService"
android:permission="android.permission.BIND_JOB_SERVICE"></service>
</application>
</manifest>
UPDATE:
Don't forget to add the receiver in the manifest xml file.
For this question:
Add in AndroidManifest.xml inside application tag:
<receiver android:name=".MyReceiver" />
Example:
I am keeping this example, it updates the notification from Broadcast Receiver class.
Create a broadcast receiver class as shown, (Don't forget to add the receiver in the manifest xml file)
public class NotificationUpdate extends BroadcastReceiver {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceive(Context context, Intent intent) {
//NEED A RESCHEDULE?
updateNotification(context);
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void updateNotification(Context context){
Notification notification = new Notification.Builder(context.getApplicationContext(), "default")
.setContentTitle("title")
.setContentText("body")
.setSmallIcon(android.R.drawable.stat_notify_chat)
.setAutoCancel(true)
.build();
NotificationManager manager=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
if(manager!=null) manager.notify(123, notification);
}
}
Example Call from an Activity:
public class MainActivity extends AppCompatActivity {
final long intervalPeriod=60*1000;
AlarmManager mAlarmManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NotificationChannel notificationChannel = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel = new NotificationChannel("default",
"primary", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) manager.createNotificationChannel(notificationChannel);
mAlarmManager=(AlarmManager)getApplicationContext().getSystemService(ALARM_SERVICE);
PendingIntent intent=PendingIntent.getBroadcast(getApplicationContext(),1234,
new Intent(getApplicationContext(),NotificationUpdate.class),0);
mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+intervalPeriod, intent);
}
}

firebase notification not showing in snackbar while app closed android

i want to show firebase push notification(sending firebase console) in activity's snackbar by broadcast receiver which i get from FirebaseMessagingService but i am unable to show.please help me.
Manifest:
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
firebase message service:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if(remoteMessage.getData().size()>0){
Log.v("Message data", remoteMessage.getData().toString());
}
if(remoteMessage.getNotification()!=null){
Log.v("MessageNotification", remoteMessage.getNotification().getBody().toString());
}
if(remoteMessage!=null){
sendNotification(remoteMessage.toString());
}
}
private void sendNotification(String messageBody){
Intent intent=new Intent(this,NotificationShowActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("FireBaseNotification",messageBody);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.notification_icon)
.setContentTitle("Notification")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
notificationShow Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification_show);
linearLayout=(RelativeLayout)findViewById(R.id.activity_notification_show);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver,new IntentFilter(MyFirebaseMessagingService.NOTIFICATION_SERVICE));
}
//broadcastReceiver
private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message=intent.getStringExtra("FireBaseNotification");
if(message!=null){
Toast.makeText(NotificationShowActivity.this,message,Toast.LENGTH_LONG).show();
}
}
};
}
To catch FCM messages in background your should use receiver, not service.
public class NotificationsReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//handle your data
abortBroadcast(); //stop sending this broadcast to other receivers.
}
}
In your manifest (important - set priority to 999, to be first in receivers queue):
<receiver
android:name=".fcm.NotificationsReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter android:priority="999">
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>

AltBeacon doesn't detect beacon when app is in background

After a lot of tests, both on Eclipse and Android Studio, we cannot understand why our app cannot start the scan from the Application Class.
Beacons are detected only when I start the scan from the button in MainActivity (didEnterRegion is properly called in ApplicationClass and I see the scanning in progress in the logCat) but if I don't let the scan start from the MainActivity with
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.bind(MainActivity.this);
it doesn't start at all.
In this case in the logCat nothing appears.
I read everything possible, and also try to launch the project on Android Studio but the same problem occurs.
Does anyone see what I'm missing? Should I do something else to let the scan start directly form the ApplicationClass?
Here is the code:
Project properties
target=Google Inc.:Google APIs:18
android.library.reference.1=../android-beacon-library
manifestmerger.enabled=true
android.library=false
Manifest
<!-- language: lang-xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pstm.testbeacon"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="18"
android:targetSdkVersion="23" />
<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_WIFI_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name="com.pstm.testbeacon.ApplicationClass">
<activity
android:launchMode="singleInstance"
android:name="com.pstm.testbeacon.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Application Class
public class ApplicationClass extends Application implements BootstrapNotifier, BeaconConsumer {
private static final String TAG = "Demo1";
private RegionBootstrap regionBootstrap;
private BeaconManager beaconManager;
int contRange = 0;
Region regionRange = new Region("apr", null, null, null);
#Override
public void onCreate()
{
super.onCreate();
initSingletons();
}
protected void initSingletons()
{
BeaconManager.setsManifestCheckingDisabled(true);
Log.d(TAG, "App started up");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.bind(this);
}
#Override
public void onBeaconServiceConnect() {
// TODO Auto-generated method stub
beaconManager.setBackgroundBetweenScanPeriod(1000l);
beaconManager.setBackgroundScanPeriod(3000l);
beaconManager.setBackgroundMode(true);
try {
beaconManager.updateScanPeriods();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// beaconManager.getBeaconParsers().add(new BeaconParser().
// setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22- 23,p:24-24"));
Region region = new Region("apr", null, null, null);
regionBootstrap = new RegionBootstrap(this, region);
}
#Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
// TODO Auto-generated method stub
}
#Override
public void didEnterRegion(Region arg0) {
// TODO Auto-generated method stub
showNotification(
"Enter in Beacon area",
"Thanks");
}
#Override
public void didExitRegion(Region arg0) {
// TODO Auto-generated method stub
showNotification(
"Exit From Beacon",
"Thanks");
}
public void showNotification(String title, String message) {
Intent notifyIntent = new Intent(this, MainActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Random random = new Random();
int n = random.nextInt(9999 - 1000) + 1000;
PendingIntent pendingIntent = PendingIntent.getActivities(this, n,
new Intent[] { notifyIntent }, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.build();
notification.defaults |= Notification.DEFAULT_SOUND;
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(n, notification);
}
}
MainActivity
public class MainActivity extends Activity implements BeaconConsumer {
private BeaconManager beaconManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.bind(MainActivity.this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBeaconServiceConnect() {
}
}

onDataChanged() not being called on android wear

I'm trying to use Data Items to send a few strings through to my wear, but my wear never seems to receive any signal, because onDataChanged() is never called. I even set a time stamp to ensure the data is always different whenever it is sent.
Is there a specific way I have to install the app onto both devices to get it to work? I'm just clicking run and selecting my phone, then switching modules and doing the same for my wear device.
Here is the code from my main activity on my phone:
public class HomeActivity extends Activity{
public static String TAG = "HomeActivity";
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.home_view);
Button mButton = (Button) findViewById(R.id.send_button);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendData();
}
});
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
}).addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}).addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
}
private void sendData(){
if (mGoogleApiClient!=null){
return;
}
final PutDataMapRequest putRequest = PutDataMapRequest.create("/SAMPLE");
final DataMap map = putRequest.getDataMap();
map.putInt("color", Color.RED);
map.putLong("date", new Date().getTime());
Wearable.DataApi.putDataItem(mGoogleApiClient, putRequest.asPutDataRequest());
}
}
And here is the code on my wearable:
public class LayoutFaceService extends CanvasWatchFaceService implements DataApi.DataListener{
#Override
public void onCreate(){
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected");
Wearable.DataApi.addListener(mGoogleApiClient, LayoutFaceService.this);
}
#Override
public void onConnectionSuspended(int i) {
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
})
.build();
mGoogleApiClient.connect();
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_DELETED) {
Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
} else if (event.getType() == DataEvent.TYPE_CHANGED) {
Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
}
}
}
And my wear manifest :
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<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" >
<service
android:name=".LayoutFaceService"
android:label="#string/my_digital_name"
android:permission="android.permission.BIND_WALLPAPER" >
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/watch_face" />
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="#drawable/preview_digital" />
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="#drawable/preview_digital_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
In sendData(), your conditional seems to be incorrect; mGoogleApiClient != null is true so you exit right there. Address that and see whether you can get any further; there might be other issues but that is the first obvious one. If that didn't completely fix your issue, then make sure you also include the manifest on your phone in your post.

Categories

Resources