4

フォアグラウンドにあるアクティビティがあり、アプリ内で別のアクティビティに移動した場合、転送を開始するときにフラグを設定し、新しいアクティビティに転送したときにそれをワイプすることで、これを検出できます。これにより、内部(フラグが設定されている)イベントまたは外部(フラグが設定されていない)イベントによるアクティビティonPauseを区別できます。

ただし、通知に埋め込まれたPendingIntentsに対してこれを行うのに問題があります。通知バーで作成した通知を選択したために、アクティビティがonPausedになっていることを検出できますか?通知が発生し、アクティビティを一時停止する保留中のインテントが実行されるにトリガーされる、使用できる通知リスナーの種類はありますか?

これがやや紛らわしいことを理解しているので、問題を示すスケルトンプロジェクトを作成しました。

package com.example.notificationtest;

import android.os.Bundle;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {

private static final int INCOMING_NOTIFICATION_ID = 1;
private static final String TAG = "NotificationTest";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
public void onPause() {
    super.onPause();
    Log.e(TAG,"onPause");
}

@Override
public void onResume() {
    super.onResume();
    Log.e(TAG,"onResume");
}

public void onTransitionButtonClick(View view) {
    Intent intent = new Intent(this, MainActivity.class);
    Log.e(TAG,"About to start activity: onPause will be invoked.");
    startActivity(intent);
}

public void onNotificationButtonClick(View view) {
    Intent intent = new Intent(this, MainActivity.class); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    Notification notification = new Notification(android.R.drawable.alert_dark_frame, "Alert!", System.currentTimeMillis());
    notification.defaults |= Notification.DEFAULT_SOUND;
    notification.defaults |= Notification.DEFAULT_VIBRATE;
    notification.defaults |= Notification.DEFAULT_LIGHTS;
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notification.flags |= Notification.FLAG_INSISTENT;
    notification.setLatestEventInfo(this, "Click to open", "Click to open", pendingIntent);

    // Show the alert.
    final NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(INCOMING_NOTIFICATION_ID, notification);
}

}

activity_main.xmlを使用する場合:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<Button
    android:id="@+id/notify_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="@dimen/padding_medium"
    android:text="Make a notification"
    android:onClick="onNotificationButtonClick"
    tools:context=".MainActivity" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/notify_button"
    android:padding="@dimen/padding_medium"
    android:text="Normal transition"
    android:onClick="onTransitionButtonClick"
    tools:context=".MainActivity" />

</RelativeLayout>

「通常の遷移」ボタンを選択すると、ログに「アクティビティを開始しようとしています:onPauseが呼び出されます」と出力されます。onPauseの前。

[通知を行う]ボタンを選択し、通知バーを下にドラッグして通知をタップすると、onPauseの前にそのタップの通知が届くので、同じ行を挿入できます。「アクティビティを開始しようとしています:onPauseは呼び出されました。」どうやってやるの?

4

2 に答える 2

2

アクティビティを開始する意図を保持するPendingIntentだけでなく、ブロードキャストを「起動」する意図を保持することもできます

このようなカスタムブロードキャストを通知のトリガーとして使用し、BroadcastReceiverそのブロードキャストに登録され、必要なものを表示してから、目的のアクティビティを開始することを実装できます。

Intent intent = new Intent("my.custom.broadcast.action");
pendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);

レシーバーは次のようになります。

private BroadcastReceiver mReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        //do whatever you want
        // if this code is being executed - it's a sign that the user clicked on the notification...

        Intent intent = new Intent(this, MainActivity.class);
        Log.e(TAG,"About to start activity: onPause will be invoked.");
        startActivity(intent);

    }
};

mReceiver whenのonCreate()呼び出しを登録し、登録を解除することを忘れないでくださいonDestroy()

registerReceiver(mReceiver , new IntentFilter("my.custom.broadcast.action"));
unregisterReceiver(mReceiver);

このアプローチでは、ユーザーが通知をクリックしたときに何が起こるかを正確に制御できます。ご覧のとおり、通知がクリックされたときにのみブロードキャストを送信できます。誰もあなたが活動を始めなければならないとは言いませんでした..

于 2013-01-24T11:17:29.680 に答える
1

質問を別の質問に翻訳することから始めましょう(わかりやすくするため):通知(制御可能)に関連付けられたアクティビティが表示されるため、一時停止する前にアクティビティにコードを実行させるにはどうすればよいですか?

翻訳が答える目的のために十分であるという条件で:

このアプローチが解決策になると確信していますか?アクティビティが一時停止され、ユーザーが通知のアクティビティを「ほぼ直後」に表示する場合が多いためですが、その間にはまだステップがあります(他の通知が最初に表示される場合など)。技術的には、これは、同じコードをそこで実行する必要があることを意味しますが、同時に、通知が「非常に近い将来」に表示されることを示すことはできません。

したがって、適切な答えを得るには、実行するコードの性質とその動機に応じて、箱の外で少し考える必要があると思います。

ですから、この点に関して質問を更新して私に通知していただければ、もう一度確認させていただきます。

質問の更新後に更新:

ユーザーが通知を押したときに次のアクティビティを発生させるのを避け、代わりにイベントを発生させることができます。アクティビティがBroadcastReceiverをプログラムで登録する場合、このイベントを受信し、それ自体を更新して、必要に応じて次のアクティビティを開始できるはずです。

于 2013-01-24T09:43:28.683 に答える