I am almost finished with this toy app game I am making.
Problem:
My notification is always showing my counter to be 30000. Why isn't it timing down?
What I have done:
I have implemented a simple Service class and a custom timer to tick down. Eventually once I am sure the timer is working I will exit the entire game.
Here is my code:
package com.example.redshirtmarblez;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.widget.Toast;
public class TimingService extends Service{
public long counter = 30000;
private Context ctx;
private Activity localActivity;
private NotificationManager nm;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
super.onCreate();
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
declareNotification();
timer.start();
//Toast.makeText(this, "Timer is :" + counter, Toast.LENGTH_LONG).show();
//showNotification();
}
public void getActivity(Activity activity)
{
localActivity = activity;
}
//count to end the game
public CountDownTimer timer = new CountDownTimer(30000, 1000){
public void onTick(long millisUntilFinished){
counter = millisUntilFinished / 1000;
}
public void onFinish(){
counter = 0;
//Kill the game
int i = android.os.Process.myPid();
android.os.Process.killProcess(i);
}
};
/*
* Show a notification while this service is running
*/
public void declareNotification()
{
//Declare a new notification
Notification notification = new Notification(R.drawable.ic_launcher, "A New Notification", System.currentTimeMillis());
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
Intent intent = new Intent(this, TimingService.class);
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
notification.setLatestEventInfo(this, "herp", "counter: " + counter, activity);
//This is clearly not 1337, but a good joke
startForeground(1337, notification);
}
}
All this does when it runs is shows "A New Notification", and then changes to "herp counter: 30000". However, this notification never changes. It just stays 30000. Why? I thought I fixed this with making the flag ongoing?
https://developer.android.com/reference/android/app/Notification.Builder.html#setUsesChronometer(boolean)
Show the when field as a stopwatch. Instead of presenting when as a
timestamp, the notification will show an automatically updating
display of the minutes and seconds since when. Useful when showing an
elapsed time (like an ongoing phone call). The counter can also be set
to count down to when when using setChronometerCountDown(boolean).
No updating required, works off the setWhen() value
NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_default_notification)
.setTicker("Ticker Text")
.setWhen(when) // the time stamp, you will probably use System.currentTimeMillis() for most scenarios
.setUsesChronometer(true)
.setContentTitle("Title Text")
.setContentText("Content Text");
counter is not a reference; the notification will not update with its new value until you explicitly tell it to.
Have a look at the documentation on updating an existing notification. Your ID is 1337 here, so you can use that to update it.
In fact, you may just be able to call declareNotification() again from your onTick() method... If this doesn't work, however, I would suggest keeping a reference to the Notification object (as a member variable), then updating it, and use nm.notify(1337, /* your notification object */);.
I don't know why you want to use a notification. But you need to keep updating your notification. For a simple fix add
declareNotification();
underneath this line:
counter = millisUntilFinished / 1000;
Note that this isn't a great way to code it. Really you should pass a method only updating the notification rather than "creating" a new one. However as long as they have the same ID, one will replace the other.
Also just to use a more up to date way of managing notifications, use
NotificationCompat.builder b = new NotificationCompat.Builder(context);
Related
I have a service that sends a notification at a random time, telling me to press a button. This button needs to be pressed quickly because after 2 minutes it will disappear again. But after those 2 minutes I don't know how I can see if the button has or hasn't been pressed.
Somehow I need to get something like a boolean from my MainActivity to my service, but I don't believe I can do that with an intent because then I would restart my service.
I have looked for an answer but wasn't able to find a solution, any help will be much appreciated!
My service:
`package com.example.pressme_alpha;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
public class ButtonAlarmService extends IntentService{
private static final String INTENT_NAME = "notification";
private NotificationManager nm;
private Notification notification;
public ButtonAlarmService() {
super("Imma button!");
}
#SuppressWarnings("static-access")
#Override
protected void onHandleIntent(Intent intent) {
nm = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
Intent newIntent = new Intent(this.getApplicationContext(), MainActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.putExtra(INTENT_NAME, true);
PendingIntent pendingIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(this);
notification = notifBuilder.setContentIntent(pendingIntent).setSmallIcon(R.drawable.ic_launcher).setContentTitle("Press me - alpha").setContentText("You need to press the button!").build();
notifBuilder.setAutoCancel(true);
nm.notify(0, notification);
startActivity(newIntent);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Check if the button is pressed here
ButtonAlarmReceiver.completeWakefulIntent(intent);
}
}
`
Extending Service (not IntentService) is what you want to do as it will keep runing untill you explicitly tell it to stop via stopService(Intent) method or if the service calls stopSelf() on its self.
You can send signals to the service via startService(Intent) method. This will start the service the first time its called (when the service is not running) and just send data to it if called subsequent times.
Make sure to spawn a new thread if you are doing heavy proccessing in the service as this will run on the Main thread (or UI thread depending on what you want to call it). You do not want to block the main thread.
When closing an application with back or homescreen button, app showing a webview closes.
On returning back to the app, it load the page all over again.
More specifically, the page this app loads contains an upload button. File upload takes some time depending on the internet speed. If the used starts uploading and goes to other app, the upload progress will be lost and on revisiting the app, the page will load all over again.
What to do to make upload in VebView work in background. Giving a notification of "upload in progress..." in notification area will be an added benefit. Suggest what to do and how?
You should do the upload in a Service, instead of in a Activity. (Lookup IntentService for example, which will shut itself down after upload)
here is sample code of service just edit is as per your need:
i have create one service and call it from my activity using:
startService(new Intent(MainActivity.this, TempServices.class));
here is my service class
package com.example.uploadfile;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;
public class TempServices extends Service {
protected static final int ID = 100;
private NotificationManager mNotifyManager;
private Builder mBuilder;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
mNotifyManager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_launcher);
// Start a lengthy operation in a background thread
new Thread(new Runnable() {
#Override
public void run() {
int incr;
// Do the "lengthy" operation 20 times
for (incr = 0; incr <= 100; incr += 5) {
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate"
// state
mBuilder.setProgress(100, incr, false);
// Displays the progress bar for the first time.
mNotifyManager.notify(0, mBuilder.build());
// Sleeps the thread, simulating an operation
// that takes time
try {
// Sleep for 5 seconds
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
Log.e("error-->", "sleep failure");
}
}
// When the loop is finished, updates the notification
mBuilder.setContentText("Download complete")
// Removes the progress bar
.setProgress(0, 0, false);
mNotifyManager.notify(ID, mBuilder.build());
}
}
// Starts the thread by calling the run() method in its Runnable
).start();
return super.onStartCommand(intent, flags, startId);
}
}
for counting progress check this link
do not forgate to add this service in android manifes:
<service android:name="TempServices" >
I am developing for Honeycomb and for days i am trying to solve this problem.
I have an notification service without intent (don`t need one), the problem is that after every call for displaymessage function the notification pup-up each time, so i get 100 notifications. I would like it to popup only once and after that only change the text of percent. Similar to downloading from market progress bar and percentage. I have isolated the function and created new testing code but with no success. If you look at this from other angle, i wish to change the text on existing notification without creating new notification.
Can you please help me?
Here is the whole code (after the isolation):
package com.disp;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.os.SystemClock;
public class DispalyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
for (int i = 0; i < 100; i++) {
SystemClock.sleep(300);
displaymessage(""+i+"%");
}
}
public void displaymessage(String string) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
Notification notification = new Notification(R.drawable.ic_launcher, "Notification Service", System.currentTimeMillis());
Context context = getApplicationContext();
notification.setLatestEventInfo(context, "Downloading Content:", string, null);
final int HELLO_ID = 2;
mNotificationManager.notify(HELLO_ID, notification);
}
}
Because each notification is uniquely identified by the NotificationManager with an integer ID, you can revise the notification by calling setLatestEventInfo() with new values, change some field values of the notification, and then call notify() again.
You can revise each property with the object member fields (except for the Context and the notification title and text). You should always revise the text message when you update the notification by calling setLatestEventInfo() with new values for contentTitle and contentText. Then call notify() to update the notification. (Of course, if you've created a custom notification layout, then updating these title and text values has no effect.)
from
http://developer.android.com/guide/topics/ui/notifiers/notifications.html
I know, there are tons of these on here, but I've been trying solutions all day and haven't gotten anywhere.
Neither the example on google's docs, nor any of the 5 other ways I've found on here have worked for me at all.
As is the typical case, when I click the notification it closes the status bar and nothing new is shown onscreen.
I am creating the notification from a service and need the notification to trigger a new activity that has not yet been created.
I also will need a way to pass information to that activity via intent.
And yes... this is java for Android
What follows are the shattered remnants of my code.
package com.bobbb.hwk2;
import java.io.FileOutputStream;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
import android.provider.ContactsContract;
import android.widget.Toast;
public class contactBackup extends Service
{
private NotificationManager nManager;
private static final int NOTIFY_ID = 1100;
#Override
public void onCreate()
{
super.onCreate();
String ns = Context.NOTIFICATION_SERVICE;
nManager = (NotificationManager)getSystemService(ns);
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// inform user that service has started
Toast.makeText(getApplicationContext(), R.string.service_started,Toast.LENGTH_LONG).show();
String data = lookUpContacts();
if( saveToSDCard(getResources().getString(R.string.backup_file_name),data) )
{
Context context = getApplicationContext();
// create the statusbar notification
Intent nIntent = new Intent(this,contactViewer.class);//Intent nIntent = new Intent(Intent.ACTION_MAIN);
nIntent.setClass(context,contactViewer.class);
//nIntent.putExtra("data",data);
Notification msg = new Notification(R.drawable.icon,"All contacts records have been written to the file.",System.currentTimeMillis());
// start notification
//PendingIntent pIntent = PendingIntent.getService(getApplicationContext(),0,nIntent,PendingIntent.FLAG_UPDATE_CURRENT|Intent.FLAG_FROM_BACKGROUND);
PendingIntent pIntent = PendingIntent.getActivity(this,0,nIntent,0);
msg.flags = Notification.FLAG_AUTO_CANCEL;
msg.setLatestEventInfo(context,
"success",
"All contacts records have been written to the file.",
pIntent);
nManager.notify(NOTIFY_ID,msg);
}
}
#Override
public void onDestroy()
{
nManager.cancel(NOTIFY_ID);
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
// function returns string containing information
// from contacts
public String lookUpContacts()
{
...
}
public boolean saveToSDCard(String fileName, String data)
{
...
}
}
I can only hope that whatever is causing my problem is something fixable and not more of the crazy glitches I've been getting with eclipse (which no one else seems to have ever seen >:U )
If you can help me solve this problem, please share.
If you can't help with this specific problem but feel obligated to say unrelated things about posting, styles, topics, or good practice, then DON'T
Thank you :D
Edit:
You're going to have to add a flag for FLAG_ACTIVITY_NEW_TASK:
nIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
This is because you're launching from outside your app (from the system notification bar).
This is what happens when people overwork themselves. XD
The only reason none of the tutorials I tired worked is because I misspelled my activity name in the manifest.
Thanks for stopping by
Just add following in contactBackup(service class),
Intent nIntent = new Intent(this,contactViewer.class);//Intent nIntent = new Intent(Intent.ACTION_MAIN);
nIntent.setClass(context,contactViewer.class);
nIntent.putExtra("data",data);
nIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Notification msg = new Notification(R.drawable.icon,"All contacts records have been written to the file.",System.currentTimeMillis());
// start notification
//PendingIntent pIntent = PendingIntent.getService(getApplicationContext(),0,nIntent,PendingIntent.FLAG_UPDATE_CURRENT|Intent.FLAG_FROM_BACKGROUND);
PendingIntent pIntent = PendingIntent.getActivity(this,0,nIntent,0);
msg.flags = Notification.FLAG_AUTO_CANCEL;
msg.setLatestEventInfo(context,
"success",
"All contacts records have been written to the file.",
pIntent);
nManager.notify(NOTIFY_ID,msg);
then get value in contactViewer class,
as,
String s=getIntent().getStringExtra("data");
Im creating an application where I can add appointments to a list.
If an appointment is nearby, I want my app to show a notification in the status bar the day of the appointment at a certain hour.
I used the code from http://developer.android.com/guide/topics/ui/notifiers/notifications.html
to create my notification.
However, the "when" parameter in the script is somewhat confusing because a statusbar notification is always triggered when called.
Notification notification = new Notification(icon, tickerText, when);
What is the best way to schedule such notification?
It seems there is no easy way and I have to create a service that starts a listener Activity with a thread to loop my appointmentdates and show a notification when a date fits the current date?
However, the "when" parameter in the script is somewhat confusing
because a statusbar notification is always triggered when called.
Notification notification = new Notification(icon, tickerText, when);
Exactly - notification is triggered when called. If you set when variable to System.currentTimeMilis() as in the example, it means - show the notification now.
As what triggers your notifications, that is up to you to handle. An Activity doesn't seem like a good choice, but a Service does. Initialize your service on application start (and don't forget to stop it on application exit), and let it do the "listening" and triggering of notifications. It might look as:
public class NotifyService extends Service {
private NotificationManager mNM;
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
//do some work, listen for change
if (triggerSatisfied) showNotification();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
// Cancel the persistent notification.
mNM.cancelAll();
}
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
private void showNotification() {
//code for notification goes here
}
public class LocalBinder extends Binder {
NotifyService getService() {
return NotifyService.this;
}
}