2013-04-04 15 views
10

Zastanawiam się, jak sprawdzić, czy moja aplikacja jest otwarta i obecnie widoczna dla użytkownika po otrzymaniu od GCM wersji onMessage(). Najpierw użyłem własnego boolean isVisible, ale potem zdałem sobie sprawę, że nie jest to niezawodne, ponieważ jeśli aplikacja nie jest otwarta, obiekt, którego używam, aby uzyskać dostęp do tej flagi, to null. Chociaż to samo w sobie może być wykorzystane do sprawdzenia, czy aplikacja jest otwarta, wydaje się nieco chaotyczna. Czy jest jakiś sposób na Androida z poziomu systemu, aby sprawdzić, czy aplikacja jest aktualnie otwarta, i czy użytkownik przegląda aplikację? Należy pamiętać, że aplikacja może być technicznie uruchomiona, ale nie jest widoczna, ponieważ użytkownik niedawno nacisnął przycisk "home", wysyłając go na drugi plan.Sprawdź, czy aplikacja jest otwarta podczas zdarzenia GMM onMessage?

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

Odpowiedz

2

Stosować SharedPreferences zapisując logiczną isVisible, a gdy pojawi się wartość od preferencji można dodać wartość domyślną.

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

To, co zawsze robię, to odniesienie do bieżącego działania.

Ustawiam bieżącą aktywność w każdej operacji onResume i ustawię ją na wartość null w każdej chwili.

Jeśli bieżąca aktywność jest zerowa, aplikacja nie jest otwarta. Jeśli nie ma wartości NULL, możesz sprawdzić, czy właściwa czynność jest otwarta i dostarczyć ją do tego działania.

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

Uważaj na wycieki pamięci! – rciovati

+0

@rciovati gdzie jest wyciek? – Klaasvaak

+0

Niestety, nie widzę, aby ustawiono wartość "null" w odniesieniu do "currentActivity", gdy Activity wchodzi w tryb onPause. – rciovati

17

użyłbym transmisje tym celu.

W swojej metodzie onMessage:

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

W swojej działalności:

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

The drugiej BroadcastReceiver

public class SecondReceiver extends BroadcastReceiver { 

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

} 

manifeście:

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

Zasadniczo w metodzie wysyłasz intencję, która jest po raz pierwszy odbierana przez program BroadcastReceiver zarejestrowany wewnątrz YourActivity, jeśli jest uruchomiony i na pierwszym planie, w przeciwnym razie zostanie odebrany przez SecondReceiver.

+2

Dziękujemy! W wierszu po 'Intent responseIntent = new Intent (" com.yourpackage.GOT_PUSH ");' dodałem 'responseIntent.PutExtras (intent);' więc moje dodatki będą kopiować. – shane

0

Rzecz, która pracowała dla mnie:

Tworzenie ostatecznej klasy Stałe, wewnątrz niego, tworzyć varaiable statyczny:

public final class Constants{ 
public static AppCompatActivity mCurrentActivity; 
} 

Teraz, każdy na wznowienie swoich activties powiedzieć:

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

Podczas odbierania powiadomienia sprawdź, czy bieżąca aktywność jest pusta, jeśli jej wartość null, aplikacja nie jest otwierana, jeśli aktywność nie jest pusta, możesz sprawdzić następujące rzeczy:

if(Constants.mCurrentActivity instanceof MainActivity){ 
    ((MainActivity) Constants.mCurrentActivity).yourPublicMethodOrStaticObject; 
} 
Powiązane problemy