Mobile - Activity
public class TestActivity extends Activity implements DataApi.DataListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private GoogleApiClient mGoogleApiClient;
Button syncBtn;
static int click = 0;
#Override
protected void onStart()
{
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onPause()
{
super.onPause();
mGoogleApiClient.disconnect();
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
//mGoogleApiClient.connect();
syncBtn = (Button) findViewById(R.id.syncBtn);
syncBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
if(mGoogleApiClient.isConnected())
{
PutDataMapRequest mapRequest = PutDataMapRequest.create(Constants.RUN_UPDATE_NOTIFICATION);
mapRequest.getDataMap().putDouble(Constants.NOTIFICATION_TIMESTAMP, System.currentTimeMillis());
mapRequest.getDataMap().putString(Constants.NOTIFICATION_TITLE, "This is a Title");
mapRequest.getDataMap().putString(Constants.NOTIFICATION_CONTENT, "This is a text with some, notification, see click: "+click++);
PutDataRequest request = mapRequest.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, request).setResultCallback(new ResultCallback<DataApi.DataItemResult>()
{
#Override
public void onResult(DataApi.DataItemResult dataItemResult)
{
if (dataItemResult.getStatus().isSuccess())
{
System.out.println(" syncing successful...."+dataItemResult.getStatus());
}
else
{
System.out.println(" syncing failed.."+dataItemResult.getStatus());
}
}
});
}
else
{
System.out.println("not connected....");
}
}
});
}
#Override
public void onConnected(Bundle bundle)
{
}
#Override
public void onConnectionSuspended(int i)
{
}
#Override
public void onDataChanged(DataEventBuffer dataEventBuffer)
{
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult)
{
}
}
Getting output from Mobile - activity -
System.outīš syncing successful....Status{statusCode=SUCCESS, resolution=null}
But it show no response on Wear - activity(Want to show something on android wear that device has synced).
Below is the code for Wear - activity
public class NotificationUpdateService extends WearableListenerService{
private int notificationId = 001;
#Override
public void onDataChanged(DataEventBuffer dataEvents)
{
super.onDataChanged(dataEvents);
System.out.println("****** ");
for(DataEvent dataEvent: dataEvents)
{
if(dataEvent.getType() == DataEvent.TYPE_CHANGED)
{
DataMap dataMap = DataMapItem.fromDataItem(dataEvent.getDataItem()).getDataMap();
String title = dataMap.getString("title");
String content = dataMap.getString("content");
System.out.println("title: "+title+" content: "+content);
sendNotification(title, content);
}
}
}
private void sendNotification(String title, String content)
{
Intent viewIntent = new Intent(this, MainActivity.class);
PendingIntent pendingViewIntent = PendingIntent.getActivity(this, 0, viewIntent, 0);
// this intent will be sent when the user swipes the notification to dismiss it
/* Intent dismissIntent = new Intent(Constants.ACTION_DISMISS);
PendingIntent pendingDeleteIntent = PendingIntent.getService(this, 0, dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT);*/
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(content)
.setContentIntent(pendingViewIntent);
//.setDeleteIntent(pendingDeleteIntent)
Notification notification = builder.build();
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
notificationManagerCompat.notify(notificationId++, notification);
}}
Android manifest.xml - Wear
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.speedometer" >
<uses-feature android:name="android.hardware.type.watch" />
<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>
<service
android:name=".NotificationUpdateService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
</application></manifest>
Below is the Android manifest for Mobile
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.speedometer" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".LocationActivity"
android:label="#string/title_activity_location" >
</activity>
<activity
android:name=".TestActivity"
android:label="#string/title_activity_test" >
</activity>
</application></manifest>
You have the line "mGoogleApiClient.connect();" commented out and therefor are not guaranteed to have usable access to the play services WearableAPI
Additionally there are two main reasons why onDataChanged won't be triggered on an android wear device 1) The DataItem you are "putting" hasn't been changed since the last time you put it into the DataLayer. Try adding a timestamp to avoid this issue for debugging purposes. 2) The package name and signature are not identical on the wear apk and mobile apk. Do all you can to ensure these are identical on both modules.
Make sure both the wearable and handheld app modules have the same package name and version number. Also check the applicationId , versionName and versionCode in build.gradle files on both the wearable and handheld app modules of your project if you are building with Gradle.
Related
I am trying to show notification at specific date I am using alarm manager and broadcast receiver to show notifications but the problem is notification works only when app is open and when app is closed notification does not show. Below is my code:
Reminder.java
public class Reminder extends AppCompatActivity {
long reminderDateTimeInMilliseconds = 000;
Button but;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminder);
but = findViewById(R.id.but);
but.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
createNotifyChannel();
Intent intent = new Intent(Reminder.this,ReminderBroadcast.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Reminder.this,0,intent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Calendar calendarToSchedule = Calendar.getInstance();
calendarToSchedule.setTimeInMillis(System.currentTimeMillis());
calendarToSchedule.clear();
//.Set(Year, Month, Day, Hour, Minutes, Seconds);
calendarToSchedule.set(2020, 8, 20, 19, 12, 0);
reminderDateTimeInMilliseconds = calendarToSchedule.getTimeInMillis();
alarmManager.setExact(AlarmManager.RTC_WAKEUP,reminderDateTimeInMilliseconds,pendingIntent);
}
});
}
private void createNotifyChannel(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
CharSequence name = "ReminChannel";
String desc = "This is my channel";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("mynotif",name,importance);
channel.setDescription(desc);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
}
ReminderBroadcast.java
public class ReminderBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationCompat.Builder notif = new NotificationCompat.Builder(context,"mynotif")
.setContentTitle("Appointment reminder")
.setContentText("Hello there")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat manager = NotificationManagerCompat.from(context);
manager.notify(200,notif.build());
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.firstapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<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=".Reminder">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ThirdActivity" />
<activity android:name=".SecondActivity" />
<activity android:name=".MainActivity">
</activity>
<receiver android:name=".ReminderBroadcast"/>
</application>
</manifest>
What am I doing wrong?
Below code is working fine upto marshmallow but it not working in from 7.0
I create Brocast receiver for to fetch location every 6 sec.
MainActivity.java
private PendingIntent getPendingIntent() {
Intent intent = new Intent(this, LocationUpdatesBroadcastReceiver.class);
intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES);
return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public void requestLocationUpdates(View view) {
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, getPendingIntent());
} catch (SecurityException e) {
Utils.setRequestingLocationUpdates(this, false);
Log.e("requestLocationUpdates"," "+e.toString());
e.printStackTrace();
}
}
LocationUpdatesBroadcastReceiver.class
This is my BrocadcastReceiver class
public class LocationUpdatesBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "LUBroadcastReceiver";
static final String ACTION_PROCESS_UPDATES =
"com.google.android.gms.location.sample.locationupdatespendingintent.action" +
".PROCESS_UPDATES";
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
final String action = intent.getAction();
Log.d("showthepackgesss","***** "+action +" \n"+ACTION_PROCESS_UPDATES );
if (ACTION_PROCESS_UPDATES.equals(action)) {
LocationResult result = LocationResult.extractResult(intent);
if (result != null) {
List<Location> locations = result.getLocations();
Utils.setLocationUpdatesResult(context, locations);
Utils.sendNotification(context, Utils.getLocationResultTitle(context, locations));
Log.i(TAG, Utils.getLocationUpdatesResult(context));
}
}
}else {
Toast.makeText(context,"No Intent found checkit",Toast.LENGTH_SHORT).show();
}
}
}
My Manifestfile.xml
Here is my manifestfiles
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cbdc.locationupdates_background">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"/>
<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=".LocationUpdatesIntentService"
android:exported="false"></service>
<receiver android:name=".LocationUpdatesBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.example.cbdc.locationupdates_background.LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES" />
</intent-filter>
</receiver>
</application>
</manifest>
if any one know please help me.....Thanks in advance!!!!!!
You need to add support for runtime permissions, introduced in API 23.
I'm new in Android Wear development. I'm trying to make the smartwatch send a string to a mobile app but I don't know how make it work. I've tried to do that following some tutorials, but still nothing works.
Android mobile manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="manuela.com.messagewearableandroid">
<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">
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<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=".ListenerService"
android:enabled="true">
<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="*" />
</intent-filter>
</service>
</application>
</manifest>
Android Wear manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="manuela.com.messagewearableandroid">
<uses-feature android:name="android.hardware.type.watch" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
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>
</application>
</manifest>
ListenerService for mobile:
public class ListenerService extends WearableListenerService {
#Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
showToast(messageEvent.getPath());
System.out.println("Arrivato");
}
private void showToast(String message) {
System.out.println("Arrivato");
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
MainActivity for Wear:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initApi();
Button button = (Button) findViewById(R.id.btn_toast);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
/**
* Sets up the button for handling click events.
*/
sendToast();
}
});
}
/**
* Initializes the GoogleApiClient and gets the Node ID of the connected device.
*/
private void initApi() {
client = getGoogleApiClient(this);
retrieveDeviceNode();
}
/**
* Returns a GoogleApiClient that can access the Wear API.
* #param context
* #return A GoogleApiClient that can make calls to the Wear API
*/
private GoogleApiClient getGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.build();
}
/**
* Connects to the GoogleApiClient and retrieves the connected device's Node ID. If there are
* multiple connected devices, the first Node ID is returned.
*/
private void retrieveDeviceNode() {
new Thread(new Runnable() {
#Override
public void run() {
client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
NodeApi.GetConnectedNodesResult result =
Wearable.NodeApi.getConnectedNodes(client).await();
List<Node> nodes = result.getNodes();
if (nodes.size() > 0) {
nodeId = nodes.get(0).getId();
}
client.disconnect();
}
}).start();
}
/**
* Sends a message to the connected mobile device, telling it to show a Toast.
*/
private void sendToast() {
if (nodeId != null) {
new Thread(new Runnable() {
#Override
public void run() {
client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
Wearable.MessageApi.sendMessage(client, nodeId, MESSAGE, null);
System.out.println("Mandato");
client.disconnect();
}
}).start();
}
}
You may follow this documentation for Sending and Receiving Messages. You send messages using the MessageApi and attach the following items to the message:
An arbitrary payload (optional)
A path that uniquely identifies the message's action
Here's another reference for Sending String from watch to phone.
I'm playing with Wear SDK and trying to create a wear application.
I want to display a custom notification as shown on android docs but it doesn't work.
This is my Activity Code:
public class WearActivity extends Activity {
private Button notifyBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wear);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
notifyBtn = (Button) stub.findViewById(R.id.notifyBtn);
notifyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
createNotification();
}
});
}
});
}
private void createNotification(){
Toast.makeText(this, "Press", Toast.LENGTH_LONG).show();
//Create Intent
Intent notificationIntent =
new Intent(this, WearNotificationActivity.class)
.putExtra("EXTRA_STRING", "Hi, I'm an EXTRA!");
PendingIntent pendingNotificationIntent =
PendingIntent.getActivity(this,0,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification =
new Notification.Builder(this)
.extend(new Notification.WearableExtender()
.setDisplayIntent(pendingNotificationIntent)
.setCustomSizePreset(Notification.WearableExtender.SIZE_MEDIUM))
.build();
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
}
Although the button press is triggered, no Custom notification appears.
I edited the Manifest Too:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tizianobasile.wearactivity" >
<uses-feature android:name="android.hardware.type.watch" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault.Light" >
<activity
android:name=".WearActivity"
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:label="#string/title_activity_wear_notification"
android:exported="true"
android:allowEmbedded="true"
android:taskAffinity=""
android:theme="#android:style/Theme.DeviceDefault.Light">
</activity>
</application>
</manifest>
I really can't find the cause, my code is almost identical to the documentation code.
In general, the smallIcon is mandatory for a notification in Android Wear. From my tests, despite that in a notification with custom card layout (setDisplayIntent) the icon is not even displayed - you still need to specify it in order to appear on Android Wear at all.
For example:
Notification notification =
new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.extend(new Notification.WearableExtender()
.setDisplayIntent(pendingNotificationIntent)
.setCustomSizePreset(Notification.WearableExtender.SIZE_MEDIUM))
.build();
For some reason, the service is not started, none of my debug logs are being called, nor are the toasts I created within the service being shown (Toasts displayed via a handler, toast code not shown, simple guide here for reference: http://www.jjoe64.com/2011/09/show-toast-notification-from-service.html)
public class MainActivity extends Activity {
Intent locationPollingIntent;
Button updateLocationButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationPollingIntent = new Intent(this, LocationService.class);
updateLocationButton = (Button) findViewById(R.id.updateLocationButton);
updateLocationButton.setText("Start");
updateLocationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, updateLocationButton.getText().toString());
if (updateLocationButton.getText().toString() == "Start") {
MainActivity.this.startService(locationPollingIntent);
updateLocationButton.setText("Stop");
} else if (updateLocationButton.getText().toString() == "Stop") {
MainActivity.this.stopService(locationPollingIntent);
updateLocationButton.setText("Start");
}
}
});
}
}
A snippet from my Service class looks like so:
public class LocationService extends Service {
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "Location service started");
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Starting Service" );
grabLocation();
return super.onStartCommand(intent, flags, startId);
}
// No implementation
#Override
public IBinder onBind(Intent arg0) {
return null;
}
Lastly, my manifest contains the following
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rperryng.intellilocation"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service
android:name=".LocationService"
android:label="Location Service" />
<activity
android:name="com.rperryng.intellilocation.activities.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>
It is also worth noting that my mainActivity is in a package com.rperryng.intellilocation.activities and my service in com.rperryng.intellilocation.backgroundServices
I found the following log that is probably related to the issue:
01-27 12:53:58.804: W/ActivityManager(262): Unable to start service Intent { cmp=com.rperryng.intellilocation/.backgroundServices.LocationService }: not found
Try specifying the full package name in your manifest android:name="com.rperryng.intellilocation.backgroundServices.LocationService"