Launch a fragment in my Android application from t

2019-02-18 05:18发布

问题:

How do I start a fragment in my Android application from a notification in the notification bar?

I've tried to implement this answer of creating my own action and then setting the action to the intent, but I'm unsure how to use it and what is required additionally - like adding something to the Manifest.

I've got a notification class that receives a context, a message and then an action. I then want to filter on that action to determine which fragment to launch, but I don't know how to launch a fragment as opposed to launching an activity.

Here is my Notifications.java class (incomplete):

public class Notifications {

    private Context mContext;

    public Notifications(Context context) {
        this.mContext = context;
    }

    public static void notify(Context context, String message, String  action) {

        //Action you invent should include the application package as a prefix — for example: "com.example.project.SHOW_COLOR".
        action = "my.package.name.here.frag."+action;

        //Construct a user message.
        String appName = context.getResources().getString(R.string.app_name);

        // Use the Notification manager to send notification
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        // Create a notification using android stat_notify_chat icon. 
        Notification notification = new Notification(R.drawable.ic_stat_notification, message, 0);

        //Sound, lights, vibration.
        //REMEMBER PERMISSIONS.
        notification.defaults |= Notification.DEFAULT_SOUND;
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        notification.defaults |= Notification.DEFAULT_LIGHTS;

        // Create a pending intent to open the application when the notification is clicked.
        //Restart the app.
        Intent launchIntent = null;

        //Get the action and based on what the action is, launch the application displaying the appropriate fragment.
        if (action.equalsIgnoreCase("friend")){
            //New friend notification
            //Launch application displaying the list of friends


        }
        if (action.equalsIgnoreCase("article")){
            //New article has been posted
            //Launch application displaying the news feed fragment


        }
        if (action.equalsIgnoreCase("points")){
            //Points scored notification
            //Launch application displaying the user's profile


        }
        if (action.equalsIgnoreCase("redeemable")){
            //New redeemable is offered
            //Launch application displaying the list of redeemables


        }
        if (!action.equalsIgnoreCase("friend") 
                && !action.equalsIgnoreCase("article") 
                && !action.equalsIgnoreCase("points") 
                && !action.equalsIgnoreCase("redeemable")){
            //Not specific, so launch the application from scratch displaying the activity feed

            launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
        }



        if(action != null && launchIntent != null){         
            launchIntent.setAction(action);         
        }

        // Set the notification and register the pending intent to it
        notification.setLatestEventInfo(context, appName, message, pendingIntent);

        // Trigger the notification
        notificationManager.notify(0, notification);
    }

}

回答1:

So this was actually pretty easy. Hopefully I can help someone else see this too.

I send an action to this notify function. The I add that action to my intent to launch an activity. In my case I open the launching activity, because all the fragments are loaded from within that activity based on what the user does. So I set the action using setAction and the I use that action in the activity as below.

My Notifications.java class changed to this:

public static void notify(Context context, String message, String  action) {

    action = action.toUpperCase();

    // Create a pending intent to open the the application when the notification is clicked.
    //Restart the app.
    Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());

    if(action != null && launchIntent != null){         
        launchIntent.setAction(action);         
    }

    PendingIntent pendingIntent = PendingIntent.getActivity(context, -1, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    notification.when = System.currentTimeMillis();  
    notification.flags |= Notification.FLAG_AUTO_CANCEL; 

    // Set the notification and register the pending intent to it
    notification.setLatestEventInfo(context, appName, message, pendingIntent);

    // Trigger the notification
    notificationManager.notify(0, notification);
}

And then in my activity from where I load the fragments, I get the action and filter it:

Intent intent = getIntent();

try{
    String action = intent.getAction().toUpperCase();

    if(action != null){
        if(action.equalsIgnoreCase(getResources().getString(R.string.notification_action_friend))){
                goFrag(getResources().getInteger(R.integer.FRAG_A_INT));
            }
        if(action.equalsIgnoreCase(getResources().getString(R.string.notification_action_article))){
                goFrag(getResources().getInteger(R.integer.FRAG_B_INT));
            }
        if(action.equalsIgnoreCase(getResources().getString(R.string.notification_action_points))){
                goFrag(getResources().getInteger(R.integer.FRAG_C_INT));
            }
        if(action.equalsIgnoreCase(getResources().getString(R.string.notification_action_redeemable))){
                goFrag(getResources().getInteger(R.integer.FRAG_D_INT));
            }
        if(action.equalsIgnoreCase(getResources().getString(R.string.notification_action_dance))){
                goFrag(getResources().getInteger(R.integer.FRAG_E_INT));
            }
        }else{
            Log.d(TAG, "Intent was null");
        }
    }catch(Exception e){
        Log.e(TAG, "Problem consuming action from intent", e);              
    }

In my goFrag function I replace the fragment if the required fragment is still in memory (meaning the user was there earlier and it hasn't been destroyed yet), or I create a new fragment required.