我试图写一个应用程序,做一些具体的时候,它被带回前台后一段时间。是否有一种方法可以检测应用程序是被发送到后台还是被带到前台?
当前回答
通过使用下面的代码,我能够得到我的应用程序的前台或后台状态。
更多关于它的工作细节,强文本点击这里
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Context context;
private Toast toast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
}
private void showToast(String message) {
//If toast is already showing cancel it
if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
toast.show();
}
@Override
protected void onStart() {
super.onStart();
showToast("App In Foreground");
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
showToast("App In Background");
}
}
}
其他回答
我在谷歌Analytics EasyTracker中使用了这个,它起作用了。可以将其扩展为使用简单整数来完成您想要的任务。
public class MainApplication extends Application {
int isAppBackgrounded = 0;
@Override
public void onCreate() {
super.onCreate();
appBackgroundedDetector();
}
private void appBackgroundedDetector() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
EasyTracker.getInstance(MainApplication.this).activityStart(activity);
}
@Override
public void onActivityResumed(Activity activity) {
isAppBackgrounded++;
if (isAppBackgrounded > 0) {
// Do something here
}
}
@Override
public void onActivityPaused(Activity activity) {
isAppBackgrounded--;
}
@Override
public void onActivityStopped(Activity activity) {
EasyTracker.getInstance(MainApplication.this).activityStop(activity);
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
}
编辑2:我在下面写的东西实际上是行不通的。谷歌拒绝了一个包含对ActivityManager.getRunningTasks()调用的应用程序。从文档中可以明显看出,这个API仅用于调试和开发。一旦我有时间更新下面的GitHub项目,我就会更新这篇文章,使用一个使用计时器的新方案,几乎一样好。
编辑1:我已经写了一篇博客文章,并创建了一个简单的GitHub存储库,使这非常容易。
公认的和最高评价的答案都不是最好的方法。排名最高的答案是isApplicationBroughtToBackground()的实现,它不处理应用程序的主活动屈服于同一个应用程序中定义的活动,但它有不同的Java包的情况。我想到了一种方法,在这种情况下行得通。
在onPause()中调用它,它会告诉你你的应用程序是否因为另一个应用程序已经启动而进入后台,或者用户已经按下了home键。
public static boolean isApplicationBroughtToBackground(final Activity activity) {
ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
// Check the top Activity against the list of Activities contained in the Application's package.
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
try {
PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
for (ActivityInfo activityInfo : pi.activities) {
if(topActivity.getClassName().equals(activityInfo.name)) {
return false;
}
}
} catch( PackageManager.NameNotFoundException e) {
return false; // Never happens.
}
}
return true;
}
The principal problem is that you have to get an specific behavior when you start an activity from background. If you override your onPause() and onResume() methods, you'll have a close answer, but not the solution. The problem is that onPause() and onResume() methods are called even if you don't minimize your application, they can be called when you start an activity and later you press the back button to return to your activity. To eliminate that problem and to know really when your application comes from background, you must to get the running process and compare with your process:
private boolean isApplicationBroughtToBackground() {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(getPackageName())) {
return true;
}
}
return false;
}
现在你必须声明一个布尔变量:
public boolean wasPaused = false;
并询问你的活动何时进入后台:
@Override
public void onPause(){
super.onPause();
if(isApplicationBroughtToBackground())
wasPaused = true;
}
现在,当你的活动再次出现在屏幕上时,在onResume()方法中询问:
@Override
public void onResume(){
super.onResume();
if(wasPaused){
lockScreen(true);
}
wasPaused = false;
}
就是这样。现在,当您的活动进入后台,稍后用户将其带到前台时,锁定屏幕将出现。
如果你想为你的应用程序的任何活动重复这个行为,你必须创建一个活动(可以是BaseActivity),放这个方法,你所有的活动都必须从BaseActivity继承。
我希望这对你有帮助。
问候!
基于Martín marconcini的回答(谢谢!)我终于找到了一个可靠(而且非常简单)的解决方案。
public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
private static boolean isInBackground = false;
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
if(isInBackground){
Log.d(TAG, "app went to foreground");
isInBackground = false;
}
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
@Override
public void onConfigurationChanged(Configuration configuration) {
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int i) {
if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
Log.d(TAG, "app went to background");
isInBackground = true;
}
}
}
然后将其添加到Application类的onCreate()中
public class MyApp extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
registerActivityLifecycleCallbacks(handler);
registerComponentCallbacks(handler);
}
}
我设法监控应用导航到后台和回前台通过实现一个BaseActivity,利用onResume, onPause和onStop活动回调的使用。这是我的实现。
override fun onResume() {
super.onResume()
if (AppActivityState.state == AppState.ON_LAUNCHED) {
// We are in the first launch.
onLaunched()
} else {
if (AppActivityState.state == AppState.ON_BACKGROUND) {
// We came from background to foreground.
AppActivityState.state = AppState.ON_FOREGROUND
onForeground()
} else {
// We are just navigating through pages.
AppActivityState.state = AppState.RESUMED
}
}
}
override fun onPause() {
super.onPause()
// If state is followed by onStop then it means we will going to background.
AppActivityState.state = AppState.PAUSED
}
override fun onStop() {
super.onStop()
// App will go to background base on the 'pause' cue.
if (AppActivityState.state == AppState.PAUSED) {
AppActivityState.state = AppState.ON_BACKGROUND
onBackground()
}
}
在创建BaseActivity之后,你只需要将这个activity扩展到应用程序中的任何activity。
在这些类型的实现中,您可以准确地检测到以下内容: onBackground >应用程序将进入后台 onForeground >应用将返回前台 onLaunch >应用程序刚刚打开
我希望这对你有帮助:)
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件