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();
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?
I'm using Firebase notifications to send notifications in my Android App. I want to achieve following:
When user clicks notification, activity of my choice should open and activity should perform some actions automatically which I'll define like loading specific url within webview, etc.
What I did?
In Firebase console, under custom data, I set key as click_action. And value as ttdemo and sent notifications.
In my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
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>
<activity android:name=".aboutmain" />
<activity android:name=".Timetable">
<intent-filter>
<action android:name="ttdemo"/>
</intent-filter>
</activity>
<activity android:name=".Results" />
<activity android:name=".timetable_downloads" />
<activity android:name=".result_downloads" />
<activity android:name=".eforms" />
<activity android:name=".write" />
<activity android:name=".qpapers" />
<activity android:name=".november2014" />
<activity android:name=".november_2014_downloads" />
<activity android:name=".april_2015" />
<activity android:name=".november_2015" />
<activity android:name=".april_2016"></activity>
</application>
Current scenario:
I'm getting notifications but Timetable activity is not opened.
Instead, the main activity opens.
Try like blow code when your onMessageReceived method called.
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
if (data.containsKey("click_action")) {
String className = data.get("click_action");
Class cls;
try {
cls = Class.forName(className);
Intent i = new Intent(context, cls);
//i.putExtras(extras); // put extras if you required
context.startActivity(i);
}catch(ClassNotFoundException e){
//means you made a wrong input in firebase console
}
}
}
To send a notification with firebase console, put a key-value-pair as custom data like this:
Key: click_action
Value: <fully qualified class name of your activity>
You need to pass panding intent to notification in the onMessageReceived(RemoteMessage remoteMessage) method of class FirebaseMessagingService
Intent resultIntent = new Intent(FirebaseMessagingService.this, MobilActivity.class);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent intent = PendingIntent.getActivity(getApplicationContext(), 0,
resultIntent, PendingIntent.FLAG_CANCEL_CURRENT);
and set to notification object as
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setContentIntent(resultPendingIntent)
and method like
private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine(message);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(inboxStyle)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.growth_indus)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(AppConstants.getParamInt(AppConstants.GlobalParamEnum.NOTIFICATION_ID), notification);
}
Finally, I achieved the objective!
This solution worked perfectly for me! http://androidbash.com/firebase-push-notification-android/
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.
Google map is displayed here and I also want to issue notification and when I click it, notification should take me to the main activity ie, google map but notification is not issued . Here are 2 classes and manifest file.
public class MainActivity extends FragmentActivity{
protected GoogleMap gMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
if (gMap == null) {
Toast.makeText(this, "Google Maps not available",
Toast.LENGTH_LONG).show();
gMap.setMyLocationEnabled(true);
}
}
Notify Class,
public class Notify extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.jollyr)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentTitle("Flood Warning")
.setContentText("You are in Danger Zone");
// Sets an ID for the notification
int notId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(notId, mBuilder.build());
Intent i=new Intent(this,MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
i,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
}
}
Manifest file,
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.map.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="com.example.map.Notify"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.map.Notify" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<meta-data
android:name="Package+.v2.API_KEY"
android:value="Key here" />
</application>
</manifest>
I have created a notification in my application to show the battery level in percentage. My manifest file is
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.create.bg"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.BATTERY_STATS"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".CreateBgActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".BatteryReceive" >
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED"></action>
</intent-filter>
</receiver>
</application>
I created a separate class that extends BroadcastReceiver to receive the battery level and notify in the status bar. My code is:
public class BatteryReceive extends BroadcastReceiver {
private String bat = "android.intent.action.BATTERY_CHANGED";
#Override
public void onReceive(Context context, Intent intent) {
//Log.d("Battery Level", ""+intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1));
if(intent.getAction().equals(bat)) {
Toast.makeText(context, "Battery Level"+intent.getIntExtra("level", 0), Toast.LENGTH_SHORT).show();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final Notification notifyDetails = new Notification(R.drawable.ic_launcher,""+intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1),System.currentTimeMillis());
//notifyDetails.flags = Notification.FLAG_AUTO_CANCEL;
notifyDetails.setLatestEventInfo(context, "Batter Level", ""+intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1), null);
mNotificationManager.notify(1, notifyDetails);
}
}
}
I could't get any notification or Log output for the battery level :( Is it anything wrong with my code. SOme one help me out of this.
#Override
public void onReceive(Context context, Intent intent) {
//Log.d("Battery Level", ""+intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1));
if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
// This is called when Your battery is changed
}
}
Change:
if(intent.getAction().equals(bat))
To:
if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED))