Get data from service android

Android get data from a Service in MainActivity

Do You know if there is any way to start a Service from the MainActivity, send some data and when the service is done, get the data from the Service. For example:

Also, If this is not possible, what alternative do You suggest, in which MainActivity has access to the data from the DataFromInternetService.class.

Note: I don’t want to use LoaderManager, I use Services to do background tasks that don’t effect the UI.

4 Answers 4

To communicate with your service you can use Bound Service:

or you can send your data within: broadcast receiver, database, shared preferences. It depends on your needs.

Instead of using a service to run stuff on the background you should use Async Tasks

you can do the following:

If you want to communicate with your service you have to use bound service and bind to it in your activity. Then create handlers for your activity and also for your service. Using these handlers you can notify your activity once the download is finished. Please let me know if you managed to solve your problem or some further instructions are needed.

That’s the kind of question where any discussion at this point was already finished few years ago, but still bothers us every time we need to choose the most comfortable approach for our app. I don’t thing that I should dive into code samples or low level explanations. You can find more than needed information by yourself.
One thing I can be helpful(I hope so) is to share my approach. When I’m facing issues like how to pass data between two different components? — I treat such situations kind of straight-forward. You need to notify your hungry component(activity in our particular case) that’s fetching was finished an it can get his info from a trustworthy place. Or to be more cruel, pass the data directly to it. This can be achieved by different implementations/solutions but the abstract ideology remains the same.
What can you do? Here are some links :

And still there are even more valuable solutions, but those are enough.

Источник

Android: How can I get the current foreground activity (from a service)?

Is there a native android way to get a reference to the currently running Activity from a service?

I have a service running on the background, and I would like to update my current Activity when an event occurs (in the service). Is there a easy way to do that (like the one I suggested above)?

13 Answers 13

Update: this no longer works with other apps’ activities as of Android 5.0

Here’s a good way to do it using the activity manager. You basically get the runningTasks from the activity manager. It will always return the currently active task first. From there you can get the topActivity.

There’s an easy way of getting a list of running tasks from the ActivityManager service. You can request a maximum number of tasks running on the phone, and by default, the currently active task is returned first.

Once you have that you can get a ComponentName object by requesting the topActivity from your list.

Here’s an example.

You will need the following permission on your manifest:

Warning: Google Play violation

Google has threatened to remove apps from the Play Store if they use accessibility services for non-accessibility purposes. However, this is reportedly being reconsidered.

Use an AccessibilityService

  • You can detect the currently active window by using an AccessibilityService .
  • In the onAccessibilityEvent callback, check for the TYPE_WINDOW_STATE_CHANGEDevent type to determine when the current window changes.
  • Check if the window is an activity by calling PackageManager.getActivityInfo() .

Benefits

  • Tested and working in Android 2.2 (API 8) through Android 7.1 (API 25).
  • Doesn’t require polling.
  • Doesn’t require the GET_TASKS permission.

Disadvantages

  • Each user must enable the service in Android’s accessibility settings.
  • This isn’t 100% reliable. Occasionally the events come in out-of-order.
  • The service is always running.
  • When a user tries to enable the AccessibilityService , they can’t press the OK button if an app has placed an overlay on the screen. Some apps that do this are Velis Auto Brightness and Lux. This can be confusing because the user might not know why they can’t press the button or how to work around it.
  • The AccessibilityService won’t know the current activity until the first change of activity.
Читайте также:  Андроид рей что это

Example

Service

AndroidManifest.xml

Merge this into your manifest:

Service Info

Put this in res/xml/accessibilityservice.xml :

Enabling the Service

Each user of the app will need to explicitly enable the AccessibilityService in order for it to be used. See this StackOverflow answer for how to do this.

Note that the user won’t be able to press the OK button when trying to enable the accessibility service if an app has placed an overlay on the screen, such as Velis Auto Brightness or Lux.

Is there a native android way to get a reference to the currently running Activity from a service?

You may not own the «currently running Activity».

I have a service running on the background, and I would like to update my current Activity when an event occurs (in the service). Is there a easy way to do that (like the one I suggested above)?

  1. Send a broadcast Intent to the activity — here is a sample project demonstrating this pattern
  2. Have the activity supply a PendingIntent (e.g., via createPendingResult() ) that the service invokes
  3. Have the activity register a callback or listener object with the service via bindService() , and have the service call an event method on that callback/listener object
  4. Send an ordered broadcast Intent to the activity, with a low-priority BroadcastReceiver as backup (to raise a Notification if the activity is not on-screen) — here is a blog post with more on this pattern

It can be done by:

Implement your own application class, register for ActivityLifecycleCallbacks — this way you can see what is going on with our app. On every on resume the callback assigns the current visible activity on the screen and on pause it removes the assignment. It uses method registerActivityLifecycleCallbacks() which was added in API 14.

In your service call getApplication() and cast it to your app class name (App in this case). Than you can call app.getActiveActivity() — that will give you a current visible Activity (or null when no activity is visible). You can get the name of the Activity by calling activeActivity.getClass().getSimpleName()

I could not find a solution that our team would be happy with so we rolled our own. We use ActivityLifecycleCallbacks to keep track of current activity and then expose it through a service:

Then configure your DI container to return instance of MyApplication for ContextProvider , e.g.

(Note that implementation of getCurrent() is omitted from the code above. It’s just a static variable that’s set from the application constructor)

Use ActivityManager

If you only want to know the application containing the current activity, you can do so using ActivityManager . The technique you can use depends on the version of Android:

Benefits

  • Should work in all Android versions to-date.

Disadvantages

  • Doesn’t work in Android 5.1+ (it only returns your own app)
  • The documentation for these APIs says they’re only intended for debugging and management user interfaces.
  • If you want real-time updates, you need to use polling.
  • Relies on a hidden API: ActivityManager.RunningAppProcessInfo.processState
  • This implementation doesn’t pick up the app switcher activity.

Example (based on KNaito’s code)

Manifest

Add the GET_TASKS permission to AndroidManifest.xml :

I’m using this for my tests. It’s API > 19, and only for activities of your app, though.

Here’s what I suggest and what has worked for me. In your application class, implement an Application.ActivityLifeCycleCallbacks listener and set a variable in your application class. Then query the variable as needed.

Use this code for API 21 or above. This works and gives better result compared to the other answers, it detects perfectly the foreground process.

I like the idea of the Application.ActivityLifecycleCallbacks . But it can be a bit tricky getting the top activity

  • Your app might have multiple activities
  • Some activities might get destroyed
  • Some activities might go to background

To handle all those cases, you need to track each activity life cycle. This is exactly what I did with my below solution.

It all consolidates into a single call of getTopForegroundActivity() that returns the top foreground activity or null if no activities in the stack or non of them are in the foreground.

Usage

Source

I don’t know if it’s a stupid answer, but resolved this problem by storing a flag in shared preferences every time I entered onCreate() of any activity, then I used the value from shered preferences to find out what it’s the foreground activity.

Here is my answer that works just fine.

You should be able to get current Activity in this way. If you structure your app with a few Activities with many fragments and you want to keep track of what is your current Activity, it would take a lot of work though. My senario was I do have one Activity with multiple Fragments. So I can keep track of Current Activity through Application Object, which can store all of the current state of Global variables.

Источник

Android Services — Tutorial

Using styles and themes in Android. Developing own services and using system services in Android. This tutorial describes how to create and consume Android services.

1. Android Services

1.1. What are services?

A service is a component which runs in the background without direct interaction with the user. As the service has no user interface, it is not bound to the lifecycle of an activity.

Читайте также:  Как перевести прошивку для андроид

Services are used for repetitive and potentially long running operations, i.e., Internet downloads, checking for new data, data processing, updating content providers and the like.

Services run with a higher priority than inactive or invisible activities and therefore it is less likely that the Android system terminates them. Services can also be configured to be restarted if they get terminated by the Android system once sufficient system resources are available again.

It is possible to assign services the same priority as foreground activities. In this case it is required to have a visible notification active for the related service. It is frequently used for services which play videos or music.

1.2. Services and background processing

By default, a service runs in the same process as the main thread of the application.

Therefore, you need to use asynchronous processing in the service to perform resource intensive tasks in the background. A commonly used pattern for a service implementation is to create and run a new Thread in the service to perform the processing in the background and then to terminate the service once it has finished the processing.

Services which run in the process of the application are sometimes called local services .

1.3. Platform service and custom services

The Android platform provides and runs predefined system services and every Android application can use them, given the right permissions. These system services are usually exposed via a specific Manager class. Access to them can be gained via the getSystemService() method. The Context class defines several constants for accessing these services.

An Android application can, in addition to consuming the existing Android platform services, define and use new services. Defining your custom services allows you to design responsive applications. You can fetch the application data via it and once the application is started by the user, it can present fresh data to the user.

1.4. Starting and defining custom services

Custom services are started from other Android components, i.e., activities, broadcast receivers and other services.

1.5. Foreground services

A foreground service is a service that should have the same priority as an active activity and therefore should not be killed by the Android system, even if the system is low on memory. A foreground service must provide a notification for the status bar, which is placed under the «Ongoing» heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.

2. Defining custom services

2.1. Implementation and declaration

A service needs to be declared in the AndroidManifest.xml file and the implementing class must extend the Service class or one of its subclasses.

The following code shows an example for a service declaration and its implementation.

2.2. Start a service

An Android component (service, receiver, activity) can trigger the execution of a service via the startService(intent) method.

Alternatively, you can also start a service via the bindService() method call. This allows you to communicate directly with the service. We discuss that later.

2.3. Service start process and execution

If the startService(intent) method is called and the service is not yet running, the service object is created and the onCreate() method of the service is called.

Once the service is started, the onStartCommand(intent) method in the service is called. It passes in the Intent object from the startService(intent) call.

If startService(intent) is called while the service is running, its onStartCommand() is also called. Therefore your service needs to be prepared that onStartCommand() can be called several times.

What if you call this method twice in your code? Do you have to worry about synchronizing the onStartCommand() method call? No, this method is called by the Android system in the main user interface thread, therefore it cannot be called simultaneously from two different threads.

A service is only started once, no matter how often you call the startService() method.

2.4. Service restart behavior

In its onStartCommand() method call, the service returns an int which defines its restart behavior in case the service gets terminated by the Android platform. You can use the constants, the most common options are described by the following table.

Table 1. Restart options

Service is restarted if it gets terminated. Intent data passed to the onStartCommand method is null. Used for services which manages their own state and do not depend on the Intent data.

Service is not restarted. Used for services which are periodically triggered anyway. The service is only restarted if the runtime has pending startService() calls since the service termination.

Similar to Service.START_STICKY but the original Intent is re-delivered to the onStartCommand method.

Option Description
You can check if the service was restarted via the Intent.getFlags() method. START_FLAG_REDELIVERY (in case the service was started with Service.START_REDELIVER_INTENT) or START_FLAG_RETRY (in case the service was started with Service.START_STICKY) is passed.

2.5. Stopping a service

You stop a service via the stopService() method. No matter how frequently you called the startService(intent) method, one call to the stopService() method stops the service.

A service can terminate itself by calling the stopSelf() method. This is typically done if the service finishes its work.

3. IntentServices for one time tasks

You can also extend the IntentService class for your service implementation.

The IntentService is used to perform a certain task in the background. Once done, the instance of IntentService terminates itself automatically. An example for its usage would be downloading certain resources from the internet.

The IntentService class offers the onHandleIntent() method which will be asynchronously called by the Android system.

4. Communication with services

4.1. Options for communication

There are several possibilities for a communication between an activity and a service. The following description discusses the possible approaches and provides recommendation which to use.

4.2. Using Intent data

In a simple scenario no direct communication is required. The service receives the intent data from the starting Android component and performs its work. No notification is necessary. For example, in case the service updates a content provider, the activity is notified by the content provider and no extra step in the service is necessary. This approach works for local and services running in their own process.

4.3. Using receiver

You can use broadcasts and registered receivers for the communication. For example, your activity can register a broadcast receiver for an event and the service sends outs corresponding events. This is a very typical scenario, in which the service need to signal to the activity that his processing has finished.

This communication flow is depicted in the following graphic.

This approach works for local and services running in their own process.

Android provides the LocalBroadcastManager class in the support library v4. This is a helper class to register for and send broadcasts of Intents to local objects within your process. This approach improves security as the broadcast events are only visible within your process and is faster than using standard events.

4.4. Activity binding to local service

If the service is started in the same process as the activity, the activity can directly bind to the service. This is a relatively simple and efficient way to communicate and recommended for activities which need to have a fast communication layer with the service.

This approach works for local services.

4.5. Handler and ResultReceiver or Messenger

If the service should be communicating back to the activity, it can receive an object of type Messenger via the Intent data it receives from the activity. If the Messenger is bound to a Handler in the activity, the service can send objects of type Message to the activity.

A Messenger is parcelable, which means it can be passed to another process and you can use this object to send Messages to the Handler in the activity.

Messenger also provides the method getBinder() which allows passing a Messenger to the activity. The activity can therefore send Messages to the service.

This approach works for local services running in their own process.

4.6. AIDL for services in a different process

To bind to a service which runs in a different process, you need to use Inter Process Communication (IPC) to community your the data. To do so, you need to create a AIDL file which looks similar to a Java interface, but ends with the .aidl file extension and is only allowed to extend other AIDL files.

This approach is required if you need to bind to a service running in another process, i.e., if your service is consumed by other Android applications.

You can find more information about this approach in the Android developer documentation about AIDL.

5. Scheduling service

See https://www.vogella.com/tutorials/AndroidTaskScheduling/article.html — Android task scheduling to learn how to schedule service periodically.

6. Exercise: Using services and service communication

The following example demonstrates how to use a service to download a file from the Internet based on a button click from an activity. Once done, the service notifies the activity via a broadcast receiver that the download is complete.

In this exercise you use the IntentService class, as this class provides automatic background processing.

Create a new project called com.vogella.android.service.receiver with the activity called MainActivity.

Create the following class for the service.

Add this class to the AndroidManifest.xml file. Also add the permission to write to external storage and to access the Internet. The resulting AndroidManifest.xml file should look similar to the following listing.

Change the layout file of your activity to the following.

Change MainActivity to the following.

If you run your example and press the button, the download should be performed by the service. Once done, the user interface is updated and a Toast with the file name is shown.

Change the setting so that the service runs in its own process. Ensure that the application still works, as broadcast receivers are received across process boundaries.

7. Exercise: Define and consume local service

This exercise demonstrates how to bind to a local service from an activity.

The activity binds itself to the service to access its data.

Create a new project called com.vogella.android.localservice with the activity called MainActivity using the Empty Activity template.

Create the following LocalWordService class.

Register your service in the AndroidManifest.xml file.

Change the layout file of the activity similar to the following example.

Change your activity class to the following code.

Run your application. Via your buttons you can update your list or tell the service to fetch more data.

Источник

Читайте также:  Как почистить андроид без рута
Оцените статью