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>
Related
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.
I understand that intents are used to start new activities and services and can contain information about these - certain UI options, etc. They can be emitted by some activities or apps to signal that others should begin or end, or that some change should occur.
I don't understand how these are handled by the System at runtime. Do these go to the OS, where they are relayed to the place where they are needed, or do all Activity instances constantly check every single intent that is emitted, to see if they apply?
Also, on that note, can all Activity instances "listen" to all intents and if not, how is this "listening privilege" given?
Do these go to the OS, where they are relayed to the place where they are needed
Yes. After all, the majority of the time, the activity that is to be started does not presently exist.
Also, on that note, can all Activity instances "listen" to all intents
Activities do not "listen" on any Intents. Activities, via the manifest, describe what Intent structures they are interested in, via <intent-filter> elements. The OS then determines the activity to handle any particular startActivity() call (perhaps with the help of the user, via a chooser UI) and starts that activity.
I read some similar questions (for example at this link), but the problem I'm asking is a bit different. In fact, in my case the service is started manually by the startService method, then as a consequence it can not be started using the bindService method.
Suppose we have a package that contains the MainService service and MainServiceActivity activity. In the file "AndroidManifest.xml" this activity is declared with action MAIN and category LAUNCHER. This activity is used to configure the service via the SharedPreferences and start the service by invoking startService method. In other words, typically the user launches the MainServiceActivity and configures/starts the MainService.
Now consider another activity (Let's call it SecondActivity) that is part of another package. Depending on the configuration, the service starts this activity using the startActivity method, so this other activity is running on a separate process than the MainService. As soon as the activity is running, it should inform the service.
At this point, a communication request/reply begins between the MainService and the SecondActivity: the service sends a request and the activity sends a reply.
The communication via messaging might fit, but the MainService is started through startService method, so the bindService method can not be invoked by activities that want to bind to the service.
Then I had an idea that makes use of an additional service (Let's call it UtilityService), which is part of the same package of MainService: the UtilityService could be started using the bindService method. As a consequence:
as soon as the MainService is running, it might perform the bind to the UtilityService;
when the MainService launches an external activity (for example the above SecondActivity), this activity bind to the UtilityService.
In this way, both the MainService and the SecondActivity are connected to the UtilityService, where the latter acts as an intermediary for communication.
Are there alternatives to this idea?
In fact, in my case the service is started manually by the startService method, then as a consequence it can not be started using the bindService method.
You can both bind and start a service, if you wish. It's a bit unusual, but it can be done.
Are there alternatives to this idea?
Binding has nothing in particular to do with services being able to communicate with activities. Using some sort of callback or listener object via binding is a possibility, but it is far from the only one.
You can:
Have the service send a broadcast Intent, to be picked up by the activity
Have the activity send a PendingIntent (e.g., via createPendingResult()) to the service in an Intent extra on the command sent via startService(), to be used by the service to send information back to the activity (or wherever the activity wants it to go, such as a broadcast)
Have the activity pass a Messenger tied to its Handler to the service in an Intent extra on the command sent via startService(), to be used by the service to send information back to the activity
All of those work perfectly well between processes, as well as within a process.
You can use Android Interface Definition Language (AIDL).
You can find an easy to use guide here
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
Common scenario - Activity with a background Service to poll server.
The Service will run periodically via AlarmManager and also perform tasks for the Activity (user hits a button, go fetch something from server).
I'd like to know the best practices here. I think the best design would be the Android LocalService example:
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
However in the example the Activity has a reference to the activity mBoundService but there is no reverse connection (the Service has no way to call the Activity).
What is the best way for the Service to call the Activity?
Do I use Intents, BroadcastReceivers, Messages? How?
I think the best design would be the Android LocalService example: http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
I wouldn't. Use the loosest possible coupling you can stand. Hence, on average, aim for the command pattern with startService() instead of the binding pattern with bindService(). Notably, binding is a bit of a pain when it comes to dealing with configuration changes (e.g., screen rotations).
What is the best way for the Service to call the Activity? Do I use Intents, BroadcastReceivers, Messages? How?
See Notify activity from service
If you need tight coupling between your activity using bindService(), the way you communicate depends on who is originating the communication.
If the Service is originating (due to say an Alarm that has some new information to share), it would typically send a broadcast.
If the Activity is originating (due to say your example "go fetch something from server"), it could be handled asynchronously using AsyncTask or similar. That is, you could fetch from the server in the AsyncTask.doInBackground(), and post the results back to the activity in AsyncTask.onPostExecute. This scenario be a bit more complicated if the requested operation is expected to take a very long time - in which case I would de-couple it, and send a broadcast back from the Service instead.
As written here
When you want to communicate from service to an Activity or Fragment
which did NOT started the service or to communicate from service to multiple activities/fragments then you can use Event Bus or
Broadcast Intents since they can receive callback for an event in any
activity or fragment wherever they are implemented.If you want to
communicate from service to an activity/fragment which started the
service then you can use Pending Intent or Messenger as they can be
put into an Intent extra and passed to Service.
Pending Intent
We can use createPendingResult() which creates a new PendingIntent
object which you can hand to service to use and to send result data
back to your activity inside onActivityResult(int, int, Intent)
callback.
Event Bus
You can have the service raise events which activities or fragments
can listen for and respond to using Event Bus.
Messenger
Messenger is parcelable ,and can therefore be put into an Intent
extra,so your activity can pass this Messenger to the service.Service
will populate Message object with whatever data needs to be
send.
Broadcast Intents
Service can send a broadcast which can be responded by the activity.