5

thisデベロッパーチュートリアルに続き、私のアプリ内でジオフェンシングが正常に機能しています。ジオフェンス遷移が発生した場合Android、アプリが開いているときに通知ではなくalertDialogを表示

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

これはチュートリアルからクッキーカッターです。意図が主な活動で、設定されている:アプリが開いており、代わりにユーザーにAlertDialogを表示する場合

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

はどのように通知を抑制する機能を追加することができますか?理想的には、Geofence Transitionが発生したときに、ユーザーが現在どのビューにいるかに応じて、異なるタスクを実行できるようにしたいと考えています。各ビュー内の遷移を監視したり、インターセプトしたりすることができますか?

ありがとうございます。

答えて

5

いくつかの回答が不完全であったため、私が探していたものに対する完全な解決策がここにあります。

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 
} 

は(名前だけラインが残りはデフォルトで、追加されました)あなたのマニフェストにこの名前を付けてください:

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

ActivityLifecycleCallbacksを実装MyApplicationクラスを設定

まず第一に、上記の作業は、アプリのライフサイクルを追跡するために使用されます。これを使用して、アプリが現在フォアグラウンドにあるかどうかを確認できます。

次に、コードを実行する場所(トリガーが発生したときにアプリが開いている場合)に、BroadcastReceiverを設定します。この場合、それは私のMainActivityである:

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

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

同じ活動のあなたのonCreateに受信機を登録します。

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

    ... 

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

そして、それを登録解除することを忘れないでください:

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

ブロードキャストを受信すると、受信機内のコードが実行されます。

今、アプリケーションがフォアグラウンドにあるかどうかを確認し、ブロードキャストを送信します。アプリは上記で定義され、MyApplication.isActivityVisible()を使用してフォアグラウンドであり、その後、送信のいずれかの場合

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

チェック: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. 
    } 
} 

重要なビットは、最後のネストされたif文であります通知を送信したり、ブロードキャストを送信することができます。インセンティブコード("some_custom_id")が送信者と受信者で一致するようにしてください。

それはそれです。アプリケーションがフォアグラウンド(特にMainActivity)にある場合、私はいくつかのコードを実行します。アプリがフォアグラウンドにない場合は、通知を送信します。

+1

私はちょうど感謝を言うためにログインしました。 –

0

a)アクティビティのライフサイクルイベントをサービスに通知できます。

b)アクティビティの静的フィールドにUIの現在の状態を保持し、通知を表示する前にサービスから確認できます。

+0

私はこの権利を得ているのかどうかはわかりませんが、そのようなサウンドは通知を抑制するだけです。ジオフェンストランジションが発生したときにalertDialogを表示するにはどうすればよいですか?またはビューを更新しますか?あなたの答えにいくつかのコードを入力してください。 – Birrel

1

最も簡単な方法は、LocalBroadcastManagerまたはevent busを使用することです。

移行が発生した場合は、IntentServiceからローカルブロードキャストを送信し、component XIntentServiceと、Activityの間に含める必要があります。 Component Xは、あなたのActivity年代のいずれかがフォアグラウンドであると

  • そうであればあれば追跡しなければならない - ショー通知 -
  • ない場合、(フォアグラウンドActivityに)他のローカル放送を渡します。

あなたのアプリがフォアグラウンドであるかどうAndroidの中で、あなたが簡単に追跡することはできません(とあなたが1つの以上の活動を持っている場合、あなたは私の意見ではそれを正しく行うことはできません)が、you can tryことに注意してください。

+0

今、私が 'LocalBroadcastManager'で考えることができる最高のものは、私の活動のそれぞれにレシーバを含めることです。 1つの受信者ですべてのアクティビティをカバーする方法はありますか?また、アプリが開いているときに 'IntentService'内から通知を抑制/停止するにはどうしたらいいですか? – Birrel

+0

私が見つけたのは、アラートを表示してタスクを実行できる答えと[this(http://stackoverflow.com/questions/3667022/checking-if-an-android-application)]の組み合わせです-is-background-in-the-background/13809991#13809991)の回答で、アプリが実行中かどうかを判断できます。 – Birrel

関連する問題