So öffnen Sie eine Fragmentseite, wenn eine Benachrichtigung in Android gedrückt wird

Lesezeit: 9 Minuten

Benutzer-Avatar
Venkat Ramarao Potlapalli

Ich versuche, ein Fragment zu öffnen, wenn ich auf eine Benachrichtigung in der Benachrichtigungsleiste drücke. Meine App-Struktur ist:

  • eine Basisaktivität mit einem Navigationsschubladenmenü
  • einige Fragmente, die aus dem Menü geöffnet werden

    b.setOnClickListener(new OnClickListener() {
    
            @SuppressWarnings({ "deprecation", "static-access" })
            public void onClick(View v) {
    
            w_nm=(NotificationManager) getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
    
             Notification notify=new Notification(R.drawable.notnificationlogo,waternoti,System.currentTimeMillis());
    
             Intent notificationIntent = new Intent(getActivity(), Abc.class);
    
    
    
             PendingIntent pending=PendingIntent.getActivity(getActivity(), 0,notificationIntent, 0);
    
    
             notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                     | Intent.FLAG_ACTIVITY_SINGLE_TOP );
    
            notify.flags = Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL;
    
               notify.setLatestEventInfo(getActivity(),waternoti,waternoti1, pending);
    
             w_nm.notify(0, notify);
    

Kann mir jemand sagen, wie ich mit der nächsten Fragmentseite verlinken kann (der aktuelle Code befindet sich in der Klasse, die das Fragment erweitert)

Benutzer-Avatar
bereit

Wenn Sie verwenden Navigation Komponente, mit der Sie ein bestimmtes Ziel öffnen können NavDeepLinkBuilder:


val pendingIntent = NavDeepLinkBuilder(context)
                     .setComponentName(MainActivity::class.java)
                     .setGraph(R.navigation.nav_graph)
                     .setDestination(R.id.destination)
                     .setArguments(bundle)
                     .createPendingIntent()

...

notificationBuilder.setContentIntent(pendingIntent)

...

Bitte beachten Sie, dass es wichtig ist, es zu verwenden setComponentName nur wenn Ihr Ziel nicht in der Launcher-Aktivität enthalten ist.

  • Ich bin nicht in der Lage, den Backstack mit dieser Soultion nachzubilden. Ich habe Fragment A -> B -> C -> D -> E, wenn ich diese Lösung verwende, ist der Graph nur A -> E . Irgendeine Idee?

    – AndroidRuntimeException

    5. Dezember 2019 um 22:11 Uhr

  • Beachten Sie, dass dadurch eine neue Instanz der Aktivität geöffnet wird. Ich habe mehrere Stunden damit verbracht, dies zu debuggen. Es gibt andere Möglichkeiten, eine vorhandene Aktivität zu öffnen, aber ich bin mir nicht sicher, ob NavDeepLinkBuilder der richtige Weg ist

    – sprajagopal

    17. Juni 2021 um 20:05 Uhr

  • Android-Link When a user opens your app via an explicit deep link, the task back stack is cleared and replaced with the deep link destination. When nesting graphs, the start destination from each level of nesting—that is, the start destination from each <navigation> element in the hierarchy—is also added to the stack. Sie müssten also verschachtelte Diagramme erstellen, damit Ihre Navigation @AndroidRuntimeException funktioniert

    – soan saini

    8. März um 7:10


Benutzer-Avatar
Vito

Sie müssen Ihre Basisaktivität wie gewohnt starten, aber der Absicht einige zusätzliche Informationen darüber hinzufügen, welches Menüfragment geöffnet wird. Hier können Sie sehen, wie es gemacht werden kann: https://stackoverflow.com/a/8610916/1652236

Dies hängt von den zusätzlichen Informationen ab, die Sie in der Methode „onCreate()“ der Aktivitäten abrufen, mit der Sie das Fragment starten/laden.

Sehen Sie hier zum Beispiel, wie Sie mit Fragmenten arbeiten: http://www.tutorialspoint.com/android/android_fragments.htm
http://developer.android.com/guide/components/fragments.html

Die Absicht, dieses Verfahren zu starten, wird in etwa so aussehen:

Intent notificationIntent = new Intent(getActivity(), Abc.class);
notificationIntent.putExtra("menuFragment", "favoritesMenuItem");

und in Ihrer Basisaktivität:

@Override
protected void onCreate(final Bundle savedInstanceState)
{
    String menuFragment = getIntent().getStringExtra("menuFragment");

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    // If menuFragment is defined, then this activity was launched with a fragment selection
    if (menuFragment != null) {

        // Here we can decide what do to -- perhaps load other parameters from the intent extras such as IDs, etc
        if (menuFragment.equals("favoritesMenuItem")) {
            FavoritesFragment favoritesFragment = new FavoritesFragment();
            fragmentTransaction.replace(android.R.id.content, favoritesFragment);
         }
    } else {
         // Activity was not launched with a menuFragment selected -- continue as if this activity was opened from a launcher (for example)
         StandardFragment standardFragment = new StandardFragment();
         fragmentTransaction.replace(android.R.id.content, standardFragment);
    }
}

  • Hier in dieser App muss ich meine eigene Nachricht als Benachrichtigung generieren und ich habe diese Schaltfläche in einer der Menüoptionen in der Aktionsleiste beibehalten, ich habe nur eine Aktivität verwendet und alle anderen sind Fragmente

    – Venkat Ramarao Potlapalli

    28. Oktober 2014 um 13:00 Uhr

  • Wie ich Sie verstanden habe, müssen Sie Ihre Basisaktivität mit einem Fragment beginnen. Und der Fragmenttyp muss vom Benachrichtigungstyp abhängen. Ist es wahr?

    – Vito

    28. Oktober 2014 um 13:02 Uhr


  • Nicht alle Fragmente, nur wenige Fragmentseiten sollten vom Benachrichtigungstyp abhängen

    – Venkat Ramarao Potlapalli

    28. Oktober 2014 um 13:09 Uhr

  • Vielleicht verstehe ich deine Frage nicht ganz. Können Sie bitte den Code Ihrer Basisaktivität posten, damit ich helfen kann?

    – Vito

    28. Oktober 2014 um 13:15 Uhr


  • Ok, ich werde es jetzt erklären, ich habe eine Aktivität mit Rasteransicht, dann sind nach dem Klicken auf ein beliebiges Symbol in der Rasteransicht die nächsten Seiten Fragmente. Ich habe 16 Symbole und ihre jeweiligen Fragmentseiten. Ich habe eine Schaltfläche in einer der Menüoptionen in der Aktionsleiste beibehalten, sodass immer dann, wenn ich darauf klicke, eine Selbstbenachrichtigung generiert wird.

    – Venkat Ramarao Potlapalli

    28. Oktober 2014 um 13:22 Uhr

notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
             | Intent.FLAG_ACTIVITY_SINGLE_TOP )

Da Ihre Intent-Flags: FLAG_ACTIVITY_SINGLE_TOP, “onCreate()” nicht aufgerufen werden, wenn die Aktivität erstellt wurde, sollten Sie stattdessen die Parameter in der Methode namens “onNewIntent()” erhalten.

Benutzer-Avatar
Jishant

sollten Sie auch hinzufügen .verpflichten(); und ft1.addToBackStack(null); damit es sich nicht mit dem vorherigen überschneidet und wenn Sie dies nicht hinzufügen ft1.addToBackStack(null); Auf der Rückseite wird Ihre App beendet, also fügen Sie dies entsprechend Ihrer Funktionalität hinzu

String menuFragment = getIntent().getStringExtra("menuFragment");

ft1 = getSupportFragmentManager().beginTransaction();

ft1.addToBackStack(null);

ft1.replace(R.id.frame_container, favoritesFragment).commit();

Es ist eine detaillierte Antwort und ich glaube, wenn Sie sie sorgfältig befolgen. Sie werden Ihr Problem lösen.

Beim Versenden der notification aus Firebase Diese Methode wird zuerst ausgeführt

public class FirebaseMessageService extends FirebaseMessagingService {

private static final String TAG = "MyFirebaseMsgService";
Map<String, String> data;
// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

    if (remoteMessage.getData().size() > 0) {
        removeUserInfoByKeyAsStatic(getApplicationContext(), USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA);
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        data = remoteMessage.getData();


        HashMap<String, String> copyData = new HashMap<>(data);

        //Calling method to generate notification
        sendNotification(data.get("body"), data.get("title"), copyData);
    }

}

dann führst du das obige aus sendNotification(..) Methode. In dieser Methode setze ich die notification data zum SharedPref. Seien Sie nicht beleidigend, wir werden es später sofort entfernen, wenn wir es verwenden.

Ich habe meine benutzt login data und einstellen intent zu unterschiedlich Activity nach meinem roleID

private void sendNotification(String messageBody, String messageTitle, HashMap<String, String> data) {

    // this methods checks my notification data is null ? isNullOrEmptyExt : "simple java is null control method"
    if (!isNullOrEmptyExt(data.get("data"))) { 

        Intent intent;
        final User myInfos = getMyInfos(getApplicationContext()); // this gives me login user data.
        boolean isConsumerOrVolunteer = myInfos.getRoleID() == Constants.ROLES.CONSUMER || myInfos.getRoleID() == Constants.ROLES.VOLUNTEER;
        // I want to show here. You can select diffrent Activity with your data..
        if (isConsumerOrVolunteer) {
            // this set my notification data to SharedPref
            setUserInfoByKeyAsStatic(getApplicationContext(), USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA, data.get("data"));
            intent = new Intent(this, EventListActivity.class);
        } else {
            intent = new Intent(this, ProducerActivity.class);
        }

        // after from here are the generally same. tricks above
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = getString(R.string.default_notification_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentTitle(messageTitle)
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());

    }

}

Wenn Sie schicken notification Diese beiden oben genannten Methoden laufen. Danach klicken Sie also auf die Benachrichtigung auf Ihrem Telefon.. richtig.. Dieser Klickvorgang öffnet die Intent(ActivityName) die du vorher gesetzt hast sendNotification(..) Methode.

Sie klicken zB auf die Benachrichtigung und dein ProducerActivity oder EventListActivity öffnet..

Wenn Ihre Rolle ist Verbraucher oder Freiwilliger ( laut meinen App-Rollen ) Sie setzen die notification data zu SharedPref

   boolean isConsumerOrVolunteer = myInfos.getRoleID() == Constants.ROLES.CONSUMER || myInfos.getRoleID() == Constants.ROLES.VOLUNTEER;
    // I want to show here. You can select diffrent Activity with your data..
    if (isConsumerOrVolunteer) {
        // this set my notification data to SharedPref
        setUserInfoByKeyAsStatic(getApplicationContext(), USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA, data.get("data"));
        intent = new Intent(this, EventListActivity.class);
    } else {
        intent = new Intent(this, ProducerActivity.class);
    }

Sie haben also die geöffnet EventListActivity. Mal sehen, was wir drin machen EventListActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_event_list_main);

    GsonBuilder gsonBuilder = new GsonBuilder();
    gson = gsonBuilder.create();

    // this gives me data from `SharePref`
    String notificationEventDataString = getUserInfoByKeyAsStatic(this, USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA);

    // then check the datastring that comes from SharedPref - simple java null check method
    if(!isNullOrEmptyExt(notificationEventDataString)){
        Bundle bundle = new Bundle();
        bundle.putParcelable(EVENT, gson.fromJson(notificationEventDataString, Event.class));
        removeUserInfoByKeyAsStatic(this, USER_KNOW_CREATED_EVENT_NOTIFICATION_DATA);
        openFragmentWithoutAnimation(this, R.id.drawer_layout, bundle, EventPreviewFragment.class, EVENT_PREVIEW_FRAGMENT);
    }

Sie erhalten die Daten von SharedPref . Dies wird nicht leer sein, denn wenn Sie die bekommen Benachrichtigung wir haben es schon eingebaut sendNotification(..) Methode .

Also stellst du deine data zu bundle und offen Fragment mit bundle data. Unmittelbar nachdem Sie die entfernt haben SharedPref Daten, die meine enthalten notification data

ICH TEILE AUCH MEINE BENUTZERDEFINIERTEN METHODEN MIT IHNEN

Dies ist eine fragmentoffene Methode

public static void openFragmentWithoutAnimation(Context context, int replaceLayout, Bundle bundle, Class<?> fragment, String fragmentTag) {
    Fragment dynamicFragment = null;
    try {
        Class<?> clazz = Class.forName(fragment.getName());
        dynamicFragment = (Fragment) clazz.newInstance();
        System.out.println(clazz.getSuperclass());
        System.out.println(clazz.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

    AppCompatActivity activity = null;
    if (context instanceof AppCompatActivity) {
        activity = ((AppCompatActivity) context);
    }
    if (activity.getSupportFragmentManager().findFragmentByTag(fragmentTag) == null) {
        FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
        if (bundle != null) {
            dynamicFragment.setArguments(bundle);
        }
        transaction.add(replaceLayout, dynamicFragment, fragmentTag);
        transaction.addToBackStack(fragmentTag);
        transaction.commit();
    }
}

Dies sind die Set- und Get-Methoden von SharedPref

public static void setUserInfoByKeyAsStatic(Context context, String key, String value){
    final SharedPreferences prefs = context.getSharedPreferences(
            USER_INFO_PREFS_KEY, Context.MODE_PRIVATE);// Saved token can be accessed only from this app or other apps that shared same id with this app.
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString(key, value);
    editor.apply();
}

public static String getUserInfoByKeyAsStatic(Context context, String key){
    final SharedPreferences controlPrefs = context.getSharedPreferences(
            USER_INFO_PREFS_KEY, Context.MODE_PRIVATE);
    return controlPrefs.getString(key,null);
}

Und das sind die Nullprüfmethoden

public static boolean isNullOrEmpty(String value){

    if(value == null){
        return true;
    }else return value.isEmpty() || value.equals("null");

}

public static boolean isNullOrEmptyExt(String value){

    if(value == null){
        return true;
    }else return value.isEmpty() || value.equals("null") || value.equals(JSON_ARRAY_EMPTY) || value.equals(JSON_OBJECT_EMPTY);

}

1187120cookie-checkSo öffnen Sie eine Fragmentseite, wenn eine Benachrichtigung in Android gedrückt wird

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy