问题
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
回答1:
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.
回答2:
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
回答3:
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
来源:https://stackoverflow.com/questions/44039668/keep-activity-alive-in-background-until-user-doesnt-kill-or-close-app