Get Android app launch source from Application context - android

Is it possible from the Application class onCreate method (not Activity!!) to identify how the app has been launched?, like if it was from the Launcher or Push Notification or a boot complete broadcast receiver etc'
Also, is there a way to get the Intent object (if exists) which caused the launch, from the Application onCreate?
Basically what I am interested is to recognize if it was from Launcher or not and get the Intent if exists. All this, in the Application class, and not Activity.

First of all, I don't believe it's possible to check whether the app has been launched by the launcher directly, but rather with a process of elimination.
Technically there is a way to get the Intent, which was used to launch the App in the Application's onCreate.
Since you can use Intent to start Activities, not Applications, you can use registerActivityLifecycleCallbacks to register an onActivityCreated callback in your App's onCreate, which gives you access to the created activity.
Once you have the activity object, you can call activity.getIntent() to get the Intent object.
The onActivityCreated callback also gives you a savedInstanceState Bundle, which you can utilize to determine, whether the App was already running before or not.

Related

Does app launch LAUNCH Activity after app upgrade?

In my next app version I need to have a boolean flag enableNotification. So in order everything works fine in my app after user launches my app in MainActivity it sets this flag to false and I saves it to SharedPreferences. If it doesn't go to MainActivity and sets this flag to Shared my app will work wrong.
So my question is whether after user upgrades his app on Google Play to the newer version (the old version doesn't have this flag in SharedPref), will it go first to MainActivity and not to the Activity the user was before (SecondActivity, ThirdActivity...)? Or it's better to save this flag to the DB, so in onCreate() set this flag to false?
Updating an App on Android force closes it.
So the next time the user opens the app, it will start the Activity that you declared with the ACTION_MAIN Intent Filter in the Android Manifest (probably MainActivity)
If your app depends on the SharedPreference 'enableNotification' to works, then you need to do the checking in Application class first.
Initialize the value in Application class first if the app never have the value before. Do the checking in application onCreate() because Application class is called before Activity as the documentation says:
void onCreate ()
Called when the application is starting, before any activity, service,
or receiver objects (excluding content providers) have been created.
Implementations should be as quick as possible (for example using lazy
initialization of state) since the time spent in this function
directly impacts the performance of starting the first activity,
service, or receiver in a process. If you override this method, be
sure to call super.onCreate().

How to detect user activity/inactivity in Android service/background application?

How to detect user activity/inactivity in android service/background application - from same or other applications?
I want to know that user stop touching screen and not busy with another activity to show notifiation popup. Not sure is there no other method than use AccessibilityService.
One of the ways is to know that from reading the Android logs
Use a boot receiver to setup the AlarmManager (and of course also check to start the polling from your main Activity too, for the case when your app is installed and the system is not booted) and have the AlarmManager send an Intent for another receiver.
I think they answered it in this question to do what you are looking for:
android: running a background task using AlarmManager
Define a interface in activity and service.
in oncreate of activity set reference to activity in service method.
Now you have activity reference for entire service lifetime.
another way to do this is, application class, same application class is shared by activity and service, so you can both of these from each other using application class.
If you want see from applications then use broadcastreceivers that is the only wau

Start activity/send intent from object instance within service

I have the following situation: A service is running in the background of my application and regularly receives UDP packets. It uses an instance of my HandleMessageAgent class which analyses every message and shall start a new activity if necessary.
I would like to perform the following task: No matter which activity is in the front (as long as the service is running) I would like to inform the user about an incoming message under certain circumstances. I also need to update the information regularly as long as it is valid. Afterwards it should be closed automatically.
At first I thought about using a Dialog, but I think I cannot use it when the activity is not visible. Therefore I decided to use an activity, as it can be started from a service all the time.
I want to start the activity within the HandleMessageAgent object (in a method). My problem is, that I do not know how I can define an Intent to start an activity within an object, as the Context is not clear to me.
Is there a more elegant way to perform this task? Or can anybody help me with starting an activity from an object method within a service? Thank you!
There are two situations to consider:
When your service need to notify user your activities are not active, because some other app is active. In this case you should notify user via a system-preferred way: Android Notifications. You should not forcefully show dialogs or activities if user is using some other app. That's what notifications are for.
If one of your activities is active (no matter which) then your service should send a broadcast and interested activities should listen for it and act upon it. That way your service will not depend upon specific activity and will not need to keep track which activities are active at the moment the notification must be shown.
You can make your object Parcelable and add it to the Intent that will start the Activity.
Or you can put it in a subclass of Application because that instance is shared between your activities and your services (as long as they're in the same process)
You might need the "START_NEW_TASK" flag on the Intent

Android: How do you use ListView to start an Activity?

I am writing my first Android application, and I have been struggling with this for over a week. It seems like the basis of all android applications yet I cannot understand how to do it. For example, if you are in the Android Settings Menu, you have a list and you click on "About", it takes you to the "About" Actvitiy etc.
I need my app to do that as well, I have 5 menu items that I want to be able to select and go to the Activity for the selected item.
Currently I have my items in a string_array, but I have nothing that corresponds the string name with the activity name I want to goto.
Can somebody please give me some tips? I am really struggling over here, kind of overwhelmed with the documentation. Thank you in advance!
You should start from reading the Developer's Guide
A particular section you should note is the Application Fundamentals and Intents
Activating components: intents
Content providers are activated when
they're targeted by a request from a
ContentResolver. The other three
components — activities, services, and
broadcast receivers — are activated by
asynchronous messages called intents.
An intent is an Intent object that
holds the content of the message. For
activities and services, it names the
action being requested and specifies
the URI of the data to act on, among
other things. For example, it might
convey a request for an activity to
present an image to the user or let
the user edit some text. For broadcast
receivers, the Intent object names the
action being announced. For example,
it might announce to interested
parties that the camera button has
been pressed.
There are separate methods for
activating each type of component:
An activity is launched (or given something new to do) by passing an
Intent object to
Context.startActivity() or
Activity.startActivityForResult(). The
responding activity can look at the
initial intent that caused it to be
launched by calling its getIntent()
method. Android calls the activity's
onNewIntent() method to pass it any
subsequent intents.
One activity often starts the next one. If it expects a result back from
the activity it's starting, it calls
startActivityForResult() instead of
startActivity(). For example, if it
starts an activity that lets the user
pick a photo, it might expect to be
returned the chosen photo. The result
is returned in an Intent object that's
passed to the calling activity's
onActivityResult() method.
A service is started (or new instructions are given to an ongoing
service) by passing an Intent object
to Context.startService(). Android
calls the service's onStart() method
and passes it the Intent object.
Similarly, an intent can be passed to Context.bindService() to establish
an ongoing connection between the
calling component and a target
service. The service receives the
Intent object in an onBind() call. (If
the service is not already running,
bindService() can optionally start
it.) For example, an activity might
establish a connection with the music
playback service mentioned earlier so
that it can provide the user with the
means (a user interface) for
controlling the playback. The activity
would call bindService() to set up
that connection, and then call methods
defined by the service to affect the
playback.
A later section, Remote procedure calls, has more details about binding
to a service.
An application can initiate a broadcast by passing an Intent object
to methods like
Context.sendBroadcast(),
Context.sendOrderedBroadcast(), and
Context.sendStickyBroadcast() in any
of their variations. Android delivers
the intent to all interested broadcast
receivers by calling their onReceive()
methods.
For more on intent messages, see the
separate article, Intents and Intent
Filters.
Check how its done here in the Settings app. They use a PreferenceActivity and embed the Intent in the XML file.
<com.android.settings.IconPreferenceScreen
android:title="#string/radio_controls_title"
settings:icon="#drawable/ic_settings_wireless">
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.WirelessSettings" />
</com.android.settings.IconPreferenceScreen>

Breaking the task barrier

I have an android app. I added an intent filter to one of my activities, so that if a url is clicked in the browser app, my activity can be launched. Looks like this:
<data android:host="www.mysite.com" android:scheme="http"></data>
this works well. The problem is that every time my activity is launched from the browser, a new instance of the activity is created, inside the browser app's task, instead of recycling any existing instance that may be in the system already.
This is a problem for me because this activity uses a singleton. If I allow more than one instance of this activity to exist, I can get into some weird situations where the two instances are in conflict when they try to share the singleton. I checked and can see that although the activity instances may be in separate tasks, they do share the same singleton instance.
An ideal solution for me would be if I could somehow bring a pre-existing instance of my application to the foreground, and launch or resume the target activity within whatever pre-existing instance of my app happens to be running.
So I tried this:
Register above filter to point to dummy activity which is just a catcher.
Dummy activity creates a broadcast intent, and tries to broadcast 'create me' message to system.
Real target activity is set to listen for this broadcast message. Hopefully if there is already an instance of the activity in the system, it will come to the foreground. If no instance yet, that's ok, allow creation in the browser task.
Not sure if this makes sense. My basic goal is to limit the activity to one instance in the system. The app is just social media app which has a login state that needs to be preserved. The singleton mentioned above preserves that login state, so I want to have only one around in the system, instead of allowing multiple login instances running around which would be a headache for the user.
Thanks
You can set the activity launch mode to singleTop to achieve this.
android:launchMode
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".
https://developer.android.com/guide/topics/manifest/activity-element.html#lmode

Categories

Resources