2013-04-04 14 views
10

Ich frage mich, wie überprüft werden kann, ob meine Anwendung geöffnet und derzeit für den Benutzer sichtbar ist, wenn Sie eine onMessage() von GCM erhalten. Zuerst benutzte ich nur meine eigene boolean isVisible, aber dann erkannte ich, dass dies nicht zuverlässig ist, denn wenn die App nicht geöffnet ist, ist das Objekt, das ich verwende, um auf dieses Flag zuzugreifen, null. Während dies an sich verwendet werden könnte, um zu sehen, ob die App geöffnet ist, scheint es ein bisschen chaotisch. Gibt es eine Möglichkeit in Android von einer Systemebene, irgendwie zu prüfen, ob die Anwendung gerade geöffnet ist und ob der Benutzer die App sieht? Denken Sie daran, dass eine App technisch ausgeführt werden kann, aber nicht sichtbar ist, weil ein Benutzer kürzlich die "Home" -Schaltfläche gedrückt hat, um sie in den Hintergrund zu stellen.Überprüfen Sie, ob die App während eines GCM onMessage-Ereignisses geöffnet ist.

@Override 
protected void onMessage(Context arg0, Intent arg1) { 
    String turn = intent.getExtras().getString("turn"); 
    if (turn.equals("yours"){ 
     if (/*app is open*/){ <------------------ what can go here? 
      // dont generate a notification 
      // display something in the game instead 
     } 
     else{ 
      // generate notification telling player its their turn 
     } 
    } 
} 

Antwort

2

Verwenden SharedPreferences die boolean isVisible speichern, und wenn Sie den Wert aus der Präferenz bekommen können Sie einen Standardwert.

SharedPreferences settings = context.getSharedPreferences("NAME_XXX", Activity.MODE_PRIVATE); 
settings.getBoolean("visible", false); 
1

Was ich immer mache, ist ein Verweis auf die aktuelle Aktivität.

Ich setze die aktuelle Aktivität in jedem onResume auf diese und setze sie in jedem onPause auf null.

Wenn die aktuelle Aktivität null ist, ist die App nicht geöffnet. Wenn es nicht null ist, können Sie sehen, ob die richtige Aktivität offen ist, und sie an diese Aktivität übergeben.

GCMIntentService:

public static Activity currentActivity; 
public static final Object CURRENTACTIVIYLOCK = new Object(); 

    @Override 
protected void onHandleIntent(Intent intent) { 
    synchronized(CURRENTACTIVIYLOCK) { 
     if (currentActivity != null) { 
      if (currentActivity.getClass() == CorrectActivity.class) { 
       CorrectActivity act = (CorrectActivity)currentActivity; 
       act.runOnUiThread(new Runnable() { 
        public void run() { 
         // Notifiy activity 
        } 
       }); 
      } else { 
       // show notification ? 
      } 
     } else { 
      // show notification 
     } 
    } 
} 

CorrectActivity:

@Override 
    protected void onResume() { 
     synchronized (GCMIntentService.CURRENTACTIVITYLOCK) { 
       GCMIntentService.currentActivity = this; 
      } 
     } 
     super.onResume(); 
    } 

@Override 
    protected void onPause() { 
     synchronized (GCMIntentService.CURRENTACTIVITYLOCK) { 
      GCMIntentService.currentActivity = null; 
     } 
     super.onPause(); 
    } 
+2

Vorsicht bei Speicherlecks! – rciovati

+0

@rciovati wo ist das Leck? – Klaasvaak

+0

Leider habe ich nicht gesehen, dass Sie den Verweis auf 'currentActivity' auf 'null' gesetzt haben, wenn die Aktivität in onPause geht. – rciovati

17

Ich würde, um Broadcasts zu verwenden, das zu tun.

In Ihrer onMessage Methode:

Intent responseIntent = new Intent("com.yourpackage.GOT_PUSH"); 
sendOrderedBroadcast(responseIntent, null); 

In Ihrer Aktivität:

public class YourActivity extends Activity { 

    final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      //Right here do what you want in your activity 
      abortBroadcast(); 
     } 
    }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     //..... 
    } 

    @Override 
    protected void onPause() { 
     unregisterReceiver(mBroadcastReceiver); 
     super.onPause(); 
    } 

    @Override 
    protected void onResume() { 
     IntentFilter filter = new IntentFilter("com.yourpackage.GOT_PUSH"); 
     filter.setPriority(2); 
     registerReceiver(mBroadcastReceiver, filter); 
     super.onResume(); 
    } 
} 

Die anderen BroadcastReceiver

public class SecondReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     //In this receiver just send your notification 
    } 

} 

Manifest:

<activity 
    android:name=".YourActivity" 
    android:label="@string/app_name"> 
    <intent-filter> 
     <action 
      android:name="android.intent.action.MAIN" /> 
     <category 
      android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity> 

<receiver 
    android:name=".SecondReceiver"> 
    <intent-filter 
     android:priority="1"> 
     <action 
      android:name="com.yourpackage.GOT_PUSH" /> 
    </intent-filter> 
</receiver> 

Grundsätzlich in der onMessage Methode senden Sie eine Absicht, die zuerst von der BroadcastReceiver registriert innerhalb YourActivity empfangen wird, wenn es im Vordergrund ausgeführt wird, sonst wird es von der SecondReceiver empfangen.

+2

Danke! In der Zeile nach "Intent responseIntent = new Intent" ("com.yourpackage.GOT_PUSH"); "Ich habe" responseIntent.PutExtras (intent) "hinzugefügt, damit meine Extras kopiert werden. – shane

0

Die Sache, die für mich gearbeitet:

Erstellen einer endgültigen Klassenkonstanten, im Inneren, statische varaiable erstellen:

public final class Constants{ 
public static AppCompatActivity mCurrentActivity; 
} 

nun auf jeder auf Lebenslauf Ihrer activties sagen:

@Override 
    protected void onResume() { 
     super.onResume(); 
     Constants.mCurrentActivity = this; 
    } 

Wenn Sie eine Benachrichtigung erhalten, überprüfen Sie, ob die aktuelle Aktivität Null ist, wenn die Null-Anwendung nicht geöffnet ist. Wenn die Aktivität nicht null ist, können Sie folgende Dinge überprüfen:

if(Constants.mCurrentActivity instanceof MainActivity){ 
    ((MainActivity) Constants.mCurrentActivity).yourPublicMethodOrStaticObject; 
} 
Verwandte Themen