Подтвердить что ты не робот

Выполнить код, когда приложение Android закрыто/отправлено на задний план

У меня есть приложение для Android, которое отправляет некоторые данные в веб-службу. Мне нужно отправить эти данные, как только приложение будет закрыто или отправлено на задний план. Но как это сделать?

Мое текущее решение - запустить его в OnPause() в моей домашней деятельности, но мне нужно, чтобы это выполнялось независимо от того, какую активность он выполняет при закрытии приложения. Возможно ли это, или мне нужно добавить Метод OnPause для всех видов деятельности?

4b9b3361

Ответ 1

Edit

Этот ответ служит только для одной цели, т.е. для запуска всех операций в коде onPause(). Это не позволяет запускать код, когда ваше приложение отправляется на задний план.

Оригинальный ответ

Сделайте операцию с именем YourBasicActivity и переопределите ее метод onPause() и продолжите каждую операцию из YourBasicActivity

Ответ 2

Прежде чем вы решите использовать этот код, сначала проверьте это решение fooobar.com/questions/26541/...!


Чтобы проверить, отправлено ли ваше приложение на задний план, вы можете вызвать этот код на onPause() или onStop() для каждого действия в вашем приложении:

 /**
   * Checks if the application is being sent in the background (i.e behind
   * another application Activity).
   * 
   * @param context the context
   * @return <code>true</code> if another application will be above this one.
   */
  public static boolean isApplicationSentToBackground(final Context context) {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(1);
    if (!tasks.isEmpty()) {
      ComponentName topActivity = tasks.get(0).topActivity;
      if (!topActivity.getPackageName().equals(context.getPackageName())) {
        return true;
      }
    }

    return false;
  }

Для этого вы должны включить это в свой AndroidManifest.xml

<uses-permission android:name="android.permission.GET_TASKS" />

Ответ 3

Это метод, который я использовал, и кажется, что он работает очень хорошо:

У меня есть класс приложений верхнего уровня, который расширяет приложение как таковое

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {

Вам также необходимо зарегистрировать этот объект приложения в файле манифеста:

<application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:name=".MyApplication">

Обратите внимание, как я также реализую интерфейс ActivityLifeCycleCallbacks. Этот интерфейс имеет следующие методы:

public static interface ActivityLifecycleCallbacks {
    void onActivityCreated(android.app.Activity activity, android.os.Bundle bundle);

    void onActivityStarted(android.app.Activity activity);

    void onActivityResumed(android.app.Activity activity);

    void onActivityPaused(android.app.Activity activity);

    void onActivityStopped(android.app.Activity activity);

    void onActivitySaveInstanceState(android.app.Activity activity, android.os.Bundle bundle);

    void onActivityDestroyed(android.app.Activity activity);
}

Вам необходимо реализовать эти методы, а затем зарегистрировать эти события в своих приложениях onCreate() следующим образом

@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(this);
}

Затем это вызовет обратный вызов (объект MyApplication) всякий раз, когда происходит процесс жизненного цикла активности, например onCreate(), onPause и т.д. В вашем onActivityPaused() вы можете проверить, было ли это приложение вызвано или нет, вызывая метод @peceps: isApplicationSentToBackground (...)

Вот как выглядит мой код тогда...

/**
 * Application.ActivityLifecycleCallbacks methods
 */
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {

}

@Override
public void onActivityStarted(Activity activity) {
}

@Override
public void onActivityResumed(Activity activity) {
}

@Override
public void onActivityStopped(Activity activity) {
    try {
        boolean foreground = new ForegroundCheckTask().execute(getApplicationContext()).get();
        if(!foreground) {
            //App is in Background - do what you want
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}

@Override
public void onActivityPaused(Activity activity) {
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}

@Override
public void onActivityDestroyed(Activity activity) {
}

Создайте новый класс для проверки Foreground (это задача async.). См. проверка приложения Android на переднем плане или нет? для более подробной информации.

class ForegroundCheckTask extends AsyncTask<Context, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Context... params) {
        final Context context = params[0];
        return isAppOnForeground(context);
    }

    private boolean isAppOnForeground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (appProcesses == null) {
            return false;
        }
        final String packageName = context.getPackageName();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }
}

Ответ 4

Может быть, это может быть полезно, скажите, если бы это сработало для вас. только когда вы возвращаетесь с фона, значение активности будет 0 (ноль) остальное время будет числом выше 0 (ноль), когда onRestart() выполняется.

public class FatherClass extends Activity {

private static int activities = 0;

public void onCreate(Bundle savedInstanceState, String clase) {
    super.onCreate(savedInstanceState);
}

protected void onRestart()
{
    super.onRestart();
    if(activities == 0){
        Log.i("APP","BACK FROM BACKGROUND");
    }
}

protected void onStop(){
    super.onStop();
    activities = activities - 1;
}

protected void onStart(){
    super.onStart();
    activities = activities + 1;
}

}

Все ваши классы должны перейти от этого класса, чтобы это работало.

Объяснение. onStart выполняется так, что действие "видимо" и onStop, когда действие "не видно". Поэтому, когда ваш APP (он говорит, что APP не активен) переходит в фоновый режим, все действия "не видны", поэтому они запускают метод onStop, поэтому идея заключается в ADD ONE каждый раз, когда активность начальный и СУБТРАКТ ОДИН каждый раз, когда выполняются действия, поэтому, если значение переменной "действия" равно нулю, это означает, что все действия, которые начались в какой-то момент, теперь не видны, поэтому, когда вы APP вернулись с фона и выполнили метод onRestart для активности в "фронте", которую вы можете проверить, происходит ли из фона или просто перезапускает действие.

Ответ 5

переопределить метод onStop() вашей домашней операции и запустить там код.

Ответ 6

Я думаю, вам нужно запустить свой собственный поток, который будет проверять, все ли запущенные действия в фоновом режиме или уничтожены.

MyBasicActivity extends Activity
{
    private static ArrayList<MyBasicActivity> activities=new ArrayList<MyBasicActivities);
    private boolean started;

    public void onCreate()
    {
       activities.add(this);
    } 

    public void onDestroy()
    {
       activities.remove(this);
    } 

    public void onStart()
    {
       this.started=true;
    }

    public void onPause()
    {
       this.started=false;
    }

    public boolean isStarted()
    {
       return started;
    }
}

MyThread implements Runnable
{
    private ArrayList<MyBasicActivity> activities;

    public MyThread(ArrayList<MyBasicActivity> activities) 
    {
        this.activities=activities;
    }

    void run()
    {
          while(!stopped)
          {
              boolean inBackground=true;
              for(MyBasicActivity activity:activities)
              {
                 if(activity.isStarted())
                 {
                      inBackground=false;
                      break;
                 }
              }
              if(inBackground)
                  //run your code here;
              sleep(10000); //10 secs
          }

    }
}