2013-04-04 43 views
10

Tôi tự hỏi làm cách nào để kiểm tra xem ứng dụng của tôi có đang mở hay không và hiển thị với người dùng khi nhận được onMessage() từ GCM. Lúc đầu, tôi chỉ sử dụng boolean isVisible của riêng mình, nhưng sau đó tôi nhận ra điều này không đáng tin cậy, bởi vì nếu ứng dụng không mở, đối tượng tôi sử dụng để truy cập cờ đó là null. Trong khi điều này trong chính nó có thể được sử dụng để xem nếu ứng dụng được mở, có vẻ như một chút lộn xộn. Có cách nào trong Android từ cấp hệ thống bằng cách nào đó kiểm tra xem ứng dụng hiện có đang mở hay không và liệu người dùng có đang xem ứng dụng không? Hãy nhớ rằng một ứng dụng có thể đang chạy về mặt kỹ thuật, nhưng không thể hiển thị, bởi vì người dùng gần đây đã nhấn nút "home" để gửi lên nền.Kiểm tra xem ứng dụng có đang mở trong sự kiện GCM onMessage không?

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

Trả lời

2

Sử dụng SharedPreferences saving the boolean isVisible và khi bạn nhận được giá trị từ tùy chọn, bạn có thể thêm giá trị mặc định.

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

Điều tôi luôn làm là tham chiếu đến Hoạt động hiện tại.

Tôi đặt Hoạt động hiện tại trong mọi onResume thành cài đặt này và đặt thành giá trị rỗng trong mỗi lần bật.

Nếu hoạt động hiện tại là null thì ứng dụng không mở. Nếu không phải là null, bạn có thể xem Hoạt động chính xác có đang mở hay không và phân phối nó cho Hoạt động đó.

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

Hãy cẩn thận về rò rỉ bộ nhớ! – rciovati

+0

@rciovati bị rò rỉ ở đâu? – Klaasvaak

+0

Rất tiếc, tôi không thấy bạn đặt thành 'null'các tham chiếu đến' currentActivity' khi Activity hoạt động ở chế độ onPause. – rciovati

17

Tôi sẽ sử dụng chương trình phát sóng để làm điều đó.

Trong onMessage phương pháp của bạn:

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

Trong hoạt động của bạn:

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

Các BroadcastReceiver khác

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> 

Về cơ bản trong phương pháp onMessage bạn gửi một Intent được BroadcastReceiver nhận lần đầu tiên được đăng ký bên trong YourActivity nếu nó đang chạy và ở nền trước, nếu không nó sẽ được nhận bởi SecondReceiver.

+2

Cảm ơn bạn! Trên dòng sau 'Intent responseIntent = new Intent (" com.yourpackage.GOT_PUSH ");' Tôi đã thêm 'responseIntent.PutExtras (intent);' do đó phần bổ sung của tôi sẽ sao chép. – shane

0

Điều mà làm việc cho tôi:

Tạo một Class Constants thức, bên trong nó, tạo varaiable tĩnh:

public final class Constants{ 
public static AppCompatActivity mCurrentActivity; 
} 

Bây giờ, trên từng vào sơ yếu lý lịch của activties bạn nói:

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

Khi nhận thông báo, kiểm tra xem hoạt động hiện tại có null hay không, nếu ứng dụng của nó không được mở, nếu hoạt động không phải là rỗng, bạn có thể kiểm tra những thứ như:

if(Constants.mCurrentActivity instanceof MainActivity){ 
    ((MainActivity) Constants.mCurrentActivity).yourPublicMethodOrStaticObject; 
} 
Các vấn đề liên quan