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)
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.
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);
}
}
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.
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);
}
Broadcast-Empfänger? developer.android.com/reference/android/content/…
– James
28. Oktober 2014 um 12:43 Uhr
Könnten Sie es bitte näher erläutern, ich bin neu bei Android
– Venkat Ramarao Potlapalli
28. Oktober 2014 um 12:47 Uhr