5

Tôi đã theo dõi this hướng dẫn dành cho nhà phát triển và yêu cầu Geofencing hoạt động trong ứng dụng của tôi như mong đợi.Android, Hiển thị alertDialog thay vì thông báo khi ứng dụng đang mở

Thông báo được gửi khi một Geofence chuyển tiếp xảy ra, từ bên trong một IntentService:

@Override 
protected void onHandleIntent(Intent intent) { 
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); 

    ...   

    sendNotification(geofenceTransitionDetails); 
} 

private void sendNotification(String notificationDetails) { 
    // Create an explicit content Intent that starts the main Activity. 
    Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); 

    // Construct a task stack. 
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 

    // Add the main Activity to the task stack as the parent. 
    stackBuilder.addParentStack(MainActivity.class); 

    // Push the content Intent onto the stack. 
    stackBuilder.addNextIntent(notificationIntent); 

    // Get a PendingIntent containing the entire back stack. 
    PendingIntent notificationPendingIntent = 
      stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 

    // Get a notification builder that's compatible with platform versions >= 4 
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 

    // Define the notification settings. 
    builder.setSmallIcon(R.mipmap.ic_launcher) 
      // In a real app, you may want to use a library like Volley 
      // to decode the Bitmap. 
      .setLargeIcon(BitmapFactory.decodeResource(getResources(), 
        R.mipmap.ic_launcher)) 
      .setColor(Color.RED) 
      .setContentTitle(notificationDetails) 
      .setContentText("Return to app") 
      .setContentIntent(notificationPendingIntent); 

    // Dismiss notification once the user touches it. 
    builder.setAutoCancel(true); 

    // Get an instance of the Notification manager 
    NotificationManager mNotificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

    // Issue the notification 
    mNotificationManager.notify(0, builder.build()); 
} 

Đây là cookie-cutter từ hướng dẫn. Mục đích được thiết lập trong Hoạt động chính:

private PendingIntent getGeofencePendingIntent() { 
    // Reuse the PendingIntent if we already have it. 
    if (mGeofencePendingIntent != null) { 
     return mGeofencePendingIntent; 
    } 
    Intent intent = new Intent(this, GeofenceTransitionsIntentService.class); 
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling 
    // addGeofences() and removeGeofences(). 
    return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
} 

Làm cách nào để thêm chức năng chặn thông báo nếu ứng dụng đang mở và thay vào đó sẽ hiển thị AlertDialog cho người dùng? Lý tưởng nhất, tôi muốn có thể thực hiện các nhiệm vụ khác nhau, tùy thuộc vào chế độ xem mà người dùng hiện đang ở khi quá trình chuyển đổi địa lý diễn ra. Tôi có thể theo dõi/chặn chuyển đổi từ bên trong mỗi chế độ xem hoặc bằng cách nào đó trên toàn cầu không?

Xin cảm ơn trước.

Trả lời

5

Một số câu trả lời chưa hoàn chỉnh và do đó, đây là giải pháp hoàn chỉnh cho những gì tôi đang tìm kiếm.

Trước hết, thiết lập MyApplication lớp, mà thực hiện ActivityLifecycleCallbacks:

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks { 

    private static boolean isActive; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     registerActivityLifecycleCallbacks(this); 
    } 

    public static boolean isActivityVisible(){ 
     return isActive; 
    } 

    @Override 
    public void onActivityResumed(Activity activity) { 
     isActive = true; 
    } 

    @Override 
    public void onActivityPaused(Activity activity) { 
     isActive = false; 
    } 

    ... no other methods need to be used, but there are more that 
    ... must be included for the ActivityLifecycleCallbacks 
} 

Hãy chắc chắn để đặt tên này trong biểu hiện của bạn (chỉ dòng Tên đã được bổ sung, còn lại là mặc định):

<application 
    android:name=".MyApplication" 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" 
    android:hardwareAccelerated="true"> 

Những gì đã được thực hiện ở trên được sử dụng để theo dõi vòng đời của ứng dụng của bạn. Bạn có thể sử dụng điều này để kiểm tra xem ứng dụng của bạn có đang ở nền trước hay không.

Tiếp theo là thiết lập BroadcastReceiver, bất cứ nơi nào bạn muốn chạy mã (trong trường hợp ứng dụng được mở khi kích hoạt xảy ra).Trong trường hợp này, đó là trong tôi MainActivity:

protected BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     ... Do whatever you want here 

     Toast.makeText(...).show(); 
    } 
}; 

Đăng ký nhận trong onCreate của bạn trong những hoạt động giống nhau:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ... 

    LocalBroadcastManager.getInstance(this).registerReceiver(mNotificationReceiver, new IntentFilter("some_custom_id")); 
} 

Và đừng quên để unregister nó:

@Override 
protected void onDestroy() { 
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mNotificationReceiver); 
    super.onDestroy(); 
} 

Khi nhận được một phát sóng, mã trong bộ thu được thực hiện.

Bây giờ, để kiểm tra xem ứng dụng có ở nền trước hay không và gửi phát sóng nếu có. Bên trong IntentService:

@Override 
protected void onHandleIntent(Intent intent) { 
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); 
    if (geofencingEvent.hasError()) { 
     String errorMessage = getErrorString(this, 
       geofencingEvent.getErrorCode()); 
     return; 
    } 

    int geofenceTransition = geofencingEvent.getGeofenceTransition(); 

    // Test that the reported transition was of interest. 
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || 
      geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { 

     ... 

     if(MyApplication.isActivityVisible()){ 
      Intent intnt = new Intent("some_custom_id"); 
      intnt.putExtra("message", geofenceTransitionDetails); 
      LocalBroadcastManager.getInstance(this).sendBroadcast(intnt); 
     }else{ 
      sendNotification(geofenceTransitionDetails); 
     } 

    } else { 
     // Log the error. 
    } 
} 

Các bit quan trọng là lồng nhau nếu-tuyên bố cuối cùng:

if(MyApplication.isActivityVisible()){ 
    Intent intnt = new Intent("some_custom_id"); 
    intnt.putExtra("message", geofenceTransitionDetails); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(intnt); 
}else{ 
    sendNotification(geofenceTransitionDetails); 
} 

Kiểm tra xem ứng dụng này là ở mặt trước sử dụng MyApplication.isActivityVisible(), như đã định nghĩa ở trên, và sau đó, hoặc gửi thông báo hoặc gửi một chương trình phát sóng. Chỉ cần đảm bảo rằng mã ý định của bạn (ví dụ: "some_custom_id") khớp với người gửi và người nhận của bạn.

Và đó là về nó. Nếu ứng dụng ở phía trước (đặc biệt là MainActivity), tôi thực thi một số mã. Nếu ứng dụng không ở phía trước, tôi sẽ gửi thông báo.

+1

Tôi vừa đăng nhập để nói lời cảm ơn. –

0

a) Bạn có thể thông báo cho dịch vụ của mình về các sự kiện vòng đời của hoạt động.

b) Bạn có thể giữ trạng thái hiện tại của giao diện người dùng trong một trường tĩnh trong hoạt động và kiểm tra nó từ dịch vụ trước khi hiển thị thông báo.

+0

Tôi không chắc liệu tôi có nhận được quyền này hay không nhưng những âm thanh đó giống như họ sẽ chỉ chặn thông báo. Làm thế nào tôi có thể sử dụng chúng để hiển thị alertDialogs khi chuyển đổi geofence xảy ra? Hoặc để cập nhật chế độ xem? Vui lòng cung cấp một số mã với câu trả lời của bạn. – Birrel

1

Cách dễ nhất là sử dụng LocalBroadcastManager hoặc một số event bus.

Vì vậy, khi quá trình chuyển đổi xảy ra, bạn nên gửi truyền phát địa phương từ IntentService và xem nó với một số component X ở giữa IntentService và bất kỳ số nào trong số Activity của bạn. Component X phải theo dõi nếu có của bạn Activity 's là trong foreground và

  • nếu có - vượt qua truyền hình địa phương khác lên (để foreground Activity),
  • nếu không muốn nói - show thông báo.

Xin lưu ý rằng trong Android bạn không thể theo dõi dễ dàng nếu ứng dụng của bạn ở tiền cảnh hoặc không (và nếu bạn có nhiều hơn 1 Hoạt động, bạn không thể làm đúng theo ý kiến ​​của tôi) nhưng you can try.

+0

Ngay bây giờ, điều tốt nhất tôi có thể nghĩ với 'LocalBroadcastManager' là bao gồm một bộ thu trong mỗi hoạt động của tôi. Có cách nào để chăn tất cả các hoạt động với một người nhận đơn lẻ không? Ngoài ra, làm cách nào để tôi chặn/dừng thông báo từ bên trong 'IntentService' khi ứng dụng đang mở? – Birrel

+0

Những gì tôi thấy hoạt động tốt nhất là sự kết hợp giữa câu trả lời của bạn, cho phép tôi hiển thị cảnh báo và thực hiện các tác vụ và [this] (http://stackoverflow.com/questions/3667022/checking-if-an-android-application -is-running-in-the-background/13809991 # 13809991) câu trả lời, cho phép tôi xác định xem ứng dụng có đang chạy hay không. – Birrel

Các vấn đề liên quan