Keep activity alive in background until user doesn't kill or close app?
Asked Answered
I

3

3

Can I keep Android activity alive in background, until user doesn't kill or close the application.

I want to detect user clicks in background some specific hardware button clicks, as onKeyDown is not available in service, I need to keep my activity alive in background until user kills the app.

Does android allows such behavior ?

Update :

I was able to solve this using following approach :

1] Use foreground service, Ref : https://developer.android.com/guide/components/services.html#Foreground

2] To handle media button click use below approach after Android 21 + ( Use this code in onCreate() of your foreground service ) :

mediaSession = new MediaSessionCompat(this, TAG);
        mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
        mediaSession.setCallback(new MediaSessionCompat.Callback() {
            @Override
            public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
                if (mediaButtonEvent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {
                    KeyEvent event = (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                    if (KeyEvent.KEYCODE_HEADSETHOOK == event.getKeyCode() && event.getAction() == KeyEvent.ACTION_DOWN) {
                        Log.e(TAG, "Media Button clicked");
                        handleHeadphoneClick();
                    }
                }
                return false;
            }
        });
        mediaSession.setActive(true);

Ref : https://developer.android.com/guide/topics/media-apps/mediabuttons.html

Imprison answered 18/5, 2017 at 5:58 Comment(7)
just if you google it How to keep my service until i close the app you will find a solutionGaler
Keeping service alive is not a problem detecting hardware button click in service is not allowed, even we try some broadcasts catching, such hardware broadcasts does not work in higher android versions.Imprison
You are able to do onKeyDown & onKeyUp click events in service also. @pcjSinh
No onKeyDOwn is available in activity developer.android.com/reference/android/app/…, android.view.KeyEvent) not in service developer.android.com/reference/android/app/Service.htmlImprison
you shouldn't do that, and there is no way for Activity. You can and should use Service for that.Pompidou
@Vlad Matvienko yep your right Service is good choice in this case but hardware button click detection is not possible in service, again if we try to catch broadcasts for those hardware buttons they work in lower version but not in higher android versions.Imprison
hey @pcj check the below answer, it works for you.Sinh
M
0

Right from developer.android.com

A service is a component that runs in the background to perform long-running operations or to perform work for remote processes. A service does not provide a user interface. For example, a service might play music in the background while the user is in a different application, or it might fetch data over the network without blocking user interaction with an activity. Another component, such as an activity, can start the service and let it run or bind to it in order to interact with it. A service is implemented as a subclass of Service and you can learn more about it in the Services developer guide.

So, as long as you create a service, and the user exits your app it will still run. Just like the example above.

This should give you all the information you need: Visit this link

Mccarron answered 18/5, 2017 at 6:3 Comment(2)
Keeping service alive is not a problem detecting hardware button click in service is not allowed, even we try some broadcasts catching, such hardware broadcasts does not work in higher android versions.Imprison
he was asking about keeping activity alive not serviceBarbarossa
S
0

Simply, just create a new service class. Here, using this class you are able to see the Hardware button click event in log. Here i am using volume key as a onKeyEvent.

public class Xtra extends Service {


@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();

    final BroadcastReceiver vReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
            boolean isScreenOn = powerManager.isScreenOn();


            if (!isScreenOn) {

                PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
                PowerManager.WakeLock mWakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "YourService");
                mWakeLock.acquire();
                // The screen has been locked
                // do stuff...
                Log.e("Do what you want to do from this service...", "Here screen is off..which do not show or work anything due to screen is off");
Toast.makeText(getActivity(), "Here screen is off..which do not show or work anything due to screen is off", Toast.LENGTH_SHORT).show();

} else {
                Log.e("Do what you want to do from this service...", "Here screen is on, works...");
Toast.makeText(getActivity(), "Here screen is on, works...", Toast.LENGTH_SHORT).show();

            }
        }

    };
    registerReceiver(vReceiver, new IntentFilter("android.media.VOLUME_CHANGED_ACTION"));
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    return super.onStartCommand(intent, flags, startId);
    //43200000 schedules notification on every 12 hours
}


@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    Log.e("BgService", "::>> Service Stopped...");
    super.onDestroy();
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}
}

Make a button click event from your activity to start the service. It will starts your service in background.

Button btnSave;
btnSave.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
      //From here service starts when you click on a button.
           startService(new Intent(activity, Xtra.class));
        }
    });

Don't forgot to add this service to your manifest.

<service android:name=".Xtra">
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </service>

When you click on btnSave, it will starts your service. Now just move to home screen and click the volume key, you will surely get the result as it works fine for me.

Sinh answered 18/5, 2017 at 6:35 Comment(4)
Hey thanks for giving me some hint here your answer is similar to this developer.android.com/reference/android/support/v4/media/… I will try this approach in my service.Imprison
Not at all. Always here to help you.Sinh
Note that this solution/action, while it works, is not "officially" part of the SDK. See here: https://mcmap.net/q/89634/-how-to-receive-volume-changed-events-for-the-voice-in-call-stream-typeAndrosterone
Also, it only worked for me when I added android.media.VOLUME_CHANGED_ACTION to the manifest, and/or added android.intent.action.MEDIA_BUTTON as a trigger for the receiver. (not sure which change fixed it)Androsterone
I
0

Update :

I was able to solve this using following approach :

1] Use foreground service, Ref : https://developer.android.com/guide/components/services.html#Foreground

2] To handle media button click use below approach after Android 21 + ( Use this code in onCreate() of your foreground service ) :

mediaSession = new MediaSessionCompat(this, TAG);
        mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
        mediaSession.setCallback(new MediaSessionCompat.Callback() {
            @Override
            public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
                if (mediaButtonEvent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {
                    KeyEvent event = (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                    if (KeyEvent.KEYCODE_HEADSETHOOK == event.getKeyCode() && event.getAction() == KeyEvent.ACTION_DOWN) {
                        Log.e(TAG, "Media Button clicked");
                        handleHeadphoneClick();
                    }
                }
                return false;
            }
        });
        mediaSession.setActive(true);

Ref : https://developer.android.com/guide/topics/media-apps/mediabuttons.html

Imprison answered 22/5, 2017 at 6:52 Comment(1)
The specific code in this answer didn't work for me (Android 9). I found this alternate version which worked: https://mcmap.net/q/410018/-listen-to-volume-buttons-in-background-serviceAndrosterone

© 2022 - 2024 — McMap. All rights reserved.