Проверьте, открыто ли приложение во время события GCM onMessage?
Мне интересно, как проверить, открыто ли мое приложение и в настоящее время видно пользователю при получении onMessage()
из GCM. Сначала я просто использовал свой собственный boolean isVisible
, но потом понял, что это ненадежно, потому что, если приложение не открыто, объект, который я использую для доступа к этому флагу, null
. Хотя это само по себе можно было бы использовать, чтобы узнать, открыто ли приложение, это кажется немного беспорядочным. Есть ли способ в Android с системного уровня, чтобы как-то проверить, открыто ли приложение в данный момент, и если пользователь просматривает приложение? Имейте в виду, что приложение может быть запущено, но не видно, потому что пользователь недавно нажал кнопку "домой", отправив его на задний план.
@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
}
}
}
Ответы
Ответ 1
Я бы использовал для этого широковещательные передачи заказов.
В вашем методе onMessage
:
Intent responseIntent = new Intent("com.yourpackage.GOT_PUSH");
sendOrderedBroadcast(responseIntent, null);
В вашей деятельности:
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();
}
}
Другой BroadcastReceiver
public class SecondReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//In this receiver just send your notification
}
}
манифеста:
<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>
В основном в методе onMessage
вы отправляете Intent, который сначала принимается BroadcastReceiver, зарегистрированным внутри YourActivity
, если он запущен и на переднем плане, в противном случае он принимается SecondReceiver
.
Ответ 2
Используйте SharedPreferences, сохраняя значение boolean isVisible, и когда вы получите значение из этой настройки, вы можете добавить значение по умолчанию.
SharedPreferences settings = context.getSharedPreferences("NAME_XXX", Activity.MODE_PRIVATE);
settings.getBoolean("visible", false);
Ответ 3
То, что я всегда делаю, это ссылка на текущую активность.
Я устанавливаю текущую активность в каждом onResume и устанавливаю ее в значение null в каждом onPause.
Если текущая активность равна нулю, приложение не открыто. Если он не является нулевым, вы можете увидеть, открыта ли правильная активность и доставить ее в эту операцию.
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();
}
Ответ 4
То, что сработало для меня:
Создайте окончательные константы класса, внутри него, создайте статические varaiable:
public final class Constants{
public static AppCompatActivity mCurrentActivity;
}
Теперь, по каждому из резюме ваших действий говорим:
@Override
protected void onResume() {
super.onResume();
Constants.mCurrentActivity = this;
}
При получении уведомления проверьте, является ли текущая активность нулевой, если ее нулевое приложение не открыто, если активность не равна нулю, вы можете проверить такие вещи, как:
if(Constants.mCurrentActivity instanceof MainActivity){
((MainActivity) Constants.mCurrentActivity).yourPublicMethodOrStaticObject;
}