クライアント側で既読通知APIを利用することにより、受信したメッセージが確認されたことをIMAPSサーバへ通知することができます。
既読通知機能を利用するには定義ファイル(impush.properties)のfj_push_read_modeの設定が必要です。詳細は"運用ガイド"を参照してください。
既読通知は、通知メッセージ情報に含まれるメッセージIDを取得し、既読通知APIを使用します。メッセージIDの取得タイミングは以下となります。
・通知バーのメッセージタップ後に自アプリが起動し、発行されたインテントからメッセージIDを取得
通知バーのメッセージタップに連動して、自アプリを起動するには、6.3 受信したメッセージからのアクションの自アプリケーション起動を参照してください。
・アプリ側でPushReceiverを実装していた場合、ペイロード情報からメッセージIDを取得
・通知センターのメッセージタップ後にアプリが起動し、渡されたペイロードからメッセージIDを取得
・FJPAppDelegateクラスを継承したサブクラスのdidReceiveRemoteNotification関数内でペイロード情報からメッセージIDを取得
・トースト通知をタップした後にアプリが起動し、渡される情報からメッセージIDを取得
Androidで既読通知機能を利用する場合は、プッシュクライアント設定ファイルのpush.NotificationMainClassNameに通知バータップ後に起動するActivityを設定してください。プッシュクライアント設定ファイルについては、付録D プッシュクライアント設定ファイルを参照してください。
注意
push.NotificationMainClassNameが省略、または存在しないクラスを指定していた場合は、アプリが起動しないためインテントを取得できません。
以下、既読API実装例です。
//アプリのMainActivity.java内(push.propertiesのpush.NotificationMainClassNameに設定)
//通知バーをタップし、アプリを起動した際の処理
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
//インテントにmsgIDが設定されている場合
if(intent != null && intent.getExtras() != null) {
//インテントからメッセージIDを取得
String msgID = intent.getStringExtra(PushDefine.EXTRA_MESSAGE_ID);
PushManager pm = new PushManager(getApplicationContext());
try {
ArrayList<String> f_msgID = pm.getFailedMsgIDList();
//アプリ領域にメッセージIDが保存されている場合
if(f_msgID != null){
//保存されているメッセージID分の既読通知を実行
for(int i = 0; i < f_msgID.size(); i++) {
String id = f_msgID.get(i);
pm.notifyMessageRead(id);
}
}
//タップしたメッセージの既読通知を実行
pm.notifyMessageRead(msgID);
} catch(PushException e) {
//例外時の処理
}
} else {
//インテントが取得できなかった場合の処理
}
}
//通知バータップで起動するActivityのlaunchModeが
//"singleTop"、"singleTask"、"singleInstance"の場合
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//インテントにmsgIDが設定されている場合
if(intent != null && intent.getExtras() != null) {
//インテントからメッセージIDを取得
String msgID = intent.getStringExtra(PushDefine.EXTRA_MESSAGE_ID);
PushManager pm = new PushManager(getApplicationContext());
try {
ArrayList<String> f_msgID = pm.getFailedMsgIDList();
//アプリ領域にメッセージIDが保存されている場合
if(f_msgID != null) {
//保存されているメッセージID分の既読通知を実行
for(int i = 0; i < f_msgID.size(); i++) {
String id = f_msgID.get(i);
pm.notifyMessageRead(id);
}
}
//タップしたメッセージの既読通知を実行
pm.notifyMessageRead(msgID);
} catch(PushException e) {
//例外時の処理
}
} else {
//インテントが取得できなかった場合の処理
}
}
アプリが起動中にメッセージを受信し、アプリ側でPushReceiverを実装していた場合
private class MyReceiver extends PushReceiver{
@Override
public void callback(int arg0, Bundle arg1) {
//IMAPSプッシュのメッセージを受信した場合
if(arg0 == com.fujitsu.fjh.push.common.PushDefine.RESULT_RECEIVE_MESSAGE) {
byte[] payloadData = arg1.getByteArray(com.fujitsu.fjh.push.common.PushDefine.MESSEAGE_BUNDLE_PAYLOAD_KEY);
String payload = new String(payloadData);
//ペイロード情報をJSONObjectへ変換
JSONObject payloadObject = new JSONObject(payload);
//ペイロード情報からmsgIDを取得
String msgid = payloadObject.getString("mid")
//受信時の処理を実装
// ・・・
//メッセージを確認したタイミング(任意)で既読通知を実行
PushManager pm = PushManager.getInstance();
try {
ArrayList<String> f_msgID = pm.getFailedMsgIDList();
//アプリ領域にメッセージIDが保存されている場合
if(f_msgID != null) {
//保存されているメッセージID分の既読通知を実行
for(int i = 0; i < f_msgID.size(); i++) {
String id = f_msgID.get(i);
pm.notifyMessageRead(id);
}
}
//受信したメッセージの既読通知を実行
pm.notifyMessageRead(msgid);
} catch(PushException e) {
//例外時の処理
}
}
}
//アプリのMainActivity.java内(push.propertiesのpush.NotificationMainClassNameに設定)
//通知バーをタップし、アプリを起動した際の処理
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
//インテントにmsgIDが設定されている場合
if(intent != null && intent.getExtras() != null) {
//インテントからメッセージIDを取得
String msgID = intent.getStringExtra(PushDefine.EXTRA_MESSAGE_ID);
GcmRegister gr = GcmRegister.getInstance(getApplicationContext());
try {
ArrayList<String> f_msgID = gr.getFailedMsgIDList();
//アプリ領域にメッセージIDが保存されている場合
if(f_msgID != null) {
//保存されているメッセージID分の既読通知を実行
for(int i = 0; i < f_msgID.size(); i++) {
String id = f_msgID.get(i);
gr.notifyMessageRead(id);
}
}
//タップしたメッセージの既読通知を実行
gr.notifyMessageRead(msgID);
} catch(PushException e) {
//例外時の処理
}
} else {
//インテントが取得できなかった場合の処理
}
}
//通知バータップで起動するActivityのlaunchModeが
//"singleTop"、"singleTask"、"singleInstance"の場合
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//インテントにmsgIDが設定されている場合
if(intent != null && intent.getExtras() != null) {
//インテントからメッセージIDを取得
String msgID = intent.getStringExtra(PushDefine.EXTRA_MESSAGE_ID);
GcmRegister gr = GcmRegister.getInstance(getApplicationContext());
try {
ArrayList<String> f_msgID = gr.getFailedMsgIDList();
//アプリ領域にメッセージIDが保存されている場合
if(f_msgID != null) {
//保存されているメッセージID分の既読通知を実行
for(int i = 0; i < f_msgID.size(); i++) {
String id = f_msgID.get(i);
gr.notifyMessageRead(id);
}
}
//タップしたメッセージの既読通知を実行
gr.notifyMessageRead(msgID);
} catch(PushException e) {
//例外時の処理
}
} else {
//インテントが取得できなかった場合の処理
}
}
private class MyReceiver extends PushReceiver {
@Override
public void callback(int arg0, Bundle arg1) {
//GCMプッシュのメッセージを受信した場合
if(arg0 == com.fujitsu.fjh.push.common.PushDefine.RESULT_RECEIVE_GCM_MESSAGE) {
Bundle payloadData = arg1.getBundle (com.fujitsu.fjh.push.common.PushDefine.MESSEAGE_BUNDLE_PAYLOAD_KEY);
String msgID = payloadData.getString("mid")
//受信時の処理を実装
// ・・・
//メッセージを確認したタイミング(任意)で既読通知を実行
GcmRegister gr = GcmRegister.getInstance(getApplicationContext());
try {
ArrayList<String> f_msgID = gr.getFailedMsgIDList();
//アプリ領域にメッセージIDが保存されている場合
if(f_msgID != null) {
//保存されているメッセージID分の既読通知を実行
for(int i = 0; i < f_msgID.size(); i++) {
String id = f_msgID.get(i);
gr.notifyMessageRead(id);
}
}
//受信したメッセージの既読通知を実行
gr.notifyMessageRead(msgid);
} catch(PushException e) {
//例外時の処理
}
}
}
AppDelegateクラス内
//通知センターのメッセージをタップし、アプリを起動した際の処理
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo != nil)
{
FJPPayloadInfo* payInfo = [[FJPPayloadInfo alloc]initWithPayload:userInfo];
//アクションを指定した通知の場合は、親クラスの関数を実行する前に既読通知を行う
if(payInfo != nil && payInfo.msgID != nil)
{
//既読通知を実行
NSArray* f_msgid = [FJPMessageReadManager getFailedMsgIDList];
//アプリ領域にメッセージIDが保存されている場合
if(f_msgid != nil)
{
//保存されているメッセージID分の既読通知を実行
for(NSString* id in f_msgid)
{
[FJPMessageReadManager notifyMessageRead:id delegate:self];
}
}
//タップしたメッセージの既読通知を実行
[FJPMessageReadManager notifyMessageRead:payInfo.msgID delegate:self];
}
}
[super application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions];
//アクション指定がない通知は親クラスの関数実行後でも既読通知を行える
//既読通知を実行
//・・・
return YES;
}
アプリ起動中にメッセージ受信した場合
アプリ起動中にメッセージを受信した場合、FJPAppDelegateクラスを継承したサブクラスのdidReceiveRemoteNotification関数内でペイロード情報からメッセージIDを取得し、既読通知APIを実行します。 また、メッセージIDは、ペイロード情報をFJPPayloadInfoオブジェクトに変換して取得します。
AppDelegateクラス内
//アプリ起動中にプッシュ通知を受信した場合
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if (userInfo != nil)
{
// ペイロード情報をFJPPayloadInfoオブジェクトに初期化
FJPPayloadInfo* payInfo = [[FJPPayloadInfo alloc]initWithPayload:userInfo];
//payload情報にmsgIDが格納されている場合
if(payInfo != nil && payInfo.msgID != nil)
{
//受信時の処理を実装
// ・・・
//メッセージを確認したタイミング(任意)で既読通知を実行
NSArray* f_msgid = [FJPMessageReadManager getFailedMsgIDList];
//アプリ領域にメッセージIDが保存されている場合
if(f_msgid != nil)
{
//保存されているメッセージID分の既読通知を実行
for(NSString* id in f_msgid)
{
[FJPMessageReadManager notifyMessageRead:id delegate:self];
}
}
//受信したメッセージの既読通知を実行
[FJPMessageReadManager notifyMessageRead:payInfo.msgID delegate:self];
}
}
}
AppDelegateクラス内
@interface AppDelegate : FJPAppDelegate <FJPNotifyDelegate>
- (void)didNotifyMessageRead:(NSError*) error
@end
#pragma mark FJPNotifyDelegate implementation
- (void)didNotifyMessageRead:(NSError*) error
{
if(error == nil)
{
//通知成功の場合の処理
}
else
{
//通知失敗の場合の処理
}
}
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
・・・
Window.Current.Activate();
//PushReceiverを継承したクラスのインスタンス生成
MyReceiver myreceiver = new MyReceiver();
WNSRegister wr = WNSRegister.getInstance(myreceiver);
//既読通知に失敗したメッセージIDを取得し、再度既読通知を行う
IList<string> list = wr.getFailedMsgIDList();
try
{
if(list != null)
{
//既読通知に失敗したメッセージID分、既読通知を実行する
foreach(string f_msgid in list)
{
wr.notifyMessageRead(f_msgid);
});
}
//LaunchActivatedEventArgsのArgumentsプロパティからメッセージIDを取得する
string msgid = wr.getMessageID(e.Arguments);
//既読通知を実行する
wr.notifyMessageRead(msgid);
}
catch(Exception e)
{
//例外時の処理
}
//アクションを実行する
WNSToastAction.action(e.Arguments, e.Kind);
}
Android はインテントからメッセージIDを取得する方法のみ有効です。
そのため、アプリ起動中においても通知バーをタップし、インテントからメッセージIDを取得する方法で既読通知を行うようにしてください。//activatedイベントにハンドラ-を登録
WinJS.Application.addEventListener("activated", onActivatedHandler, false);
function onActivatedHandler(args) {
if (args.detail.arguments !== "") {
//既読通知処理
try {
//メッセージID取得
var msgid = Com.Fujitsu.Imaps.Push.WNS.WNSRegister.getInstance().getMessageID(args.detail.arguments);
//既読通知の実行
Com.Fujitsu.Imaps.Push.WNS.WNSRegister.getInstance().notifyMessageRead(msgid);
}
//WinJSの制限により、nullが返る場合はArgumentNullExceptionが発生する(getMessageID返却値がnull)
catch (e) {
//例外時の処理
}
//アクションの実行
Com.Fujitsu.Imaps.Push.WNS.WNSToastAction.action(args.detail.arguments, args.detail.kind);
}
}
※Windowsの場合は、プッシュ受信アプリ以外のアプリのアクションを指定したプッシュ通知に対しても、既読通知を行うことができます。
アクション指定した通知をタップし起動するのは、アクションに指定されたアプリです。
そのため、アクションにプッシュ受信アプリ以外のアクションを指定していた場合は、それらのアプリ(ブラウザ、メールなど)が起動します。 つまり、プッシュ受信アプリが未起動時の場合は、通知をタップしてもプッシュ受信アプリは起動しません。 プッシュ受信アプリが起動しないため、既読通知APIを実行することができません。
プッシュ受信アプリが起動中の場合は、PushReceiverを利用してメッセージIDを取得することで、 アプリがフォアグラウンド(アクション実行前)の場合のみ既読通知を実行することができます。
Androidのハイブリッドアプリの場合、プッシュ受信アプリが未起動時・起動中共に既読通知APIを実行することができません。
これは、Androidのハイブリッドアプリでは、通知バーをタップしインテントからメッセージIDを取得する方法でのみ既読通知することが可能なのですが、 通知バーのタップによりプッシュ受信アプリ以外のアプリ(ブラウザ、メールなど)が起動し、 プッシュ受信アプリが起動しないため、既読通知APIを実行することができないからです。
プッシュ受信アプリ未起動時は、FJPAppDelegateの派生クラスのdidFinishLaunchingWithOptions関数内で渡されたパラメータからメッセージIDを取得し、既読通知APIを実行することができます。 ただし、親クラスの同関数を実行する前(アプリ起動後のアクション実行前)でのみ有効です。
プッシュ受信アプリ起動中においても、FJPAppDelegateの派生クラスのdidReceiveRemoteNotification関数内で渡されたパラメータからメッセージIDを取得し、既読通知APIを実行することができます。 ただし、プッシュ受信アプリ未起動時と同様に、親クラスの同関数を実行する前でのみ有効です。
・com_fujitsu_push_msg_id_data
・com_fujitsu_push_msg_id_data
・com_fujitsu_push_msg_id_data
メッセージをタップ後に起動するActivityのlaunchModeが省略もしくは、"standard" が設定されていた場合は、メッセージタップにてActivityを初回起動後、メッセージを受信し、 その後メッセージをタップしても新規Activityが起動せず、前回のActivityが表示され、 onCreate()やonNewIntent()などのライフサイクルイベントにてメッセージIDが取得できず、既読通知を行うことができません。
そのため、メッセージタップ後に起動するActivityのlaunchModeは、"singleTop"、"singleTask"、"singleInstance" のいずれかを指定してください。