Question

So i have an AsyncTask that handles an upload to a server while at the same time calls a NotificationHelper class to update the notification bar to display the current upload percentage. That part works fine, the only issues i have are getting the actions to work correctly and being able to use the intents sent by the actions (most recent attempt was using a broadcast manager inside the parent activity, but i never get the messages). If anyone could point me in the right direction, that would be very much appreciated.

Here is a bit of the code:

 mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

    Intent intent = new Intent("com.example.sibmedemo.sibme");
    intent.putExtra("message","pause");
    PendingIntent pIntent = PendingIntent.getActivity(mContext, 0, intent, 0);

    mBuilder = new Notification.Builder(mContext)
            .setContentTitle("Upload File")
            .setContentText("Upload in progress")
            .setSmallIcon(R.drawable.ic_launcher)
            .addAction(R.drawable.ic_launcher,"Pause",pIntent)
            .addAction(R.drawable.ic_launcher,"Cancel",pIntent);

    mBuilder.setProgress(100,0,false);
    mNotificationManager.notify(0,mBuilder.build());

I would assume that my main issue is that i do not correctly understand how pendingIntents work or how they are exchanged inside of an android activity, any clarity on this issue would be helpful.

-------WORKING CODE AFTER USING SOLUTION----------- main activity-----------

public class FileUploadActivityV2 extends Activity {

public static int flags = 0;
public BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        Log.i("message", "got a message");

        if(intent.getStringExtra("message").equalsIgnoreCase("pause"))
            flags = 1;

        goAsync();
    }
};

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_file_upload_activity_v2);

    registerReceiver(receiver, new IntentFilter("sibme"));

    flags = 0;
    (new UploadTask(this)).execute();
}

yes i know im suppose to take care of the life cycle of the brodcastReceiver but as of now this is acceptable for testing. For anyone wondering, the goAsync() function is part of the Android API and simply states that once the receiver has called the onReceive function, recycle the receiver for future so it can be used again.

in AsyncTask class---------

    @Override
    protected Long doInBackground(Integer... integers) {

    while(FileUploadActivityV2.flags == 0)
    {
        try{
            Thread.sleep(1000);
            Log.i("Running", "Running in background");
        }catch(Exception e){

        }
    }

    return null;
}

inside of notification helper class------

    public void createNotification() {
    mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

    Intent intent = new Intent("sibme");
    intent.putExtra("message","pause");
    PendingIntent pIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);

    mBuilder = new Notification.Builder(mContext)
            .setContentTitle("Upload File")
            .setContentText("Upload in progress")
            .setSmallIcon(R.drawable.ic_launcher)
            .addAction(R.drawable.ic_launcher,"Pause",pIntent)
            .addAction(R.drawable.ic_launcher,"Cancel",pIntent);

    mBuilder.setProgress(100,0,false);
    mNotificationManager.notify(0,mBuilder.build());

}
Was it helpful?

Solution 2

To interact with the asynctask that is working in the background, then you MAY be able to do so within publishProgress() (I've never tried it). Otherwise you just have on pre and post execute. Only thing I can come up with if this isn't the case is a class int variable whose value is changed depending on what the button the user clicks. This can then be checked within doInBackground and appropriate action can be taken.

OTHER TIPS

understanding PendingIntent is important. this is one of the powerful components Android have, and can be use for lot's of purposes beside notifications action handling.

you can think as pending intent as object that represents an action you want to perform (sending broadcast / starting activity / starting serive) + the intent to perform this action with. what makes it powerful is that you can provide pending intents to another process / applications (in your case the other process is the OS NotificationManager) and by that you give the other process ability to wake up your application and start automatically for you the intent you provided with the pending intent.

so, pending intent is in some way used in the notification as a "remote listener" that does not have to run in order to detect the event (in your case, the event is notification button click)

because of the nature of PendingIntent as object that shared between different apps - you get reference / create new one by static methods (PendingIntent.getService() / PendingIntent.getActivity() and so on) that returns you new instance or existing one managed by the system.

let's get to your code:

by calling PendingIntent.getActivity() you create pending intent that the AlarmManager could start the specific activity you provided in the intent ("com.example.sibmedemo.sibme" in your case). I guess you want to react differently to pause and and cancel actions. that's why you'll need different pending intent for each one of them. you can differ between the two actions in more then one way:

  • start different activity / service or send broadcast (PendingIntent.getBroadcast()) for each one of them
  • start the same activity, but use different request code

anyway - you'll have to create to different intents and thuss - two different pending intents to represent the different actions you want to perform for different actions.

hope it helped you, and maybe others.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top