I want to start activities when users click on push notifications. It works fine for activity A, but does not work for another activity B, it does not fully work. What happened to activity B is that if the app is not running, clicking on the push notification will correctly start activity B. However, if the app is already running, clicking on the push notification just open the current screen.
Here is how I set up the push notification:
Intent rewardsIntent = new Intent(this, ActivityRewards.class);
rewardsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationUtils.createNotification(this, R.string.reward_notification, getResources().getString(R.string.reward_notification), "You have been rewarded", rewardsIntent);
And the static method in NotificationUtils to create the Push Notification:
public static void createNotification(Context context, int notificationId, String title, String text, Intent resultIntent) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ico_launcher)
.setContentTitle(title)
.setContentText(text);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setAutoCancel(true);
mBuilder.setOngoing(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(notificationId, mBuilder.build());
}
In AndroidManifest.xml, I declared the activity as follows:
<activity android:name=".ActivityRewards"
android:label="#string/my_rewards"
android:exported="true">
</activity>
This has puzzled me for few days. Any help would be very much appreciated. Thanks.
I managed to make this work by adding launchMode declaration for ActivityRewards as below:
<activity android:name=".ActivityRewards"
android:label="#string/my_rewards"
android:launchMode="singleTask"
android:exported="true">
Related
I have a long audio file that has different sections.
I have a Map containing where those sections start.
I want to implement skipToNext() and skipToPrevious methods for it.
I have access to the map inside BackgroundAudioTask.
I have implemented onSkipToNext like this:
#override
Future<void> onSkipToNext() async => () {
print('next pressed');
final currentIndex = _getCurrentTrackIndex(_player.position);
print(currentIndex);
if (currentIndex < _tracks.length - 1) {
_player.seek(
Duration(milliseconds: _tracks[currentIndex + 1]['start']),
);
}
};
The _tracks looks like this:
[{id: 1, title: INTRODUCTION, start: 0}, {id: 2, title: Next track, start: 68347},]
But when I press on MediaControl.skipToNext from the notification or
AudioService.skipToNext(); from Flutter UI.
It is not working i.e next pressed is not showing in the console and the audio is not working.
Am I doing something wrong?
Can't I press MediaControl.skipToNext if there is no queue?
If I cannot do so, how can I implement such a feature?
Note: I am using just_audio for playing audio
Edit: Here's my systemActions
systemActions: [
MediaAction.seekTo,
MediaAction.seekForward,
MediaAction.seekBackward,
MediaAction.skipToNext,
MediaAction.skipToPrevious,
],
Solved: Incorrect implementation of onSkipToNext() was the case of the problem as the accepted answer suggests.
Assuming everything else works and it's just these two skip actions that don't work, the first thing you will need to do is include skipToNext and skipToPrevious in the controls parameter of AudioServiceBackground.setState rather than systemActions. systemActions is only for things that are not clickable buttons (e.g. seekTo).
You must also pass androidEnableQueue: true to AudioService.start if you want these queue-skipping actions to work on Android.
For completeness, I'll also just mention that none of the notification buttons (or headset buttons) will work on Android unless you have declared the broadcast receiver in your AndroidManifest.xml file:
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
But aside from all of those things, I notice your code contains a subtle programming error that is unrelated to audio_service. Your implementation of onSkipToNext simply returns a closure () { ... } so even if this callback is being called, the code inside the closure isn't being called. So you need to replace => () { ... } by { ... }.
I am developing an app in Xamarin.Forms, before I was trying to make a master detail page to become my MainPage when I logged in to my app, this I have already achieved. Now I have the problem that when I use the button behind the phone my app is miimiza and goes to the background which is the behavior I hope, but when I return to my app does not continue showing my master detail page, but returns to my LginPage.
It is as if my app was running twice or at least there were two instances of LoginPage existing at the same time, this is because in my LoginPage I trigger some DisplayAlert according to some messages that my page is listening through the MessaginCenter and they are they shoot twice.
Can someone tell me how I can return the same to my app on the master detail page and not restart in the strange way described?
LoginView.xaml.cs:
public partial class LogonView : ContentPage
{
LogonViewModel contexto = new LogonViewModel();
public LogonView ()
{
InitializeComponent ();
BindingContext = contexto;
MessagingCenter.Subscribe<LogonViewModel>(this, "ErrorCredentials", async (sender) =>
{
await DisplayAlert("Error", "Email or password is incorrect.", "Ok");
}
);
}
protected override void OnDisappearing()
{
base.OnDisappearing();
MessagingCenter.Unsubscribe<LogonViewModel>(this, "ErrorCredentials");
}
}
Part of my ViewModel:
if (Loged)
{
App.token = token;
Application.Current.MainPage = new RootView();
}
else
{
MessagingCenter.Send(this, "ErrorCredentials");
}
Thanks.
I hope this is in Android. All you can do is, you can override the backbuttonpressed method in MainActivity for not closing on back button pressed of the entry page. like below, you can add some conditions as well.
public override void OnBackPressed()
{
Page currentPage = Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();
if (currentPage != null)
{
if (currentPage.GetType().Name == "HomePage" || currentPage.GetType().Name == "LoginPage")
{
return;
}
}
base.OnBackPressed();
}
When you press the Home button, the application is paused and the
current state is saved, and finally the application is frozen in
whatever state it is. After this, when you start the app, it is
resumed from the last point it was saved with.
However, when you use the Back button, you keep traversing back in
the activity stack, closing one activity after another. in the end,
when you close the first activity that you opened, your application
exits. This is why whenever you close your application like this, it
gets restarted when you open it again.
Answer taken from this answer. The original question asks about the native Android platform, but it still applies here.
It means you have to Use Setting Plugin or save data in Application properties.
You have to add below code in App.xaml.cs file:
if (SettingClass.UserName == null)
MainPage = new LoginPage();
else
MainPage = new MasterDetailPage();
For Setting Plugin you can refer this link.
In AndroidManifext.xml, I have :
<activity
android:name=".mypackage.ChildActivity"
android:label="Child"
android:parentActivityName=".mypackage.ParentActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".view.activities.ParentActivity" />
</activity>
Inside ParentActivity, I have a few fragements, A, B, C. At fragment C, I launch ChildActivity when clicking a button. When backing to ParentActivity, I am not landing on Fragment C, but Fragment A. It appears that ParentActivity is relaunched or initialized again.
In ChildActivity, I have:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
As a comparison, I also tried to replace ChildActivity with a Fragment D and backing from fragment D correctly lands on fragment C.
Where did I miss for the ChildActivity implementation?
Edited:
Just noticed that when clicking "Back" button on device, it properly backs to Fragment C of ParentActivity, but if hitting the "<" button at the left top corner in Child Activity, that's where issue arises.
Thanks in advance!
Shawn
Remove the mentioning parent from your childActivity. Like below. Because android already maintains the stack of navigations
<activity
android:name=".mypackage.ChildActivity"
android:label="Child"
android:parentActivityName=".mypackage.ParentActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize">
</activity>
i want my application should give me notification and on clicking on notification another activity should open like whatsapp notifications
this is my code c an anyone help?????
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// sendNotification(remoteMessage.getNotification().getBody());
//Bundle bundle=new Bundle();
//bundle.putString("msgBody",remoteMessage.getNotification().getBody());
//intent use for start this activity after click on notification
Intent intent = new Intent(getApplicationContext(),Secondactivity.class);
String valu=remoteMessage.getNotification().getBody();
intent.putExtra("notificationmessage",valu);
**strong text** //here we are telling system after clicking you have to come on mainactivity
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//here we are giving rights to main activity.FLAG_ONE_SHOT useful to indicate this pending intent can use only once
PendingIntent pendingintent=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
//notificationcompat useful for creating notification layout
NotificationCompat.Builder notificationbuilder=new NotificationCompat.Builder(this);
notificationbuilder.setContentText(remoteMessage.getNotification().getBody());
notificationbuilder.setContentTitle("FCM NOTIFICATION");
notificationbuilder.setSmallIcon(R.mipmap.ic_launcher);
notificationbuilder.setAutoCancel(true);
notificationbuilder.setContentIntent(pendingintent);
NotificationManager notificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationbuilder.build());
}
You have to add an extra parameter in the message content for identifying the type. Then create notification manager with different activity based on that type value.
ex:
switch (type){
case 1:
notification manager for activity A
break:
case 2:
notification manager for activity B
break:
}
I'm going to use home button (Action bar App icon) as back button. I got it to work but not in the way i intended.
My MainActivity is an activity which holds (1) a drawer that shows a list of categories. And a Fragment that displays a list of items in the category chosen in the drawer.
when a item in the list is clicked, a new DetailActivity is started to show the details.
here starts the problem:
From the DetailActivity when i press Back button, it returns to the MainActivity as it was before clicking the item to show details. That is what I expect. However, when use home button as Up navigation, it starts the MainActivity as if I opened the app again. Not showing the list that was previously being shown.
I read in developer documents that for fragments I have to use: .add(detailFragment, "detail") And .addToBackStack() then commit.
But what am I suppose to add in add(---,"---"). And then how should I use it?!
this is my codes:
the method is the MainActivity that shows the content:
public void refreshDisplay(Context context, View view, String category, int i) {
List<Lesson> lessonByCategory = datasource.findByCategory(category, i);
final ListView lv = (ListView) view.findViewById(R.id.listView);
final ArrayAdapter<Lesson> adapter = new LessonListAdapter(context, lessonByCategory);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
Log.i(LOGTAG, "onListItemClick called");
ArrayAdapter<Lesson> m_adapter = adapter;
// get the Lesson object for the clicked row
Lesson lesson = m_adapter.getItem(position);
Intent intent = new Intent(MainActivity.this, LessonDetailActivity.class);
intent.putExtra(".model.Lesson", lesson);
intent.putExtra("isStared", isStared);
startActivityForResult(intent, LESSON_DETAIL_ACTIVITY);
}
});
}
In my LESSON_DETAIL_ACTIVITY that shows the detail content I have this code to enable up navigation for home button:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// I have some other cases here
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
And finally in the Manifest I used the code below to introduce MainActivity as the parrent of LessonDetailActivity:
<activity
android:name=".LessonDetailActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.MainActivity" />
</activity>
I want the Home button as up navigation to behave like back button so that when its clicked it takes me to the MainActivity as it was before opening the LessonDetailActivity. The code above doesn't do that and every time I press Home in the action bar it starts the MainActivity from scratch.
Could anyone help me with this please?
I also should say that I'm new so I'd appreciate it if the answers were detailed.