+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+// http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
package org.iotivity.service.notification;\r
\r
import android.util.Log;\r
\r
-/**\r
- * Created by jaesick.shin on 2016-04-26.\r
- */\r
-public class NSMessage {\r
- \r
- String id = null;\r
- String title = null;\r
- String body = null;\r
- \r
- public NSMessage(String id) {\r
- this.id = id;\r
- }\r
-\r
- public String getTitle() {\r
- return title;\r
- }\r
-\r
- public void setTitle(String title) {\r
- this.title = title;\r
- }\r
-\r
- public String getBody() {\r
- return body;\r
- }\r
-\r
- public void setBody(String body) {\r
- this.body = body;\r
- }\r
-\r
- public String getId() {\r
- return id;\r
- }\r
- \r
+public class NSMessage\r
+{\r
+ String id = null;\r
+ String title = null;\r
+ String body = null;\r
+ String source = null;\r
+\r
+ public NSMessage(String id)\r
+ {\r
+ this.id = id;\r
+ }\r
+\r
+ public String getId()\r
+ {\r
+ return id;\r
+ }\r
+\r
+ public String getTitle()\r
+ {\r
+ return title;\r
+ }\r
+\r
+ public void setTitle(String title)\r
+ {\r
+ this.title = title;\r
+ }\r
+\r
+ public String getBody()\r
+ {\r
+ return body;\r
+ }\r
+\r
+ public void setBody(String body)\r
+ {\r
+ this.body = body;\r
+ }\r
+\r
+ public String getSource()\r
+ {\r
+ return source;\r
+ }\r
+\r
+ public void setSource(String source)\r
+ {\r
+ this.source = source;\r
+ }\r
}\r
}\r
}\r
\r
+ LOGI("consumer ID : %s\n", consumer->mId);\r
+ jstring consumerId = (*env)->NewStringUTF(env, consumer->mId);\r
+\r
jclass cls = (*env)->GetObjectClass(env, g_obj_subscriptionListener);\r
if (!cls)\r
{\r
return;\r
}\r
\r
- //(*env)->CallVoidMethod(env, g_obj_subscriptionListener, mid);\r
+ (*env)->CallVoidMethod(env, g_obj_subscriptionListener, mid, consumerId);\r
\r
(*g_jvm)->DetachCurrentThread(g_jvm);\r
\r
return;\r
}\r
\r
- //(*env)->CallVoidMethod(env, g_obj_syncListener, mid, strMessageId, (jint) sync->mState);\r
+ (*env)->CallVoidMethod(env, g_obj_syncListener, mid, strMessageId, (jint) sync->mState);\r
\r
(*g_jvm)->DetachCurrentThread(g_jvm);\r
\r
}\r
LOGI("Message Body: %s\n", messageBody);\r
\r
+ // Message Source\r
+ jfieldID fid_source = (*env)->GetFieldID(env, cls, "source", "Ljava/lang/String;");\r
+ if (fid_source == NULL)\r
+ {\r
+ LOGE("Error: jfieldID for message source is null");\r
+ return (jint) NS_ERROR;\r
+ }\r
+ jstring jmsgSource = (*env)->GetObjectField(env, jMsg, fid_source);\r
+ const char * messageSource = (*env)->GetStringUTFChars(env, jmsgSource, NULL);\r
+ if (messageSource == NULL)\r
+ {\r
+ printf("Error: messageSource is null\n");\r
+ return (jint) NS_ERROR;\r
+ }\r
+ LOGI("Message Source: %s\n", messageSource);\r
+\r
NSMessage * nsMsg = (NSMessage *) malloc(sizeof(NSMessage));\r
\r
nsMsg->mId = strdup(messageId);\r
nsMsg->mTitle = strdup(messageTitle);\r
nsMsg->mContentText = strdup(messageBody);\r
+ nsMsg->mSource = strdup(messageSource);\r
\r
return nsMsg;\r
\r
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
- <option value="$PROJECT_DIR$/iotivity-armeabi-notification-service-debug" />
- <option value="$PROJECT_DIR$/iotivity-base-armeabi-debug" />
+ <option value="$PROJECT_DIR$/iotivity-armeabi-notification-service-release" />
+ <option value="$PROJECT_DIR$/iotivity-base-armeabi-release" />
</set>
</option>
</GradleProjectSettings>
--- /dev/null
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="Project Default" />
+ <inspection_tool class="AndroidLintHandlerLeak" enabled="false" level="WARNING" enabled_by_default="false" />
+ </profile>
+</component>
\ No newline at end of file
--- /dev/null
+<component name="InspectionProjectProfileManager">
+ <settings>
+ <option name="PROJECT_PROFILE" value="Project Default" />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
+ </settings>
+</component>
\ No newline at end of file
<module fileurl="file://$PROJECT_DIR$/NotiProviderExample.iml" filepath="$PROJECT_DIR$/NotiProviderExample.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
<module fileurl="file://$PROJECT_DIR$/iotivity-armeabi-notification-service-debug/iotivity-armeabi-notification-service-debug.iml" filepath="$PROJECT_DIR$/iotivity-armeabi-notification-service-debug/iotivity-armeabi-notification-service-debug.iml" />
+ <module fileurl="file://$PROJECT_DIR$/iotivity-armeabi-notification-service-release/iotivity-armeabi-notification-service-release.iml" filepath="$PROJECT_DIR$/iotivity-armeabi-notification-service-release/iotivity-armeabi-notification-service-release.iml" />
<module fileurl="file://$PROJECT_DIR$/iotivity-base-armeabi-debug/iotivity-base-armeabi-debug.iml" filepath="$PROJECT_DIR$/iotivity-base-armeabi-debug/iotivity-base-armeabi-debug.iml" />
+ <module fileurl="file://$PROJECT_DIR$/iotivity-base-armeabi-release/iotivity-base-armeabi-release.iml" filepath="$PROJECT_DIR$/iotivity-base-armeabi-release/iotivity-base-armeabi-release.iml" />
</modules>
</component>
</project>
\ No newline at end of file
dependencies {\r
compile fileTree(include: ['*.jar'], dir: 'libs')\r
compile 'com.android.support:appcompat-v7:23.0.1'\r
- compile project(':iotivity-base-armeabi-debug')\r
- compile project(':iotivity-armeabi-notification-service-debug')\r
+ compile project(':iotivity-base-armeabi-release')\r
+ compile project(':iotivity-armeabi-notification-service-release')\r
}\r
import android.app.NotificationManager;\r
import android.content.Intent;\r
import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.os.Message;\r
import android.support.v7.app.AppCompatActivity;\r
import android.util.Log;\r
import android.view.View;\r
import android.widget.Button;\r
import android.widget.EditText;\r
import android.widget.TextView;\r
-import java.util.Random;\r
\r
public class MainActivity extends AppCompatActivity {\r
\r
- private static final int PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;\r
- private final String TAG = "NS_JNI_MAIN_ACTIVITY";\r
-\r
+ private final String TAG = "NS_MAIN_ACTIVITY";\r
+ private static final int MESSAGE_SUBSCRIPTION = 1;\r
+ private static final int MESSAGE_SYNC = 2;\r
private Button btnTitle;\r
private Button btnBody;\r
private Button btnSend;\r
private Button btnSync;\r
private EditText editTextTitle;\r
private EditText editTextBody;\r
- private TextView TvLog;\r
-\r
- private static int notiId = 0;\r
+ private static TextView TvLog;\r
\r
+ private static int notiId = 100;\r
+ private static int subCnt = 0;\r
private boolean isStarted = false;\r
- private String LastMessageId = null;\r
private String consumerId;\r
\r
private NotiListener mNotiListener = null;\r
private ProviderProxy mProviderProxy = null;\r
\r
+ public static Handler mHandler = new Handler() {\r
+ @Override\r
+ public void handleMessage(Message msg) {\r
+ switch (msg.what) {\r
+ case MESSAGE_SUBSCRIPTION:\r
+ String subscriber = (String) msg.obj;\r
+ if(subscriber != null)\r
+ TvLog.append("Recv-Sub(" + subCnt++ + ") " + subscriber + "\n");\r
+ break;\r
+\r
+ case MESSAGE_SYNC:\r
+ String sync = (String) msg.obj;\r
+ if(sync != null)\r
+ TvLog.append("Sync-Read(#" + sync + ")\n");\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ };\r
+\r
@Override\r
protected void onCreate(Bundle savedInstanceState) {\r
super.onCreate(savedInstanceState);\r
btnStop.setOnClickListener(mClickListener);\r
\r
mProviderProxy = new ProviderProxy(getApplicationContext());\r
+ mProviderProxy.setHandler(mHandler);\r
+\r
mNotiListener = new NotiListener(this);\r
\r
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");\r
startActivity(intent);\r
}\r
\r
- public ProviderProxy getProviderExample() {\r
+ @Override\r
+ protected void onDestroy() {\r
+ super.onDestroy();\r
+ }\r
+\r
+ public ProviderProxy getProviderProxy()\r
+ {\r
return mProviderProxy;\r
}\r
\r
- Button.OnClickListener mClickListener = new View.OnClickListener() {\r
+ Button.OnClickListener mClickListener = new View.OnClickListener() {\r
public void onClick(View v) {\r
switch (v.getId()) {\r
\r
if (isStarted == false) {\r
Log.i(TAG, "Start NS Provider Service");\r
\r
+ TvLog.setText("Start NS-Provider\n");\r
+\r
boolean access = true; // ptovider controls the acceptance of consumers\r
mProviderProxy.startNotificationServer(access);\r
isStarted = true;\r
\r
case R.id.BtnCreateNoti: {\r
\r
- Random r = new Random();\r
- int notiId = r.nextInt(901) + 100; //[100, 1000]\r
-\r
String id = Integer.toString(notiId); // generate notificaion ID\r
String title = editTextTitle.getText().toString();\r
String body = editTextBody.getText().toString();\r
Notification.Builder notiBuilder = new Notification.Builder(getApplicationContext());\r
notiBuilder.setContentTitle(title);\r
notiBuilder.setContentText(body);\r
+ notiBuilder.setPriority(Notification.PRIORITY_MAX);\r
+ notiBuilder.setDefaults(Notification.DEFAULT_ALL);\r
notiBuilder.setSmallIcon(R.mipmap.ic_launcher);\r
NotificationManager notiMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);\r
notiMgr.notify(notiId, notiBuilder.build());\r
\r
- LastMessageId= id; // for test to send sync\r
+ notiId++;\r
\r
Log.i(TAG, "#" + notiId + " notified ..");\r
+ TvLog.append("Send Notitication(#" + notiId + ")\n");\r
\r
}\r
break;\r
Log.e(TAG, "Fail to send sync");\r
break;\r
}\r
- mProviderProxy.readCheck(LastMessageId);\r
+ //mProviderProxy.readCheck(LastMessageId);\r
}\r
break;\r
\r
\r
mProviderProxy.stopNotificationServer();\r
isStarted = false;\r
+\r
+ TvLog.append("Stop NS-Provider\n");\r
}\r
break;\r
}\r
Log.i(TAG, "Create NotiListener with MainActivity");\r
\r
this.mActivity = activity;\r
- this.mProviderProxy = mActivity.getProviderExample();\r
+ this.mProviderProxy = mActivity.getProviderProxy();\r
\r
if(mProviderProxy == null) {\r
Log.i(TAG, "Fail to get providerProxy instance");\r
super.onNotificationPosted(sbn);\r
\r
Bundle bundle = sbn.getNotification().extras;\r
- //Log.i("PACKAGENAME : ", sbn.getPackageName());\r
\r
if (sbn.getPackageName().equals("android"))\r
return;\r
\r
+ Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());\r
+ Log.i(TAG, "Noti. ID : " + sbn.getId());\r
+\r
String id = Integer.toString(sbn.getId());\r
String title = bundle.getString(Notification.EXTRA_TITLE, "");\r
String body = bundle.getString(Notification.EXTRA_TEXT, "");\r
+ String source = "OCF";\r
\r
Log.i(TAG, "onNotificationPosted .. ");\r
Log.i(TAG, "Id : " + id);\r
Log.i(TAG, "Body : " + body);\r
\r
if (mProviderProxy != null) {\r
-\r
- NotificationObject notiObject = new NotificationObject(id, title);\r
- notiObject.setContentText(body);\r
- mProviderProxy.sendNSMessage(id, title, body);\r
-\r
+ mProviderProxy.sendNSMessage(id, title, body, source);\r
} else {\r
Log.i(TAG, "providerExample is NULL");\r
}\r
public void onNotificationRemoved(StatusBarNotification sbn) {\r
super.onNotificationRemoved(sbn);\r
\r
- Log.i(TAG, "onNotificationRemoved .. ");\r
+ Bundle bundle = sbn.getNotification().extras;\r
+\r
+ if (sbn.getPackageName().equals("android"))\r
+ return;\r
+\r
+ Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());\r
+ Log.i(TAG, "Noti. ID : " + sbn.getId());\r
+\r
+ mProviderProxy.readCheck(Integer.toString(sbn.getId()));\r
}\r
}\r
+++ /dev/null
-/*\r
- *******************************************************************\r
- *\r
- * Copyright 2015 Intel Corporation.\r
- *\r
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
- */\r
-\r
-package com.sec.notiproviderexample;\r
-\r
-public class NotificationObject {\r
-\r
- private static final String TITLE_KEY = "title";\r
- private static final String ID_KEY = "id";\r
- private static final String CONTENT_TEXT_KEY = "contentText";\r
- private static final String TAG = "NS_JNI_NOTI_OBJECT";\r
-\r
- private String mId = null;\r
- private String mTitle = null;\r
- private String mContentText = null;\r
-\r
- public NotificationObject(String id, String title) {\r
- this.mId = id;\r
- this.mTitle = title;\r
- }\r
-\r
- public String getContentText() {\r
-\r
- return mContentText;\r
- }\r
- public String getmTitle() {\r
-\r
- return mTitle;\r
- }\r
- public String getmId() {\r
-\r
- return mId;\r
- }\r
-\r
- public void setmId(String mId) {\r
-\r
- this.mId = mId;\r
- }\r
-\r
- public void setContentText(String contentText) {\r
-\r
- this.mContentText = contentText;\r
- }\r
-}\r
package com.sec.notiproviderexample;\r
\r
import android.content.Context;\r
+import android.os.Handler;\r
+import android.os.Message;\r
import android.util.Log;\r
\r
import org.iotivity.base.ModeType;\r
import org.iotivity.service.notification.NSConsumer;\r
import org.iotivity.service.notification.NSMessage;\r
\r
-public class ProviderProxy {\r
+import java.util.HashMap;\r
\r
- private static final String TAG = "NS_JNI_PROVIDER_PROXY";\r
+public class ProviderProxy\r
+ implements IoTNotification.NSSubscriptionListner, IoTNotification.NSSynchListner{\r
+\r
+ private static final String TAG = "NS_PROVIDER_PROXY";\r
\r
private Context mContext = null;\r
private OcResourceHandle mResourceHandle; //resource handle\r
private IoTNotification ioTNotification = null;\r
+ private HashMap<String, Integer> msgMap;\r
\r
- private final int SUCCESS = 200;\r
+ private Handler mHandler = null;\r
+ private static final int MESSAGE_SUBSCRIPTION = 1;\r
+ private static final int MESSAGE_SYNC = 2;\r
\r
public ProviderProxy(Context context) {\r
Log.i(TAG, "Create providerProxy Instance");\r
\r
+ this.msgMap = new HashMap<>();\r
this.mContext = context;\r
ioTNotification = new IoTNotification();\r
}\r
\r
+ public void setHandler(Handler handler)\r
+ {\r
+ this.mHandler = handler;\r
+ }\r
+\r
private void configurePlatform() {\r
\r
PlatformConfig platformConfig = new PlatformConfig(\r
try {\r
OcPlatform.stopPresence(); // Initialize OcPlatform\r
} catch(Exception e) {\r
- Log.e(TAG, "Exception during sropPresence: " + e);\r
+ Log.e(TAG, "Exception: stopping presence when configuration step: " + e);\r
}\r
Log.i(TAG, "Configuration done Successfully");\r
}\r
public void startNotificationServer(boolean access)\r
{\r
configurePlatform();\r
- ioTNotification.NSStartProvider(access);\r
+ ioTNotification.NSStartProvider(access, this, this);\r
}\r
\r
public void stopNotificationServer() {\r
try {\r
OcPlatform.stopPresence();\r
} catch (Exception e) {\r
- Log.e(TAG, "Exception during stopPresence to terminate ns: " + e);\r
+ Log.e(TAG, "Exception: stopping presence when terminating NS server: " + e);\r
}\r
\r
ioTNotification.NSStopProvider();\r
}\r
\r
- public void sendNSMessage(String id, String title, String body) {\r
+ public void sendNSMessage(String id, String title, String body, String source) {\r
\r
NSMessage notiMessage = new NSMessage(id);\r
notiMessage.setTitle(title);\r
notiMessage.setBody(body);\r
+ notiMessage.setSource(source);\r
+ msgMap.put(id, 1);\r
ioTNotification.NSSendNotification(notiMessage);\r
}\r
\r
public void readCheck(String messageId) {\r
-\r
- NSMessage notiMessage = new NSMessage(messageId);\r
- ioTNotification.NSProviderReadCheck(notiMessage);\r
+ if(msgMap.containsKey(messageId)) {\r
+ NSMessage notiMessage = new NSMessage(messageId);\r
+ ioTNotification.NSProviderReadCheck(notiMessage);\r
+ }\r
}\r
\r
public void accept(String consumerId, boolean accepted)\r
NSConsumer consumer = new NSConsumer(consumerId);\r
ioTNotification.NSAccept(consumer, accepted);\r
}\r
+\r
+ @Override\r
+ public void OnNSSubscribedEvent(String consumerId) {\r
+ Log.i(TAG, "OnNSSubscribedEvent");\r
+\r
+ Log.i(TAG, "Consumer: " + consumerId);\r
+ Message msg = mHandler.obtainMessage(MESSAGE_SUBSCRIPTION, consumerId);\r
+ mHandler.sendMessage(msg);\r
+ }\r
+\r
+ @Override\r
+ public void OnNSSynchronizedEvent(String messageId, int syncState) {\r
+ Log.i(TAG, "OnNSSynchronizedEvent");\r
+\r
+ Log.i(TAG, "Message Id: " + messageId);\r
+ Log.i(TAG, "Sync state: " + syncState);\r
+\r
+ Message msg = mHandler.obtainMessage(MESSAGE_SYNC, messageId + "(" + syncState + ")");\r
+ mHandler.sendMessage(msg);\r
+ }\r
}\r
--- /dev/null
+configurations.create("default")
+artifacts.add("default", file('iotivity-armeabi-notification-service-release.aar'))
\ No newline at end of file
--- /dev/null
+configurations.create("default")
+artifacts.add("default", file('iotivity-base-armeabi-release.aar'))
\ No newline at end of file
-include ':app', ':iotivity-base-armeabi-debug', ':iotivity-armeabi-notification-service-debug'\r
+include ':app', ':iotivity-armeabi-notification-service-release', ':iotivity-base-armeabi-release'\r
#define NS_ATTRIBUTE_ID "ID"
#define NS_ATTRIBUTE_TITLE "TITLE"
#define NS_ATTRIBUTE_TEXT "CONTENTTEXT"
+#define NS_ATTRIBUTE_SOURCE "SOURCE"
#define NS_ATTRIBUTE_STATE "STATE"
#define NS_ATTRIBUTE_DEVICE "DEVICE"
*/
typedef enum
{
- Notification_Read,
- Notification_Dismiss,
+ Notification_Read = 0,
+ Notification_Dismiss = 1,
+ Notification_Unread = 2,
+
} NSSyncTypes;
/**
{
char * mId;
void * mUserData;
+
} NSDevice;
/**
char * syncUri;
OCDoHandle messageHandle;
OCDoHandle syncHandle;
+
} NSProvider;
/**
char * mId;
char * mTitle;
char * mContentText;
+ char * mSource;
+
} NSMessage;
/**
//Optional
NSDevice * mDevice;
+
} NSSync;
#endif /* _NS_COMMON_H_ */
}\r
else if (OC_REST_POST == entityHandlerRequest->method)\r
{\r
+ /** Receive sync data from consumer which read or dismiss notification message.\r
+ And broadcast the sync data to all subscribers including provider app\r
+ to synchronize the notification message status. */\r
OIC_LOG (INFO, LISTENER_TAG, "Received OC_REST_POST from client");\r
NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_POST");\r
+\r
+ // send to subscribers\r
NSPushQueue(NOTIFICATION_SCHEDULER, TASK_SEND_READ,\r
NSBuildOICNotificationSync(entityHandlerRequest->payload));\r
+\r
+ // send to provider app\r
+ NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ,\r
+ NSBuildOICNotificationSync(entityHandlerRequest->payload));\r
+\r
ehResult = OC_EH_OK;\r
}\r
else if (OC_REST_DELETE == entityHandlerRequest->method)\r
\r
if (flag & OC_OBSERVE_FLAG)\r
{\r
+ /** Requested by consumers to synchronize notification message status.\r
+ Store the observer IDs to storage or cache */\r
+\r
OIC_LOG(INFO, LISTENER_TAG, "Flag includes OC_OBSERVE_FLAG");\r
\r
if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)\r