9

Ho incontrato un requisito ma non sono in grado di ottenere il modo corretto di implementazione e quindi ho bisogno del vostro aiuto.App Android, stato attività (in esecuzione, non in esecuzione, primo piano/sfondo)

Cosa voglio fare? - Voglio eseguire un'azione a seconda notifica ottengo come segue:

  1. Quando applicazione è aperta e in primo piano cioè visibile agli utenti e ottengo la notifica mostro semplicemente un popup per iniziare la mia attività B
  2. Quando l'app è chiusa cioè né in background né in primo piano e ricevo la notifica Iniziamo prima la mia applicazione e poi avvio l'attività B
  3. Quando l'app è in esecuzione MA in background cioè in ritroso ma non visibile all'utente, quindi voglio iniziare la mia attività B senza riavviare l'applicazione. Inoltre, in questo caso quando l'utente preme di nuovo l'attività B, dovrebbe vedere lo schermo che avevano lasciato prima di inviarlo allo sfondo.

Cosa ho fatto? Ho raggiunto il punto n. 1 e n. Voglio raggiungere il punto # 3. Ho provato il seguito

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; 
} 

Tuttavia questa restituisce true in entrambi i casi, il punto # 2 e # 3, quindi non sono in grado di distinguere solo # 3.

Inoltre ho provato il seguito in ogni attività che ho,

@Override 
protected void onPause() { 
    super.onPause(); 
    saveIsPausedInPref(true); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    saveIsPausedInPref(false); 
} 

Ma, inoltre, non dà il risultato desiderato coz se l'applicazione viene inviato a sfondo premendo il tasto Home mia preferenza avrà isPaused = true e se l'utente rimuove l'app dal recente, allora rimarrà true e di nuovo non riuscirò a differenziare i punti 2 e 3 quando arriva la notifica.

Ci scusiamo per l'intera storia, ma spero di essere in grado di spiegare la mia esigenza.

Grazie in anticipo. :)

Edit:

 <activity 
      android:name=".HomeActivity" 
      android:screenOrientation="portrait" > 
     </activity> 
     <activity 
      android:name=".ChatProfileActivity" 
      android:screenOrientation="portrait" > 
     </activity> 
+0

Così come ho potuto capire, è necessario passare per l'applicazione che si trovava al primo piano quando tasto 'back' utente ha premuto l'Activity 3? –

+0

Sì potrebbe essere se è un modo possibile. Idealmente avrei bisogno di richiamare la mia app da sfondo e iniziare la mia attività B su di essa. –

+0

mostra il file manifest, voglio vedere le dichiarazioni di attività A e B. –

risposta

2

Per distinguere caso # 2 e # 3 caso, è possibile effettuare le seguenti operazioni:

lancio ActivityB se non è il caso # 1. In ActivityB.onCreate() fare questo:

super.onCreate(...); 
if (isTaskRoot()) { 
    // ActivityB has been started when the app is not running, 
    // start the app from the beginning 
    Intent restartIntent = new Intent(this, MyRootActivity.class); 
    startActivity(restartIntent); 
    finish(); 
    return; 
} 
... rest of onCreate() code here... 
+1

Grazie David, ho usato questo solo per ora. :) Stavo cercando una risposta migliore. Finché non troverò rimarrà con questo. –

+0

Cosa intendi per "risposta migliore". Cosa c'è di sbagliato in questo? Forse la tua architettura è rotta perché stai cercando di differenziare tra tutti questi casi. Che cosa stai cercando di raggiungere esattamente? –

1

So che u capito 1 & 2 ma mal giusti i miei toughts nel caso in cui u fatto qualcos'altro e u voglia di dare un'occhiata.

  1. Come sapere se l'app è in primo piano?

    this dovrebbe essere il modo corretto, se in primo piano quindi inviare un evento via eventbus, EventBus è il mio modo preferito per il tuo.

  2. Avviare l'app in una specifica attività con stack? dare un'occhiata a TaskStackBuilder con questo answer, fornirà informazioni su come questo in modo corretto.
  3. Riprendere l'app con una certa attività mantenendo lo stack corrente? Verifica lo stato dell'app con i callback, quindi quando ricevi la notifica apri l'attività senza FLAG_ACTIVITY_NEW_TASK. Questo dovrebbe fare il tricl.
+0

Potrebbe per favore sottolineare su "Controllare lo stato dell'app con i callback"? –

+0

Nei callback delle attività controllare se ha colpito suActivityPaused e non suActivityDestroyd. Questo ti permetterà di capire lo stato della tua app. – EE66

+0

Ok. Lo farò un tentativo.:) Grazie –

1

Se si modifica per non mostrare alcun pop-up, solo per passare all'attività B sempre (distrutto, sfondo o in primo piano), non è necessario alcun controllo. Solo per lavorare con le flag FLAG_ACTIVITY_X sulla tua notifica (è GCM questa notifica?).

LaunchMode on Manifest

Intent Flags

È possibile utilizzare il metodo onNewIntent per controllare l'intento, se proviene da una notifica e iniziare attività B.

Notification Proper BackStack

4

Sotto codice funziona per me

In AndroidManifes t.xml

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

MyApplication.java

public class MyApplication extends Application { 
private ActivityLifecycleCallbacks myLifecycleHandler; 

@Override 
    public void onCreate() { 
     super.onCreate(); 
     myLifecycleHandler=new MyLifecycleHandler(); 
     registerActivityLifecycleCallbacks(myLifecycleHandler); 
    } 
} 

MyLifecycleHandler.java

public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks { 
    private static final String TAG = MyLifecycleHandler.class.getSimpleName(); 

private static int resumed; 
private static int paused; 
private static int started; 
private static int stopped; 

@Override 
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 
} 

@Override 
public void onActivityDestroyed(Activity activity) { 
} 

@Override 
public void onActivityResumed(Activity activity) { 
    ++resumed; 
} 

@Override 
public void onActivityPaused(Activity activity) { 
    ++paused; 
    Log.d(TAG, "application is in foreground: " + (resumed > paused)); 
} 

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

@Override 
public void onActivityStarted(Activity activity) { 
    ++started; 
} 

@Override 
public void onActivityStopped(Activity activity) { 
    ++stopped; 
    Log.d(TAG, "application is visible: " + (started > stopped)); 
} 

public static boolean isApplicationVisible() { 
    return started > stopped; 
} 

public static boolean isApplicationInForeground() { 
    return resumed > paused; 
} 
} 

Ora utilizzando myLifecycleHandler metodi che è possibile ottenere tutti gli stati che vi serve.

isApplicationInForeground significa -> Almeno un'attività è in stato visibile.

isApplicationVisible mezzi -> Atleast un'attività è lì che è cominciato, ma non fermato, significa che l'applicazione è in esecuzione stato

se isApplicationInForeground vale isApplicationVisible sarà sempre vero, ma viceversa non è vero

+0

Che differenza c'è tra isApplicationVisible e isApplicationInForeground? –

+0

ho modificato la mia risposta – Akhil

Problemi correlati