How can I modify a textview from a non-activity class? Android - android

I want to modify a TextView from an alarmmanager class's onReceive method this class does not extend activity. The alarm sends an intent that creates a notification and I want to make it so clicking the notification will open a textview with a particular string that I get in this onReceive method.
RemoteViews contentView = new RemoteViews(context.getPackageName(),R.layout.notify_layout);
contentView.setTextViewText(R.id.notetext,my_message);
notif.contentView = contentView;
I tried to do this using the RemoteView above with the notification intent but it doesn't seem to work.
I know I can't access this using findViewById, but what approach should I take here?
This is from the code that handles the intent
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.notify_layout);
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE); nm.cancel(getIntent().getExtras().getInt("com.myapp.NotificationDisp"));
Then I have this whole notification thing here. I know that its deprecated and I should be using builder but I need this to be compatible back to gingerbread which it seems builder is not.
Intent i = new Intent("com.MyApp.NotificationDisp");
i.putExtra("com.MyApp.NotificationDisp", 1);
nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
#SuppressWarnings("deprecation")
Notification notif = new Notification(R.drawable.ic_launcher,
"Myapp", System.currentTimeMillis());
//
RemoteViews contentView = new RemoteViews(context.getPackageName(),
R.layout.notify_layout);
contentView.setTextViewText(R.id.notetext,
my_message);
notif.contentView = contentView;
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
i, 0);
notif.contentIntent = contentIntent;
//
notif.setLatestEventInfo(context, "Myapp", my_message, contentIntent);
notif.vibrate = new long[] { 100, 250, 100, 500};
nm.notify(1, notif);
So this brings up a notification with the correct text in my status bar but when I click on it it only shows a blank textview. The xml notify_layout should be setup fine.

Related

Android: programmatically adding buttons to notification

I am trying programmatically add Imagebuttons to notification, but I cannot find work method for this. I know this is possible, because I saw similar app
This is how I build notification:
public class MyNotification extends Notification {
private Context ctx;
public Context getCtx() {
return ctx;
}
private NotificationManager mNotificationManager;
public MyNotification(Context ctx, int layout_id) {
super();
this.ctx = ctx;
String ns = Context.NOTIFICATION_SERVICE;
mNotificationManager = (NotificationManager) ctx.getSystemService(ns);
CharSequence tickerText = "Shortcuts";
long when = System.currentTimeMillis();
Notification.Builder builder = new Notification.Builder(ctx);
Notification notification = builder.getNotification();
notification.when = when;
notification.tickerText = tickerText;
notification.icon = R.drawable.ic_launcher;
RemoteViews contentView = new RemoteViews(ctx.getPackageName(), layout_id);
//set button listners
setListeners(contentView);
notification.contentView = contentView;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
mNotificationManager.notify(1387, notification);
}
And how i try to add ImageButton
RemoteViews button = new RemoteViews(ctx.getPackageName(), R.layout.image_btn_layout_test);
Intent actionIntent = new Intent("MyIntent");
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 0, actionIntent, 0);
button.setOnClickPendingIntent(R.id.image, pendingIntent);
contentView.addView(R.layout.noti_layout, button);
Read through these questions:
How to add button to notifications in android?
Adding button action in custom notification
Handling buttons inside android notifications
Also take look at the Notification Actions developers guide.
Also it looks like after a notification is created you cannot add actions, so you should create new notification with specified actions, and then replace previous one (assign id to your notifications).

Unable to cancel the notification from the notification tray when different layouts used for expand/collapse

I have a share option in the notification tray. So, I have used 2 custom views in my code.
1. Expandable Notification Layout
2. Normal Notification Layout
The UI is working fine. But, notifications are misbehaving. If I click the first notification or share first item in the notification, it works perfectly. But, If I click the last notification, then it opens the app but notification is not cleared from the notification tray. Also, the strange thing is, after clicking the notification,small icon which comes in the status bar disappears and now if i click the notification, it doesn't respond. I'm cancelling the notification. That's why second time, when i click it doesn't work. This was not happening when I used default builder layout for normal view.
Here is my code:
//setup a expanded notification layout
RemoteViews expandedView=new RemoteViews(context.getPackageName(), R.layout.custom_notification);
expandedView.setImageViewResource(R.id.image_logo, R.drawable.ic_launcher);
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm aa");
String time = dateFormat.format(new Date(when));
expandedView.setTextViewText(R.id.current_time, time);
expandedView.setTextViewText(R.id.title, context.getResources().getString(R.string.app_name));
expandedView.setTextViewText(R.id.text, message);
expandedView.setTextViewCompoundDrawables(R.id.share, R.drawable.gcm_share, 0, 0, 0);
//set a normal notification layout
RemoteViews collapsedView=new RemoteViews(context.getPackageName(), R.layout.custom_notification_normal_layout);
collapsedView.setTextViewText(R.id.text, message);
notificationId = ((int) System.currentTimeMillis() % 1000000);
//register listenr for Share Icon
setBtnListeners(expandedView, requestID, message, context, notificationId);
`Bitmap largeIcon = ((BitmapDrawable) context.getResources().getDrawable(R.drawable.ic_launcher)).getBitmap()`;
//Construct notification Builder
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(context);
mNotifyBuilder
.setWhen(when)
.setSmallIcon(icon)
.setLargeIcon(largeIcon)
.setContentTitle(message)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message));
notification = mNotifyBuilder.build();
//assign the vies to the notification builder
notification.bigContentView = expandedView;
notification.contentView = collapsedView;
//create pending Intent
Intent notificationIntent;
//notificationIntent = new Intent(context, Launcher.class);
notificationIntent = new Intent(context, SplashActivity.class);//Sritapana189
notificationIntent.putExtra(BundleKeys.NORMAL_PUSH, 1);
notificationIntent.putExtra(BundleKeys.DEFAULT_NOTI_NAV, nav);
notificationIntent.putExtra(BundleKeys.FROM_GCM, true);
notificationIntent.putExtra(ApplicationConstants.GCMKeys.GCM_NOTIFICATION_ID, notificationId);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context, requestID, notificationIntent, 0); //Modified
notification.contentIntent = contentIntent;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(notificationId, notification);
//Registering the share icon of notification tray
private static void setBtnListeners(RemoteViews notificationView, int requestId, String message, Context context, int notificationId) {
Intent shareBtnIntent = new Intent(context, GcmTransparentActivity.class);
shareBtnIntent.putExtra(ApplicationConstants.GCMKeys.BREAKING_NEWS, message);
shareBtnIntent.putExtra(ApplicationConstants.GCMKeys.GCM_NOTIFICATION_ID, notificationId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, requestId, shareBtnIntent, 0);
notificationView.setOnClickPendingIntent(R.id.share, pendingIntent);
}
//SplashActivity recieving Pending Inent
//here I'm retrieving the payload data and saving it and then cancelling the notification
Utility.cancelNotification(gcmNotificationId, getApplicationContext());
public static void cancelNotification(int id, Context ctx) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nMgr = (NotificationManager) ctx.getSystemService(ns);
nMgr.cancel(id);
}
The only change i did in my code is I added custom layout for the normal view.After this change, it's misbehaving when last notification item is clicked. Is there anything I'm missing. please help me to sort out this strange issue.
try this,
problem may be because you are not getting the notification id properly
quick fix can be,
Notification nNotificationManager nMgr = (NotificationManager) ctx.getSystemService(ns);
nMgr.cancel(id);
replace this with ,
Notification nNotificationManager nMgr = (NotificationManager) ctx.getSystemService(ns);
nMgr.cancelAll();
I resolved my issue. The problem was with the RemoteViews. I had made them local and making them final solved my issue
final RemoteViews expandedView=new RemoteViews(context.getPackageName(), R.layout.custom_notification);
final RemoteViews collapsedView=new RemoteViews(context.getPackageName(), R.layout.custom_notification_normal_layout)

How to invalidate RemoteView

I am making custom notification, and in receiver for intents I change text in element in layout of notification itself. When I update Notification nothing happens. Intents are being passed to receiver, I checked in log. Activity that makes notification, and receiver are separate classes. Any ideas? I know for that AppWidgetProvider for widget works great, but in this case there is no AppWidgetProvider, this is plain notification. Is there any other way to invalidate RemoteView?
//Receiver.onReceive() method
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.notification_layout);
//make dataString
views.setTextViewText(R.id.n_track_name, dataString);
//while searching i figured out this is something that should update notification
NotificationManager mNotificationManager = (NotificationManager)act.getSystemService(Activity.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, act.notification);
This is code which makes Notification for first time in other activity:
Notification notification = new Notification(icon, "Music Player", when);
NotificationManager mNotificationManager = (NotificationManager)MusicPlayerActivity.currentActivity.getSystemService(NOTIFICATION_SERVICE);
RemoteViews contentView = new RemoteViews(act.getPackageName(), R.layout.notification_layout);
//make pending intent on button
Intent intent = new Intent(act, NotificationReceiver.class);
intent.setAction(NotificationReceiver.ACTION_NOTIFICATION_NEXT);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(act, 0, intent, 0);
contentView.setOnClickPendingIntent(R.id.n_btnNext, actionPendingIntent);
//make other intents
//show notification
mNotificationManager.notify(1, notification);

The notification won't be "On Going"

I want to show an on going notification. but It's still shows up in Notifications part.
I used a custom layout for my notification.
here is my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int icon = android.R.drawable.alert_dark_frame;
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, "Hi", when);
RemoteViews contentView = new RemoteViews(getPackageName(),
R.layout.custom_notification);
notification.contentView = contentView;
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.contentIntent = contentIntent;
notification.defaults |= Notification.FLAG_ONGOING_EVENT;
mNotificationManager.notify(0, notification);
}
Edit:
You can see this image to see what I want to do.
http://backcountrynavigator.com/wp-content/uploads/screenshots/download_ongoing_notification.png
You should start ongoing notifications with Service.startForeground() besides NotificationManager.notify()
EDIT: I also recommend that you use Notification.Builder instead of new Notification(), and then use setOngoing(), just to keep it clean.

Android show notification from BroadcastReceiver

I have a class which extends BroadcastReceiver that gets called whenever new Wifi scan results are available (the receiver is registered in the manifest with the Scan_Results broadcast as the intent-filter).
From this class, I want to be able to show a notification to the user. Currently, I pass the context that is received as a parameter in the onReceive method of my broadcast intent class to a "show notification" method of another class.
When it gets to the line:
myNotificationManager.notify(notificationId, notification);
it fails with the following exception:
java.lang.IllegalArgumentException: contentView required: pkg=com.mumfordmedia.trackify id=2131034122 notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x0)
Any idea why this is happening? All I can think of is because the context that I am getting from the onReceive parameter is not ... for lack of a better phrase, "right for the job"...
Any ideas?
Thanks,
Max.
ContentView is the view which is required when the notification is clicked. The code below works fine and setLatestEventInfo() is required method.
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher,
"Hello from service", System.currentTimeMillis());
Intent intent = new Intent(this, MainActivity.class);
notification.setLatestEventInfo(this, "contentTitle", "contentText",
PendingIntent.getActivity(this, 1, intent, 0));
manager.notify(111, notification);
Not sure exactly why it wasnt working before but here is the code I got it working with:
Declare the following outside of any method:
int YOURAPP_NOTIFICATION_ID = 1234567890;
NotificationManager mNotificationManager;
Then in the onReceive method call the following:
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
showNotification(context, R.drawable.icon, "short", false);
Then declare the following method:
private void showNotification(Context context, int statusBarIconID, String string, boolean showIconOnly) {
// This is who should be launched if the user selects our notification.
Intent contentIntent = new Intent();
// choose the ticker text
String tickerText = "ticket text";
Notification n = new Notification(R.drawable.icon, "ticker text", System.currentTimeMillis());
PendingIntent appIntent = PendingIntent.getActivity(context, 0, contentIntent, 0);
n.setLatestEventInfo(context, "1", "2", appIntent);
mNotificationManager.notify(YOURAPP_NOTIFICATION_ID, n);
}
You have to call Notification.setLatestEventInfo().
Use this code along with your notification
Intent intent = new Intent(this, MusicDroid.class);
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
notification.setLatestEventInfo(this, "This is the title",
"This is the text", activity);
notification.number += 1;
nm.notify(NOTIFY_ID, notification);
From what I can tell, when you're creating you notification to pass to the Notification manager, you're not giving it a content view to display. Review the line where you actually create the notification to see if you're actually giving the notification a view to display.
For those who are using NotificationCompat, the following code will work:
NotificationCompat.Builder n = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.icon).setContentText("Notify Title").setContentText("Sample Text");
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent i = new Intent(this,MainActivity.class);
PendingIntent ac = PendingIntent.getActivity(this, 0, i, 0);
n.setContentIntent(ac);
nm.notify(12222, n.build());

Categories

Resources