Push notification click using TaskStackBuilder - google-cloud-messaging

I'm setting an activity, Receiver, as the content intent for a notification.
Intent clickIntent = new Intent(context, Receiver.class);
mBuilder.setContentIntent(PendingIntent.getActivity(context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Inside Receiver Activity, I'm starting activities which are intended to be opened using TaskStackBuilder in the following way.
Intent intent = new Intent(this, Class.forName(className));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder.create(this).addParentStack(Class.forName(className)).addNextIntent(intent).startActivities();
When the app is in the background and a notification click happens, it resumes the ParentActivity. Especially when device goes to idle and comes back. Any help? I'm cracking my head on this.

For an Android app, you should also declare android:launchMode in your androidManifest.xml file.
As discussed in the Android documentation:
An instruction on how the activity should be launched. There are four modes that work in conjunction with activity flags (FLAG_ACTIVITY_* constants) in Intent objects to determine what should happen when the activity is called upon to handle an intent.
They are:
"standard"
"singleTop"
"singleTask"
"singleInstance"
The default mode is "standard".
Solution given in this SO post - resuming an activity from a notification might also help.

Related

Kotlin: Start an activity from a thread

I try to program an kids-launcher.
I search for my problem three days but I do not find a solution (I am a beginner in android/kotlin)
I want to start an app and after a while (when the time for the kids is elapsed) I want to come back to my launcher
I wrote the function
fun openApp(context: Context, packageName: String?) {
context.startActivity(context.packageManager.getLaunchIntentForPackage(packageName!!))
}
I started an app and after a while (when the time for the kids is elapsed) I want to come back to my launcher
openApp(this, packageName)
timer.schedule(10000) {
openApp(this, "PackageNameMyLauncher")
}
But it does not work.
when I write "openApp(applicationContext, packageName)" instead, than it works a little bit. But when the app is closed and I press the home button than it won´t work.
I think I didn´t understand some fundamental at the moment.
In the thread there is no context
I also tried to run a pendingIntent with an alarmManager
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
val mPendingIntent = PendingIntent.getActivity(
this,
123456, //PendingIntentId,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
)
val mgr = this.getSystemService(Context.ALARM_SERVICE) as AlarmManager
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, mPendingIntent)
System.exit(0) //finish()
but that is also not working
I know it is not an answer, but when I was a beginner what I lacked was some kind of upper-level design ideas
I don't think Android provides the ability to schedule app opening without user's intention. And also your timer will be destroyed when you will remove application from processes.
I think your best bet will be to design app that way, that it will be unavailable till some time will elapse. You can save the last timestamp when the app became unavailable on the backend or in shared preferences and later on you can compare it with current timestamp, which you will get each time you open the app. If the
currentTimeStamp - savedTimeStamp >= timeLimit you will make further logic of your app available, otherwise you will display some kind of a message.

System applies night mode to views added in service (TYPE_APPLICATION_OVERLAY), but how to apply night mode manually?

I have a LinearLayout that I inflate and add to screen from a service as TYPE_APPLICATION_OVERLAY. This view changes to dark mode when I change the theme from system settings for the whole phone. But when I want to set the night mode manually in my app, this view doesn't change. It only obeys the system theme.
Note that I also have an activity from which I start the service, and I have no trouble setting dark/light mode for that activity manually. But it does not affect the service view, which stays the same as the system theme.
For reference, I have tried AppCompatDelegate methods inside the service, but it doesn't work + plus my activity loses serviceConnection to the service. I have also tried inflating the view with a new ContextThemeWrapper, which did not work either.
Bottom line: How do I manually change the theme for the views added in a foreground/background service?
After days of research and trials, I have concluded that this is not possible. It all comes down to what context is used in the service. According to this question with many detailed answers, service context cannot inflate layouts with custom themes, the system will always inflate them with the default system theme.
If anyone finds a way, I'll be happy to learn.
Try to look here: https://gist.github.com/chrisbanes/bcf4b11154cb59e3f302f278902eb3f7
It is working for me
The code snippet:
fun createNightModeContext(context: Context, isNightMode: Boolean): Context {
val uiModeFlag = if (isNightMode) Configuration.UI_MODE_NIGHT_YES else Configuration.UI_MODE_NIGHT_NO
val config = Configuration(context.resources.configuration)
config.uiMode = uiModeFlag or (config.uiMode and Configuration.UI_MODE_NIGHT_MASK.inv())
return context.createConfigurationContext(config)
}

Kotlin activity restart

How to restart the onCreate after coming back from another activity?
Using below to
val intent = Intent(this, WritePage::class.java)
startActivity(intent)
When im finished
finish()
So i’m back to the previous page. How can i restart this page from onCreate?
This is the offical documentation of the lifecycle of an app. If you finish an activity you can only restart that activity by creating a new instance of it. If you want to reuse it you should only pause that activty so you can easily resume that same instance of the activity (as Chris Shaw already mentioned).

MediaPlayer issues - audio file only plays back once

I'm trying to implement a basic MediaPlayer in an app, and have the button change states depending on whether the clip is playing, playback is completed, or playback is manually interrupted (by pressing the same button).
With the code below, I get the following results:
On first load, the audio plays back fine.
If I press the ImageButton a second time during playback, the playback stops. When I press it again, the playback resumes from the timestamp in which it was stopped (I thought this was strange behaviour more typical of a "pause()".
Once the playback is completed, the button change works perfectly, however I can not replay the audio file a second time. When I press start, it starts playing back, then immediately transitions to playbackcompleted, without actually playing the audio.
I've been scouring through other posts / google / android documentation, but haven't found a solution as yet.
I have also tried so far:
setLooping(true); - this had no effect at all, other than the setOnCompletionListener never being reached. The audio did not replay at all.
In the onCompletion method, setting the seekTo() to several different values (0, 100), and using log messages including the "getCurrentPosition()" to confirm it was actually doing it, but even when this confirms that it's starting from position 0, or 100, the result is still the same (no audio is heard and completion occurs immediately).
In the onCompletion method, several combinations of calling "stop()", "prepareAsync()" or even prepare(). The results were the same, however on subsequent attempts (i.e. attempt 2, 3, etc) to playback, when the onCompletion method was called, I started getting various errors for calling stop() / prepare() methods in the incorrect state.
final ImageButton pauseButton = (ImageButton) rootView.findViewById(R.id.playButton1);
final MediaPlayer mediaPlayer = MediaPlayer.create(getActivity().getApplicationContext(), R.raw.ch01_01);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
pauseButton.setImageResource(R.drawable.play_button);
}
});
pauseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.prepareAsync();
pauseButton.setImageResource(R.drawable.play_button);
} else {
mediaPlayer.start();
pauseButton.setImageResource(R.drawable.stop_button);
}
}
});
Any help would be appreciated!
P.S. I'm using all of this code in the onCreateView method for a Fragment in my application. Just in case anyone thinks that might be relevant.
Apparently this issue is simply my Samsung Galaxy S2, as the same code works perfectly as expected on my Nexus 7 (2013) running Lollipop 5.0.1.
The issue on the Galaxy S2 includes the following:
Once an MediaPlayer is in the PlaybackCompleted state, it will not play the same file a second time when play is pressed
Attempting to run Methods in the PlaybackCompleted state (which should be valid according to Android documentation) seem to do something (i.e. seekTo(0); will actually seek to 0, but the audio file will never play a second time.

Testing an activity 4 clicks deep using Robotium

I have a home activity ActivityA, which has button that creates an intent, sets up some Extras and calls ActivityB. This in turn calls ActivityC , and in turn calls ActivityD.
I don't want to have to write a test case that opens ActivityA and proceeds to drill through 4 activities to get to the one I want to test. How can I set up the Extras required by ActivityD when it launches to prevent errors in my code. For example before I call the intent that launches activityD it sets up an Extra which ActivityD then uses.
Thanks
Robotium gives you an option to launch an activity with a given intent, you will need to determine the intent that you need in order to launch the activity correctly. If you look in logcat it might give you the details that you need to launch the activity correctly. If you are unsure what to look for post the logcat logs of the time between clicking the element on Activity C and Activity D launching and i can try to look for you.