How to implement an Android detail notification? - java

This has probably been asked before, but I can't find a good way of implementing it. I'm trying to write a program that manages a form of messages, and these messages are received from an external data source. This all works. However, the problem comes when I try to notify the user: I would like to have the notification jump directly to the message when it is touched, but this seems to mess up the back stack. This is probably best explained by example:
I open up the message list, the main activity, and browse for a while.
I hit home and go into another app (let's say Music).
A new message is received. A notification comes up, which I touch. The message detail view is displayed.
Now I hit Back. What I want to have happen is that I return to Music, but unfortunately, Back sends me to the message list, and then hitting Back will return me to music.
The both the list and the detail activities are marked as "singleTop", and the exact flags that I use for the notification Intent are:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
I figure if the Messaging application can do this, why can't I?

I have found one way to do this, but it's still not ideal:
Change the detail activity to have a different task affinity from everything else.
Add android:launchMode="singleTop" and android:excludeFromRecents="true" to the detail activity's manifest entry.
(Optional) Modify the list activity to open the detail activity with FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET. (This makes the task more like the built-in messaging app.)
The only fault to this scheme is that switching back over to the app will always go back to the list activity, but at least it is consistent. If someone else has a better way to do this, I'd love to hear it.

Related

Why are my Firebase In-app messages unreliable in production?

In-app messages work well in test mode, but seem to be very unreliable in production. I made campaigns with "Modals" as the message layout. The simplest possible messages, without any pictures. If I set countries as the targets, no messages seem to be shown in the target countries.
I have 2 campaigns without any country targets and those messages get shown, but still just sometimes. The first of these campaigns informs the user they have an opportunity to reach Level 1.
The message get shown about 50% of the times it should be shown (once per device). Sometimes the message get shown so quickly that it just flashes by, so it is impossible to read the text. It closes before the user closes it. The second of these campaigns inform the user when they have reached Level 1. It is the same result as described above here.
My calls to logEvent are from methods, which are directly called from the onresume method in the Main activity of the app. They are called according to certain conditions, not every time onresume is called. My calls look for instance like this:
FirebaseAnalytics.getInstance(this).logEvent("gyro_access", Bundle.EMPTY);
What can be done to make the In-app messages work in a reliable way in production?
I got this to work now. I used this method instead to trigger the messages:
FirebaseInAppMessaging.getInstance().triggerEvent()
I also updated Gradle, so the latest version of com.google.firebase:firebase-inappmessaging-display was used.
So the solution to my problem was either using the triggerEvent-method or updating Gradle.

Since when is the phone charging/discharging

I wanted to learn more about the Android Services / Broadcasts, so I started a simple project, to create a battery monitoring app. It turned out pretty good, I'm using it for a few days now, but I want to add a new function: to show since when is the phone charging/discharging.
First I thought that I would create two static fields in my BoradcastReciever extension class, where I get and publish the data about the battery, one for the actual state (charging/discharging), and one for the time, when the change in state happened. This way, I could just subtract from the current time the last change, and know exactly since when is the phone charging/discharging.
But there is a problem with this solution: It won't show the correct data at first, when a user starts the app. I wouldn't make a big deal of it, but I saw that Android tracks this data somewhere, because inside my phone settings I found this information, so why take the hard way.
So my question is: is there an easy way to get from the Android system the date/time (no matter what format) of the last charging state change?
I looked at the BatteryManager reference but there are no constants named after what I seek, and which I could use, to get the information from the Intent of my receiver.
The Android OS tracks the connect/disconnect of a power source, but does not make this data accessible to apps. You have to record this all yourself, using intent filters.
The two intent filters to use are android.intent.action.ACTION_POWER_CONNECTED and android.intent.action.ACTION_POWER_DISCONNECTED; with these, you can monitor when the power source is connected and disconnected.
You can find information about this process explained incredibly clearly here. Another blog describing the process can be found here.

android app design: Viewflipper or Activities?

I'm planing some kind of information app for android and I'm not sure what technical design is best (because this is my first real android app).
The app which observes the latest information from an server consists of 4 screens:
Main screen -> shows the information (consists of a thread which updates the information by server push)
Configuration screen -> you come here from main screen if you'd like
to configure the information type you want to see.
message screen 1 -> you come here from main screen to send new messages to the server. The screen consists of a radiobutton list where you have to specify the type of information you have to send.
message screen 2 -> You come here from message screen 1. Here you can type the messages and send it to the server.
My thought is either using 4 Activities each containing one view or using just one Activity which contains a ViewFlipper of these 4 Views. What is the best approach and why?
Activities have their name for a reason. Each "action/activity" should be placed in a seperate activity. The user want's to configure something? Send him to the preference activity. The user wants to take a picture? Send him to a photo activity. And so on.
Therefore I think you should have 3 activities here when you split this by actions:
Main screen (user activity "read information/messages")
Configuration screen (user activity "change preferences")
Message screen (user activity "send a message")
For the last one you could use a ViewFlipper if you want to split the sending into two different layouts.
What advantages does this have?
Well, first of all you don't have a big ball of code in one activity that handles everything. Certainly that's possible, but can get somewhat ugly. Maintainablility here.
Also remember that we are still in a mobile environment. Yes phones are really powerful these days, but they still have very short run times on battery. So don't waste battery when you don't have to. Which would mean in case of one giant activity that everytime the user wants to send just a message, he has to load all the other stuff with it. Unneccessary code executed -> unneccessary CPU cycles -> battery drained for no reason.
Apart from that it's convinient for you because the framework supports you this way. For example: the backstack handles a lot of stuff for you already, e.g. you don't have to manage all the back-key logic (you would have to keep track of the layout and the back key depencies otherwise).
If you want to make use of androids intent system for 3rd party apps, this is also very useful. You can control access to your activities on a per-type basis. E.g. allow other apps to call your message activity, but not your preference activity. If you have one big activity this becomes difficult, with some intent extra parsing just to determine which screen the other apps intents to display. And that's propably the biggest reason why activities are activities. Apps can work on a action-base with each other.

Empty (or fill) Recent Apps List

I have developed a baby app where I need to lock all keys and ways out of the app, in order to be able to hand over the phone to my daughter. I used the "replace home screen" method to capture the home key, and that works great. All other hard keys (except power button, but that's not an issue since it's not easily pressed anyway) are locked. But the often discussed long press of home key is still launching the recent apps and offers a way out (which of course the daughter finds almost instantly).
I have seen other apps in market (toddler lock and more) work around this by emptying the recent apps list (or filling it with an icon that leads back to the baby app), but I have no idea of how to accomplish this. Anyone have a solution? How do I fill the recent apps from my app? Toddler lock even resets the recent apps after the lock-app is exited.
You could create an activity in your application that does nothing, and start it with an intent with the FLAG_ACTIVITY_NEW_TASK flag set. Fire this intent however many times you need to fill the history (my Incredible has 8 spots). For repopulating the history, look into ActivityManager.RecentTaskInfo.getRecentTasks (int maxNum, int flags)
See Documentation
It looks like you need to hold the GET_TASKS permission
The intents that originally fired those apps are stored as baseIntent, so you should be able to store them yourself(don't forget the extras), and re-fire them in order to repopulate the history list.
This is a hack, but it should work
Edit: After playing with this a little, it looks like you would need to have 8 different activities for this method to work, which is not realistic.
You need to do what is described in Mobius's post, but also set android:taskAffinity="" on the dummy activity elements in the android manifest file.

Prevent duplicate activities

So, I'm both new to Java and to creating android apps, but not new to programming. I've read through most of the developer.android.com site, but I haven't been able to find this:
I want to make sure that a certain activity isn't running more than once at the same time. So we have a task somewhat like this:
Activity A) a TabActivity, which launches
Activity B) a ListView that, on-click, opens up
Activity C) which is the interface for a mediaplayer object
Right now, whenever somebody presses the back-button whilst in C (Which is a likely thing, because they're going to listen to a streaming 1-hour long mp3) and then presses another list item, instead of returning to C, C is opened a second time, and two streams are playing. Of course, I'd want only one instance of C running, and I want a second click on the list item to bring C back to the front. This could also be useful for notification intents.
I've been messing around with the flags (especially FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_REORDER_TO_FRONT), but no success so far.
If someone could help me out here I could focus on my next challenge - making it a real feed reader :P
Thanks in advance,
You need to flag your actvity as either "singleTask" or "singleInstance" in your manifest. I can't remember the exact differences between the 2, but either should do what you want. SingleInstance just does something different with the stack.
Example :
<activity android:name="MainActivity" android:launchMode="singleInstance"></activity>
You can handle new calls to startActivity() from the same activity instance with onNewIntent()
I've got it!
For those reading this question and wanting to know the summary: I mistakenly thought more then one activity was running, but it appeared more MediaPlayer instances where running. I made my mediaplayer a class member and am now controlling it from the onStart() event.
I am using SharedPreferences to check if the stream needs to reset and change source, or continue running and just show the interface.
Thanks for all your reactions. Really helped me out.
Just Edit the package names in .xml
EX: com.org.MainActivity
change to
.org.MainActivity
It works for me.....yup

Categories

Resources