3

I just wanted to learn how to do some Android App development, so I started with some simple demos and now doing something harder (I guess ;-)).

Using: Eclipse + min SDK 8 + Android 2.2. Debugging and testing on emulator and my SGS I9000:

I managed to use AsyncTask to send some Data (Picture which I get from Camera or over the Gallery) to a server which works great. So, now that things works great, I decided to add a Custom Notification to the Status bar with a progress bar and text. Well, that worked too, but then I noticed:

1) as soon ad I call the publishProgress() from doInBackground() which will call the onProgressUpdate() where I update my notification. I noticed by "opening" and "closing" the Notification bar during the update, that it is not smooth. It freezes or sometime you'll see that the notification bar is not responding anymore (If opened it won't close anymore or if it was closed and try to open it won't).

2) I also noticed when I start x Notifications, then my System crashes and it looks as my system did a new start which it didn't!

well, I thought I did everything as it stands in the documentations, but I am sure I did something wrong, cause I am sure it's possible what I am looking for since Facebook for Android does the same as I soon as I choose a picture to share.

I create the notification in my onPreExecute() call (so that means on the UI thread).

here my code if anybody can tell me where my problem is: (I hope that's Okay to post the code here) NotificationHelper manges the Notification by generating and updating the progressbar/text

public class NotificationHelper {

     private Context mContext;
     private Notification mNotification;
     private NotificationManager mNotificationManager;
     private PendingIntent mContentIntent;
     private RemoteViews contentView;
     private static Random randomGenerator = new Random();
     private int Id = -1;

     public NotificationHelper(Context context)
     {
         mContext = context;
         Id = randomGenerator.nextInt(1000);
     }

     public void CreateNotification(String text)
     {
         mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         mNotification = new Notification(R.drawable.icon, "MyTestApp", System.currentTimeMillis());
         contentView = new RemoteViews(mContext.getPackageName(), R.layout.notification);
         contentView.setProgressBar(R.id.progressBar, 100, 0, false);        
         contentView.setTextViewText(R.id.text, Html.fromHtml("<b>TEST </b>" + text));
         contentView.setTextViewText(R.id.textStatus, String.format(mContext.getString(R.string.uploading), ""));
         mNotification.contentView = contentView;

         Intent notificationIntent = new Intent(mContext, main.class);
         notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContentIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0);
         mNotification.contentIntent = mContentIntent;
         mNotificationManager.notify(Id, mNotification);
     }

     public void UpdateProgress(int Percent)
     {
         if (mNotification == null) return;
         mNotification.contentView.setProgressBar(R.id.progressBar, 100, Percent, false);
         contentView.setTextViewText(R.id.textStatus, String.format(mContext.getString(R.string.uploading), Integer.toString(Percent) + "%"));
         mNotificationManager.notify(Id, mNotification);
     }

     public void Completed(boolean Status)
     {
         if (contentView != null) {
             //mNotificationManager.cancel(Id);
             contentView.setViewVisibility(R.id.progressbarContainer, View.INVISIBLE);
             if (Status) 
             {
                 contentView.setTextViewText(R.id.textStatus, mContext.getString(R.string.upload_done));
             }else
             {
                 contentView.setTextViewText(R.id.textStatus, mContext.getString(R.string.upload_failed));
             }
             mNotificationManager.notify(Id, mNotification);
         }
     }

}

here is my Task:

public class MyTask extends AsyncTask<Void, Integer, Integer> {

    private Context context;
    private NotificationHelper pbNotificationHelper;
    public String TextToShow;

    public MyTask(Context context, String text) {
        this.context = context;
        TextToShow = text;
    }

    @Override
    protected Integer doInBackground(Void... params) {

        int xfileSize = 1048576 * 4;
        if (true){
            int i = 0;
            while (true)
            {
                if (i > xfileSize) break;
                i += 32 * 1024;
                publishProgress( (i * 100) / xfileSize);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        pbNotificationHelper = new NotificationHelper(context);
        pbNotificationHelper.CreateNotification(TextToShow);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
        pbNotificationHelper.UpdateProgress(values[0]);
    }

    @Override
    protected void onPostExecute(Integer result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        pbNotificationHelper.Completed(true);
    }
}

and here is my test activity:

public class main extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void Test1Click(View view) {
        new MyTask(getApplicationContext(), "This is a test message").execute();
    }
}

I am sorry if that is too much code, but I am really at end of my understandings!

Interesting is that, when I don't call the publishProgress() nothings freezes and looks everything smooth! Any help? any Idea what I do wrong?

Many thanks in advance, Cheers Gohlool

Gohlool
  • 363
  • 2
  • 5
  • 15

1 Answers1

0

I think where ever you calling your async task code it should be in separate thread.

Alexander
  • 23,432
  • 11
  • 63
  • 73
Anup Rojekar
  • 1,093
  • 9
  • 29
  • 1
    thanks buddy, but it din't help much. here is what I did: ´public void Test1Click(View view) { final MyTask task = new MyTask(getApplicationContext(), "This is a test message"); Thread x = new Thread(){ @Override public void run() { task.execute(); } }; x.start(); }´ – Gohlool May 16 '11 at 13:57
  • can you tell me this where would this Test1Click() method be called. – Anup Rojekar May 17 '11 at 04:59
  • from the main activity (look at the last code in my original post). In documentation stands that the Task which will do some progress update must be called from the UI thread? – Gohlool May 17 '11 at 13:35
  • are but you are calling it explicitly? i didn't get it. – Anup Rojekar May 17 '11 at 13:39
  • In my test sample I just have a Button in the main activity which onClick is set to Test1Click()! so as soon as I click the Button I create a new Task and execute it. Info: I am doing just the same as I would do dynamically set the onClick Event with calling the Button.setOnClickListener(new OnClickListener(){....}); – Gohlool May 18 '11 at 00:30
  • @thanks Gohlool +1 for your Hints. updating notification should also be done with in the separate thread. – Krishna Shrestha Aug 03 '12 at 08:10