diff --git a/.github/os_probot_metadata.js b/.github/os_probot_metadata.js new file mode 100644 index 0000000000..9708a59228 --- /dev/null +++ b/.github/os_probot_metadata.js @@ -0,0 +1,58 @@ +/** + * Based on probot-metadata - https://github.com/probot/metadata + */ +const regex = /\n\n/ + +const { Octokit } = require("@octokit/action") + +const octokit = new Octokit() + +module.exports = (context, issue = null) => { + console.log(context) + const prefix = "onesignal-probot" + + if (!issue) issue = context.payload.issue + + return { + async get (key = null) { + let body = issue.body + + if (!body) { + body = (await octokit.issues.get(issue)).data.body || '' + } + + const match = body.match(regex) + + if (match) { + const data = JSON.parse(match[1])[prefix] + return key ? data && data[key] : data + } + }, + + async set (key, value) { + let body = issue.body + let data = {} + + if (!body) body = (await octokit.issues.get(issue)).data.body || '' + + body = body.replace(regex, (_, json) => { + data = JSON.parse(json) + return '' + }) + + if (!data[prefix]) data[prefix] = {} + + if (typeof key === 'object') { + Object.assign(data[prefix], key) + } else { + data[prefix][key] = value + } + + body = `${body}\n\n` + + const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/") + const issue_number = context.payload.issue.number + return octokit.issues.update({ owner, repo, issue_number, body }) + } + } +} diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000000..48f81b5af4 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,25 @@ +name-template: $RESOLVED_VERSION +tag-template: $RESOLVED_VERSION +categories: + - title: 🚀 Features + label: Enhancement / Feature + - title: 🐛 Bug Fixes + label: Bug + - title: 🧰 Improvements + label: Improvement +change-template: '- $TITLE (#$NUMBER)' +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: patch +template: | + ## Other Changes + + $CHANGES \ No newline at end of file diff --git a/.github/set_response_times.js b/.github/set_response_times.js new file mode 100644 index 0000000000..5bcac44929 --- /dev/null +++ b/.github/set_response_times.js @@ -0,0 +1,47 @@ +function calcResponseTimeForIssueCreatedAt(createdAt) { + const issueOpenedDate = new Date(createdAt); + const issueTriagedDate = new Date(); + const businessDaysResponseTime = calcBusinessDaysBetweenDates(issueOpenedDate, issueTriagedDate); + return businessDaysResponseTime; +} + +function calcBusinessDaysBetweenDates(openedDate, triagedDate) { + let differenceInWeeks, responseTime; + if (triagedDate < openedDate) + return -1; // error code if dates transposed + let openedDay = openedDate.getDay(); // day of week + let triagedDay = triagedDate.getDay(); + openedDay = (openedDay == 0) ? 7 : openedDay; // change Sunday from 0 to 7 + triagedDay = (triagedDay == 0) ? 7 : triagedDay; + openedDay = (openedDay > 5) ? 5 : openedDay; // only count weekdays + triagedDay = (triagedDay > 5) ? 5 : triagedDay; + // calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000) + differenceInWeeks = Math.floor((triagedDate.getTime() - openedDate.getTime()) / 604800000); + if (openedDay < triagedDay) { //Equal to makes it reduce 5 days + responseTime = (differenceInWeeks * 5) + (triagedDay - openedDay); + } + else if (openedDay == triagedDay) { + responseTime = differenceInWeeks * 5; + } + else { + responseTime = ((differenceInWeeks + 1) * 5) - (openedDay - triagedDay); + } + return (responseTime); +} + +module.exports = async(context, osmetadata) => { + const foundResponseTime = await osmetadata(context).get('response_time_in_business_days'); + if (foundResponseTime) { + const foundString = "already found response time in business days: " + foundResponseTime + console.log(foundString); + return foundString; + } + if (context.payload.comment && context.payload.comment.author_association != "MEMBER" && context.payload.comment.author_association != "OWNER" && context.payload.comment.author_association != "CONTRIBUTOR") { + return; + } + const businessDaysResponseTime = calcResponseTimeForIssueCreatedAt(context.payload.issue.created_at); + console.log("response time in business days: " + businessDaysResponseTime); + const result = osmetadata(context, context.payload.issue).set('response_time_in_business_days', businessDaysResponseTime) + console.log("osmetadata update result: " + result); + return "set response time in business days: " + businessDaysResponseTime; +} diff --git a/.github/workflows/Zapier.yml b/.github/workflows/Zapier.yml new file mode 100644 index 0000000000..3665dd5864 --- /dev/null +++ b/.github/workflows/Zapier.yml @@ -0,0 +1,34 @@ +# This is an action to close asana tasks that were generated by Github issues + +name: Zapier web hook + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "main" branch + issues: + types: [closed] + +permissions: + issues: read + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Runs a set of commands using the runners shell + - name: Call Zapier web hook to close Asana task + if: ${{ !github.event.issue.pull_request }} + env: + ISSUE_TITLE: ${{ github.event.issue.title }} + run: | + curl --location --request POST 'https://hooks.zapier.com/hooks/catch/12728683/b7009qc/' \ + --header 'Content-Type: application/json' \ + --header 'Accept: application/json' \ + --data-raw '{ + "task_name" : "$ISSUE_TITLE" + }' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0a5512443..5880a10486 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,15 +29,10 @@ jobs: working-directory: OneSignalSDK run: | ./gradlew ktlintCheck --console=plain - - name: "[Test] Analyzing" - working-directory: OneSignalSDK - continue-on-error: true - run: | - ./gradlew detekt --console=plain - name: "[Test] SDK Unit Tests" working-directory: OneSignalSDK run: | - ./gradlew unittest:testReleaseUnitTest --console=plain + ./gradlew test --console=plain - name: Unit tests results if: failure() uses: actions/upload-artifact@v3 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000000..439cae130b --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,41 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - main + # pull_request event is required only for autolabeler + pull_request: + # Only following types are handled by the action, but one can default to all as well + types: [opened, reopened, synchronize] + # pull_request_target event is required for autolabeler to support PRs from forks + # pull_request_target: + # types: [opened, reopened, synchronize] + +permissions: + contents: read + +jobs: + update_release_draft: + permissions: + # write permission is required to create a github release + contents: write + # write permission is required for autolabeler + # otherwise, read permission is required at least + pull-requests: write + runs-on: ubuntu-latest + steps: + # (Optional) GitHub Enterprise requires GHE_HOST variable set + #- name: Set GHE_HOST + # run: | + # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV + + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + # with: + # config-name: my-config.yml + # disable-autolabeler: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/set_response_time.yml b/.github/workflows/set_response_time.yml new file mode 100644 index 0000000000..e77fc84dd8 --- /dev/null +++ b/.github/workflows/set_response_time.yml @@ -0,0 +1,32 @@ +name: Set Response Time +on: + issue_comment: + types: + - created + issues: + types: + - closed +jobs: + calculate: + name: set reponse time for the issue + if: github.event.issue.pull_request == null + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - run: npm install @octokit/action + - uses: actions/github-script@v6 + id: set-time + with: + result-encoding: string + script: | + const os_probot_metadata = require('./.github/os_probot_metadata.js') + const set_response_time = require('./.github/set_response_times.js') + return await set_response_time(context, os_probot_metadata) + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Get result + run: echo "${{steps.set-time.outputs.result}}" >> $GITHUB_STEP_SUMMARY diff --git a/Examples/OneSignalDemo/app/agconnect-services.json b/Examples/OneSignalDemo/app/agconnect-services.json index 97036fd5bd..965d4a0f6c 100644 --- a/Examples/OneSignalDemo/app/agconnect-services.json +++ b/Examples/OneSignalDemo/app/agconnect-services.json @@ -1,49 +1,75 @@ { "agcgw":{ - "backurl":"connect-dre.dbankcloud.cn", - "url":"connect-dre.hispace.hicloud.com", - "websocketbackurl":"connect-ws-dre.hispace.dbankcloud.cn", - "websocketurl":"connect-ws-dre.hispace.dbankcloud.com" + "backurl":"connect-dre.hispace.hicloud.com", + "url":"connect-dre.dbankcloud.cn", + "websocketbackurl":"connect-ws-dre.hispace.dbankcloud.com", + "websocketurl":"connect-ws-dre.hispace.dbankcloud.cn" }, "agcgw_all":{ - "CN":"connect-drcn.hispace.hicloud.com", - "CN_back":"connect-drcn.dbankcloud.cn", - "DE":"connect-dre.hispace.hicloud.com", - "DE_back":"connect-dre.dbankcloud.cn", - "RU":"connect-drru.hispace.hicloud.com", - "RU_back":"connect-drru.dbankcloud.cn", - "SG":"connect-dra.hispace.hicloud.com", - "SG_back":"connect-dra.dbankcloud.cn" + "CN":"connect-drcn.dbankcloud.cn", + "CN_back":"connect-drcn.hispace.hicloud.com", + "DE":"connect-dre.dbankcloud.cn", + "DE_back":"connect-dre.hispace.hicloud.com", + "RU":"connect-drru.hispace.dbankcloud.ru", + "RU_back":"connect-drru.hispace.dbankcloud.cn", + "SG":"connect-dra.dbankcloud.cn", + "SG_back":"connect-dra.hispace.hicloud.com" + }, + "websocketgw_all":{ + "CN":"connect-ws-drcn.hispace.dbankcloud.cn", + "CN_back":"connect-ws-drcn.hispace.dbankcloud.com", + "DE":"connect-ws-dre.hispace.dbankcloud.cn", + "DE_back":"connect-ws-dre.hispace.dbankcloud.com", + "RU":"connect-ws-drru.hispace.dbankcloud.ru", + "RU_back":"connect-ws-drru.hispace.dbankcloud.cn", + "SG":"connect-ws-dra.hispace.dbankcloud.cn", + "SG_back":"connect-ws-dra.hispace.dbankcloud.com" }, "client":{ "cp_id":"5190001000034239317", - "product_id":"9105385871709201822", - "client_id":"336482233541985344", - "client_secret":"5E30C748A012DE67BAF83E2C542A4AB694CCAA89F1D5E8FCEFA57E0F28A077FB", - "project_id":"9105385871709201822", - "app_id":"102009847", - "api_key":"CV68fkx9E2fU8Fv/v3zbuO8+rCjJ8w6QiMha7ZJUpIGTxs08n0/ddVXbOueUKBtxf3sD+ni8WPx27htLHhtse5eP5VrT", - "package_name":"com.onesignal.example" + "product_id":"388421841221340564", + "client_id":"1103097158011211392", + "client_secret":"14843C60CAFDCFD5E50025C14864697AFF55886BCF00558E8C817F141E0B4704", + "project_id":"388421841221340564", + "app_id":"107780279", + "api_key":"DAEDAN06wwm3fsiHbQaQzugegFDUc6lpsR9VZGRNoWEbjHpDphR5rSbobUr5/ohT1WlRTyIykjr4GzzEJ/jSxlziFmXF/8e56HAYiw==", + "package_name":"com.onesignal.sdktest" }, "oauth_client":{ - "client_id":"102009847", + "client_id":"107780279", "client_type":1 }, "app_info":{ - "app_id":"102009847", - "package_name":"com.onesignal.example" + "app_id":"107780279", + "package_name":"com.onesignal.sdktest" }, "service":{ "analytics":{ "collector_url":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn", + "collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com", + "collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn", + "collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn", + "collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn", "resource_id":"p1", "channel_id":"" }, + "edukit":{ + "edu_url":"edukit.edu.cloud.huawei.com.cn", + "dh_url":"edukit.edu.cloud.huawei.com.cn" + }, "search":{ "url":"https://search-dre.cloud.huawei.com" }, "cloudstorage":{ - "storage_url":"https://ops-dre.agcstorage.link" + "storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia", + "storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru", + "storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru", + "storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu", + "storage_url_de":"https://ops-dre.agcstorage.link", + "storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn", + "storage_url_sg":"https://ops-dra.agcstorage.link", + "storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn", + "storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn" }, "ml":{ "mlservice_url":"ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn" @@ -53,17 +79,17 @@ "configuration_version":"3.0", "appInfos":[ { - "package_name":"com.onesignal.example", + "package_name":"com.onesignal.sdktest", "client":{ - "app_id":"102009847" + "app_id":"107780279" }, "app_info":{ - "package_name":"com.onesignal.example", - "app_id":"102009847" + "package_name":"com.onesignal.sdktest", + "app_id":"107780279" }, "oauth_client":{ "client_type":1, - "client_id":"102009847" + "client_id":"107780279" } } ] diff --git a/Examples/OneSignalDemo/app/build.gradle b/Examples/OneSignalDemo/app/build.gradle index 2cf76baad0..94a542ab4b 100644 --- a/Examples/OneSignalDemo/app/build.gradle +++ b/Examples/OneSignalDemo/app/build.gradle @@ -1,10 +1,12 @@ -apply plugin: 'com.android.application' +plugins { + id 'com.android.application' +} android { - compileSdkVersion 31 + compileSdkVersion 33 defaultConfig { - minSdkVersion 16 - targetSdkVersion 31 + minSdkVersion 19 + targetSdkVersion 33 versionCode 1 versionName "1.0" multiDexEnabled true @@ -13,12 +15,16 @@ android { flavorDimensions "default" } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } +// signingConfigs { +// huawei { +// storeFile file('SdkTest.jks') +// keyAlias 'SdkTest' +// keyPassword '' +// storePassword '' +// v1SigningEnabled true +// v2SigningEnabled true +// } +// } productFlavors { gms { @@ -27,8 +33,20 @@ android { } huawei { dimension "default" - minSdkVersion 17 - applicationId "com.onesignal.example" + minSdkVersion 19 + applicationId "com.onesignal.sdktest" + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { +// signingConfig null +// productFlavors.huawei.signingConfig signingConfigs.huawei + debuggable true } } @@ -54,24 +72,24 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - implementation 'com.android.support:multidex:1.0.3' - implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.appcompat:appcompat:1.4.0' + implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.vectordrawable:vectordrawable:1.1.0' - implementation 'com.google.android.gms:play-services-location:18.0.0' + implementation 'com.google.android.material:material:1.7.0' + implementation 'com.google.android.gms:play-services-location:21.0.0' implementation 'com.github.bumptech.glide:glide:4.12.0' /** START - Google Play Builds **/ - gmsImplementation('com.onesignal:OneSignal:4.6.3') + gmsImplementation('com.onesignal:OneSignal:5.1.0') /** END - Google Play Builds **/ /** START - Huawei Builds **/ // Omit Google / Firebase libraries for Huawei builds. - huaweiImplementation('com.onesignal:OneSignal:4.6.3') { + huaweiImplementation('com.onesignal:OneSignal:5.1.0') { exclude group: 'com.google.android.gms', module: 'play-services-gcm' exclude group: 'com.google.android.gms', module: 'play-services-analytics' exclude group: 'com.google.android.gms', module: 'play-services-location' diff --git a/Examples/OneSignalDemo/app/src/huawei/java/com/onesignal/sdktest/notification/HmsMessageServiceAppLevel.java b/Examples/OneSignalDemo/app/src/huawei/java/com/onesignal/sdktest/notification/HmsMessageServiceAppLevel.java index 21d20f86f6..1d49484664 100644 --- a/Examples/OneSignalDemo/app/src/huawei/java/com/onesignal/sdktest/notification/HmsMessageServiceAppLevel.java +++ b/Examples/OneSignalDemo/app/src/huawei/java/com/onesignal/sdktest/notification/HmsMessageServiceAppLevel.java @@ -1,11 +1,12 @@ package com.onesignal.sdktest.notification; import android.os.Bundle; +import android.util.Log; import com.huawei.hms.push.HmsMessageService; import com.huawei.hms.push.RemoteMessage; -import com.onesignal.OneSignal; -import com.onesignal.OneSignalHmsEventBridge; +import com.onesignal.notifications.bridges.OneSignalHmsEventBridge; +import com.onesignal.sdktest.constant.Tag; public class HmsMessageServiceAppLevel extends HmsMessageService { @@ -19,19 +20,19 @@ public class HmsMessageServiceAppLevel extends HmsMessageService { */ @Override public void onNewToken(String token, Bundle bundle) { - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HmsMessageServiceAppLevel onNewToken refresh token:" + token + " bundle: " + bundle); + Log.d(Tag.LOG_TAG, "HmsMessageServiceAppLevel onNewToken refresh token:" + token + " bundle: " + bundle); // Forward event on to OneSignal SDK - OneSignalHmsEventBridge.onNewToken(this, token, bundle); + OneSignalHmsEventBridge.INSTANCE.onNewToken(this, token, bundle); } @Deprecated @Override public void onNewToken(String token) { - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HmsMessageServiceAppLevel onNewToken refresh token:" + token); + Log.d(Tag.LOG_TAG, "HmsMessageServiceAppLevel onNewToken refresh token:" + token); // Forward event on to OneSignal SDK - OneSignalHmsEventBridge.onNewToken(this, token); + OneSignalHmsEventBridge.INSTANCE.onNewToken(this, token); } /** @@ -44,18 +45,18 @@ public void onNewToken(String token) { */ @Override public void onMessageReceived(RemoteMessage message) { - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived: " + message); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.ttl:" + message.getTtl()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.data:" + message.getData()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.title: " + message.getNotification().getTitle()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.body: " + message.getNotification().getBody()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.icon: " + message.getNotification().getIcon()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.color: " + message.getNotification().getColor()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.channelId: " + message.getNotification().getChannelId()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.imageURL: " + message.getNotification().getImageUrl()); - OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "HMS onMessageReceived.tag: " + message.getNotification().getTag()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived: " + message); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.ttl:" + message.getTtl()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.data:" + message.getData()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.title: " + message.getNotification().getTitle()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.body: " + message.getNotification().getBody()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.icon: " + message.getNotification().getIcon()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.color: " + message.getNotification().getColor()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.channelId: " + message.getNotification().getChannelId()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.imageURL: " + message.getNotification().getImageUrl()); + Log.d(Tag.LOG_TAG, "HMS onMessageReceived.tag: " + message.getNotification().getTag()); // Forward event on to OneSignal SDK - OneSignalHmsEventBridge.onMessageReceived(this, message); + OneSignalHmsEventBridge.INSTANCE.onMessageReceived(this, message); } } diff --git a/Examples/OneSignalDemo/app/src/main/AndroidManifest.xml b/Examples/OneSignalDemo/app/src/main/AndroidManifest.xml index 449ae4a97e..14d81d3f3d 100644 --- a/Examples/OneSignalDemo/app/src/main/AndroidManifest.xml +++ b/Examples/OneSignalDemo/app/src/main/AndroidManifest.xml @@ -46,17 +46,17 @@ diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/activity/MainActivity.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/activity/MainActivity.java index 3f21992ee7..82f307615e 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/activity/MainActivity.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/activity/MainActivity.java @@ -6,7 +6,7 @@ import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; -import com.onesignal.core.OneSignal; +import com.onesignal.OneSignal; import com.onesignal.sdktest.R; import com.onesignal.sdktest.model.MainActivityViewModel; @@ -21,7 +21,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.main_activity_layout); viewModel = new MainActivityViewModel(); - OneSignal.getNotifications().addPushPermissionHandler(viewModel); + OneSignal.getNotifications().addPermissionObserver(viewModel); // TODO("STILL SUPPORT?") // OneSignal.addSubscriptionObserver(viewModel); // OneSignal.addEmailSubscriptionObserver(viewModel); @@ -41,7 +41,7 @@ public void onBackPressed() { protected void onResume() { super.onResume(); - boolean hasConsent = OneSignal.getRequiresPrivacyConsent(); + boolean hasConsent = OneSignal.getConsentGiven(); if (hasConsent) viewModel.setupLayout(); } diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/PairRecyclerViewAdapter.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/PairRecyclerViewAdapter.java index dda58ef910..6315ba5b0d 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/PairRecyclerViewAdapter.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/PairRecyclerViewAdapter.java @@ -81,8 +81,10 @@ private void populateInterfaceElements(final int position) { if (Util.isBoolean(value)) value += " (bool)"; - else if (Util.isNumeric(value)) - value += " (num)"; + else if (Util.isInteger(value)) + value += " (int)"; + else if (Util.isFloat(value)) + value += " (float)"; else value += " (str)"; pairValueTextView.setText(value); diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/SingleRecyclerViewAdapter.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/SingleRecyclerViewAdapter.java index 401dbfe7d1..7cae936707 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/SingleRecyclerViewAdapter.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/SingleRecyclerViewAdapter.java @@ -76,8 +76,10 @@ private void populateInterfaceElements(final int position) { if (Util.isBoolean(value)) value += " (bool)"; - else if (Util.isNumeric(value)) - value += " (num)"; + else if (Util.isInteger(value)) + value += " (int)"; + else if (Util.isFloat(value)) + value += " (float)"; else value += " (str)"; singleTextView.setText(value); diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/SubscriptionRecyclerViewAdapter.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/SubscriptionRecyclerViewAdapter.java new file mode 100644 index 0000000000..c7a49f2645 --- /dev/null +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/adapter/SubscriptionRecyclerViewAdapter.java @@ -0,0 +1,105 @@ +package com.onesignal.sdktest.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.onesignal.sdktest.R; +import com.onesignal.sdktest.callback.SingleItemActionCallback; +import com.onesignal.sdktest.callback.SubscriptionItemActionCallback; +import com.onesignal.user.subscriptions.IEmailSubscription; +import com.onesignal.user.subscriptions.ISmsSubscription; +import com.onesignal.user.subscriptions.ISubscription; + +import java.util.ArrayList; + +public class SubscriptionRecyclerViewAdapter extends RecyclerView.Adapter { + + private LayoutInflater layoutInflater; + + private Context context; + + private ArrayList subscriptions; + private SubscriptionItemActionCallback callback; + + public SubscriptionRecyclerViewAdapter(Context context, ArrayList subscriptions, SubscriptionItemActionCallback callback) { + this.context = context; + + this.subscriptions = subscriptions; + this.callback = callback; + + layoutInflater = LayoutInflater.from(context); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) { + View view = layoutInflater.inflate(R.layout.subscription_recycler_view_item_layout, parent, false); + view.setHasTransientState(true); + return new SubscriptionViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + ((SubscriptionViewHolder) holder).setData(position, subscriptions.get(position)); + } + + @Override + public int getItemCount() { + return subscriptions.size(); + } + + public class SubscriptionViewHolder extends RecyclerView.ViewHolder { + + private LinearLayout singleLinearLayout; + private TextView idTextView; + private TextView addressTitleTextView; + private TextView addressTextView; + + private ISubscription item; + + SubscriptionViewHolder(View itemView) { + super(itemView); + + singleLinearLayout = itemView.findViewById(R.id.subscription_recycler_view_item_linear_layout); + idTextView = itemView.findViewById(R.id.subscription_recycler_view_item_id_text_view); + addressTitleTextView = itemView.findViewById(R.id.subscription_recycler_view_item_address_title_text_view); + addressTextView = itemView.findViewById(R.id.subscription_recycler_view_item_address_text_view); + } + + private void setData(int position, ISubscription item) { + this.item = item; + populateInterfaceElements(position); + } + + private void populateInterfaceElements(final int position) { + idTextView.setText(item.getId()); + + if(item instanceof IEmailSubscription) { + addressTitleTextView.setText(R.string.email_colon); + addressTextView.setText(((IEmailSubscription) item).getEmail()); + } + else if(item instanceof ISmsSubscription) { + addressTitleTextView.setText(R.string.sms_colon); + addressTextView.setText(((ISmsSubscription) item).getNumber()); + } + + singleLinearLayout.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + callback.onLongClick(item); + return false; + } + }); + + } + + } + +} diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/application/MainApplication.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/application/MainApplication.java index 71c8d59c86..7c48f4b070 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/application/MainApplication.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/application/MainApplication.java @@ -7,22 +7,32 @@ import androidx.annotation.Nullable; import androidx.multidex.MultiDexApplication; -import com.onesignal.core.OneSignal; -import com.onesignal.iam.IInAppMessage; -import com.onesignal.iam.IInAppMessageAction; -import com.onesignal.iam.IInAppMessageClickHandler; -import com.onesignal.iam.IInAppMessageLifecycleHandler; -import com.onesignal.core.debug.LogLevel; -import com.onesignal.notification.INotification; +import com.onesignal.OneSignal; +import com.onesignal.inAppMessages.IInAppMessageClickListener; +import com.onesignal.inAppMessages.IInAppMessageClickEvent; +import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent; +import com.onesignal.inAppMessages.IInAppMessageDidDisplayEvent; +import com.onesignal.inAppMessages.IInAppMessageLifecycleListener; +import com.onesignal.debug.LogLevel; +import com.onesignal.inAppMessages.IInAppMessageWillDismissEvent; +import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent; +import com.onesignal.notifications.IDisplayableNotification; +import com.onesignal.notifications.INotificationLifecycleListener; +import com.onesignal.notifications.INotificationWillDisplayEvent; import com.onesignal.sdktest.BuildConfig; import com.onesignal.sdktest.R; import com.onesignal.sdktest.constant.Tag; import com.onesignal.sdktest.constant.Text; +import com.onesignal.sdktest.notification.OneSignalNotificationSender; import com.onesignal.sdktest.util.SharedPreferenceUtil; +import com.onesignal.user.state.IUserStateObserver; +import com.onesignal.user.state.UserChangedState; +import com.onesignal.user.state.UserState; import org.json.JSONObject; public class MainApplication extends MultiDexApplication { + private static final int SLEEP_TIME_TO_MIMIC_ASYNC_OPERATION = 2000; public MainApplication() { // run strict mode default in debug mode to surface any potential issues easier @@ -43,58 +53,83 @@ public void onCreate() { SharedPreferenceUtil.cacheOneSignalAppId(this, appId); } + OneSignalNotificationSender.setAppId(appId); OneSignal.initWithContext(this, appId); - OneSignal.getIam().setInAppMessageLifecycleHandler(new IInAppMessageLifecycleHandler() { + OneSignal.getInAppMessages().addLifecycleListener(new IInAppMessageLifecycleListener() { @Override - public void onWillDisplayInAppMessage(@NonNull IInAppMessage message) { - Log.v("MainApplication", "onWillDisplayInAppMessage"); + public void onWillDisplay(@NonNull IInAppMessageWillDisplayEvent event) { + Log.v(Tag.LOG_TAG, "onWillDisplayInAppMessage"); } @Override - public void onDidDisplayInAppMessage(@NonNull IInAppMessage message) { - Log.v("MainApplication", "onDidDisplayInAppMessage"); + public void onDidDisplay(@NonNull IInAppMessageDidDisplayEvent event) { + Log.v(Tag.LOG_TAG, "onDidDisplayInAppMessage"); } @Override - public void onWillDismissInAppMessage(@NonNull IInAppMessage message) { - Log.v("MainApplication", "onWillDismissInAppMessage"); + public void onWillDismiss(@NonNull IInAppMessageWillDismissEvent event) { + Log.v(Tag.LOG_TAG, "onWillDismissInAppMessage"); } @Override - public void onDidDismissInAppMessage(@NonNull IInAppMessage message) { - Log.v("MainApplication", "onDidDismissInAppMessage"); + public void onDidDismiss(@NonNull IInAppMessageDidDismissEvent event) { + Log.v(Tag.LOG_TAG, "onDidDismissInAppMessage"); } }); - OneSignal.getIam().setInAppMessageClickHandler(new IInAppMessageClickHandler() { + OneSignal.getInAppMessages().addClickListener(new IInAppMessageClickListener() { @Override - public void inAppMessageClicked(@Nullable IInAppMessageAction result) { - Log.v("MainApplication", "inAppMessageClicked"); + public void onClick(@Nullable IInAppMessageClickEvent event) { + Log.v(Tag.LOG_TAG, "INotificationClickListener.inAppMessageClicked"); } }); - OneSignal.getNotifications().setNotificationOpenedHandler(result -> - { - Log.v("MainApplication", "INotificationOpenedResult: " + result); - }); - - OneSignal.getNotifications().setNotificationWillShowInForegroundHandler(notificationReceivedEvent -> - { - Log.v("MainApplication", "NotificationWillShowInForegroundHandler fired!" + - " with notification event: " + notificationReceivedEvent.toString()); + OneSignal.getNotifications().addClickListener(event -> + { + Log.v(Tag.LOG_TAG, "INotificationClickListener.onClick fired" + + " with event: " + event); + }); - INotification notification = notificationReceivedEvent.getNotification(); - JSONObject data = notification.getAdditionalData(); + OneSignal.getNotifications().addForegroundLifecycleListener(new INotificationLifecycleListener() { + @Override + public void onWillDisplay(@NonNull INotificationWillDisplayEvent event) { + Log.v(Tag.LOG_TAG, "INotificationLifecycleListener.onWillDisplay fired" + + " with event: " + event); + + IDisplayableNotification notification = event.getNotification(); + JSONObject data = notification.getAdditionalData(); + + //Prevent OneSignal from displaying the notification immediately on return. Spin + //up a new thread to mimic some asynchronous behavior, when the async behavior (which + //takes 2 seconds) completes, then the notification can be displayed. + event.preventDefault(); + Runnable r = () -> { + try { + Thread.sleep(SLEEP_TIME_TO_MIMIC_ASYNC_OPERATION); + } catch (InterruptedException ignored) { + } + + notification.display(); + }; + + Thread t = new Thread(r); + t.start(); + } + }); - notificationReceivedEvent.complete(notification); - }); + OneSignal.getUser().addObserver(new IUserStateObserver() { + @Override + public void onUserStateChange(@NonNull UserChangedState state) { + UserState currentUserState = state.getCurrent(); + Log.v(Tag.LOG_TAG, "onUserStateChange fired " + currentUserState.toJSONObject()); + } + }); - OneSignal.getNotifications().setUnsubscribeWhenNotificationsAreDisabled(true); - OneSignal.getIam().setPaused(true); - OneSignal.getLocation().setLocationShared(false); + OneSignal.getInAppMessages().setPaused(true); + OneSignal.getLocation().setShared(false); - Log.d(Tag.DEBUG, Text.ONESIGNAL_SDK_INIT); + Log.d(Tag.LOG_TAG, Text.ONESIGNAL_SDK_INIT); } } diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/callback/SubscriptionItemActionCallback.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/callback/SubscriptionItemActionCallback.java new file mode 100644 index 0000000000..579faaa25b --- /dev/null +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/callback/SubscriptionItemActionCallback.java @@ -0,0 +1,9 @@ +package com.onesignal.sdktest.callback; + +import com.onesignal.user.subscriptions.ISubscription; + +public interface SubscriptionItemActionCallback { + + void onLongClick(ISubscription value); + +} diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/constant/Tag.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/constant/Tag.java index f7cef94065..927df53e4f 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/constant/Tag.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/constant/Tag.java @@ -1,8 +1,5 @@ package com.onesignal.sdktest.constant; public class Tag { - - public static final String DEBUG = "DEBUG"; - public static final String ERROR = "ERROR"; - + public static final String LOG_TAG = "sdktest"; } diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/ActivityViewModel.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/ActivityViewModel.java index 09ad08f028..8aeb6fcbd3 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/ActivityViewModel.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/ActivityViewModel.java @@ -4,13 +4,13 @@ import android.content.Context; import androidx.appcompat.app.AppCompatActivity; -import com.onesignal.notification.IPermissionChangedHandler; +import com.onesignal.notifications.IPermissionObserver; /** * This is the interface created with a few generic methods for setting a ViewModel * as the responsible guardian of an Activity */ -public interface ActivityViewModel extends IPermissionChangedHandler { // TODO() extends OSPermissionObserver, OSSubscriptionObserver, OSEmailSubscriptionObserver { +public interface ActivityViewModel extends IPermissionObserver { /** * Casts Context of the given Activity to an Activity object diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java index 6374068ffa..e54538fed2 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java @@ -3,7 +3,7 @@ import android.app.Activity; import android.content.Context; import com.google.android.material.appbar.AppBarLayout; - +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.core.widget.NestedScrollView; @@ -12,9 +12,9 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.appcompat.widget.Toolbar; - import android.content.Intent; import android.os.Build; +import android.util.Log; import android.util.Pair; import android.view.View; import android.view.ViewTreeObserver; @@ -23,19 +23,16 @@ import android.widget.RelativeLayout; import android.widget.Switch; import android.widget.TextView; - -import com.onesignal.core.Continue; -import com.onesignal.core.OneSignal; -import com.onesignal.notification.IPermissionStateChanges; -import com.onesignal.core.user.subscriptions.IEmailSubscription; -import com.onesignal.core.user.subscriptions.IPushSubscription; -import com.onesignal.core.user.subscriptions.ISmsSubscription; +import com.onesignal.Continue; +import com.onesignal.OneSignal; +import com.onesignal.sdktest.adapter.SubscriptionRecyclerViewAdapter; +import com.onesignal.sdktest.constant.Tag; +import com.onesignal.user.subscriptions.IPushSubscription; import com.onesignal.sdktest.R; import com.onesignal.sdktest.activity.SecondaryActivity; import com.onesignal.sdktest.adapter.InAppMessageRecyclerViewAdapter; import com.onesignal.sdktest.adapter.NotificationRecyclerViewAdapter; import com.onesignal.sdktest.adapter.PairRecyclerViewAdapter; -import com.onesignal.sdktest.adapter.SingleRecyclerViewAdapter; import com.onesignal.sdktest.callback.AddPairAlertDialogCallback; import com.onesignal.sdktest.callback.PairItemActionCallback; import com.onesignal.sdktest.callback.SendOutcomeAlertDialogCallback; @@ -53,14 +50,15 @@ import com.onesignal.sdktest.util.SharedPreferenceUtil; import com.onesignal.sdktest.util.ProfileUtil; import com.onesignal.sdktest.util.Toaster; - +import com.onesignal.user.subscriptions.ISubscription; +import com.onesignal.user.subscriptions.IPushSubscriptionObserver; +import com.onesignal.user.subscriptions.PushSubscriptionChangedState; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; @RequiresApi(api = Build.VERSION_CODES.N) -public class MainActivityViewModel implements ActivityViewModel { +public class MainActivityViewModel implements ActivityViewModel, IPushSubscriptionObserver { private Animate animate; private Dialog dialog; @@ -84,7 +82,8 @@ public class MainActivityViewModel implements ActivityViewModel { private RelativeLayout appIdRelativeLayout; private TextView appIdTitleTextView; private TextView appIdTextView; - private Button switchUserButton; + private Button loginUserButton; + private Button logoutUserButton; // Alias private TextView aliasTitleTextView; @@ -110,14 +109,15 @@ public class MainActivityViewModel implements ActivityViewModel { private PairRecyclerViewAdapter tagPairRecyclerViewAdapter; private RecyclerView emailsRecyclerView; - private SingleRecyclerViewAdapter emailsRecyclerViewAdapter; + private SubscriptionRecyclerViewAdapter emailsRecyclerViewAdapter; private RecyclerView smssRecyclerView; - private SingleRecyclerViewAdapter smssRecyclerViewAdapter; + private SubscriptionRecyclerViewAdapter smssRecyclerViewAdapter; private Button addTagButton; // Notification Demo private TextView pushNotificationTitleTextView; + private TextView sendPushNotificationTitleTextView; private RecyclerView pushNotificationRecyclerView; private NotificationRecyclerViewAdapter pushNotificationRecyclerViewAdapter; @@ -134,6 +134,7 @@ public class MainActivityViewModel implements ActivityViewModel { // In App Messaging Demo private TextView inAppMessagingTitleTextView; + private TextView sendInAppMessagingTitleTextView; private RecyclerView inAppMessagingRecyclerView; private InAppMessageRecyclerViewAdapter inAppMessagingRecyclerViewAdapter; @@ -145,11 +146,19 @@ public class MainActivityViewModel implements ActivityViewModel { private Switch locationSharedSwitch; private Button promptLocationButton; + // Misc Buttons for Testing + private TextView miscButtonsTitleTextView; + private Button miscButton1; + private Button miscButton2; + private Button miscButton3; + // Push - private RelativeLayout subscriptionRelativeLayout; - private TextView subscriptionTextView; - private TextView subscriptionDescriptionTextView; - private Switch subscriptionSwitch; + private TextView pushSubscriptionIdTitleTextView; + private TextView pushSubscriptionIdTextView; + private RelativeLayout pushSubscriptionEnabledRelativeLayout; + private TextView pushSubscriptionEnabledTitleTextView; + private Switch pushSubscriptionEnabledSwitch; + private LinearLayout promptPushBottonLayout; private Button promptPushButton; private RelativeLayout pauseInAppMessagesRelativeLayout; private TextView pauseInAppMessagesTextView; @@ -161,11 +170,10 @@ public class MainActivityViewModel implements ActivityViewModel { private Context context; - private Boolean isLoggedIn = false; private HashMap aliasSet; private ArrayList aliasArrayList; - private ArrayList emailArrayList; - private ArrayList smsArrayList; + private ArrayList emailArrayList; + private ArrayList smsArrayList; private HashMap tagSet; private ArrayList tagArrayList; @@ -208,7 +216,8 @@ public ActivityViewModel onActivityCreated(Context context) { appIdTitleTextView = getActivity().findViewById(R.id.main_activity_account_details_app_id_title_text_view); appIdTextView = getActivity().findViewById(R.id.main_activity_account_details_app_id_text_view); revokeConsentButton = getActivity().findViewById(R.id.main_activity_app_revoke_consent_button); - switchUserButton = getActivity().findViewById(R.id.main_activity_switch_user_button); + loginUserButton = getActivity().findViewById(R.id.main_activity_login_user_button); + logoutUserButton = getActivity().findViewById(R.id.main_activity_logout_user_button); aliasTitleTextView = getActivity().findViewById(R.id.main_activity_aliases_title_text_view); noAliasesTextView = getActivity().findViewById(R.id.main_activity_aliases_no_aliases_text_view); @@ -231,6 +240,7 @@ public ActivityViewModel onActivityCreated(Context context) { addTagButton = getActivity().findViewById(R.id.main_activity_add_tags_button); pushNotificationTitleTextView = getActivity().findViewById(R.id.main_activity_push_notification_title_text_view); + sendPushNotificationTitleTextView= getActivity().findViewById(R.id.main_activity_send_push_notification_title_text_view); pushNotificationRecyclerView = getActivity().findViewById(R.id.main_activity_push_notification_recycler_view); outcomeTitleTextView = getActivity().findViewById(R.id.main_activity_outcomes_title_text_view); @@ -242,6 +252,7 @@ public ActivityViewModel onActivityCreated(Context context) { addTriggerButton = getActivity().findViewById(R.id.main_activity_add_triggers_button); inAppMessagingTitleTextView = getActivity().findViewById(R.id.main_activity_in_app_messaging_title_text_view); + sendInAppMessagingTitleTextView = getActivity().findViewById(R.id.main_activity_send_in_app_messaging_title_text_view); inAppMessagingRecyclerView = getActivity().findViewById(R.id.main_activity_in_app_messaging_recycler_view); locationTitleTextView = getActivity().findViewById(R.id.main_activity_location_title_text_view); @@ -251,10 +262,18 @@ public ActivityViewModel onActivityCreated(Context context) { locationSharedSwitch = getActivity().findViewById(R.id.main_activity_location_shared_switch); promptLocationButton = getActivity().findViewById(R.id.main_activity_location_prompt_location_button); - subscriptionRelativeLayout = getActivity().findViewById(R.id.main_activity_push_subscription_relative_layout); - subscriptionTextView = getActivity().findViewById(R.id.main_activity_push_subscription_text_view); - subscriptionDescriptionTextView = getActivity().findViewById(R.id.main_activity_push_subscription_info_text_view); - subscriptionSwitch = getActivity().findViewById(R.id.main_activity_push_subscription_switch); + miscButtonsTitleTextView = getActivity().findViewById(R.id.main_activity_misc_buttons_title_text_view); + miscButton1 = getActivity().findViewById(R.id.main_activity_misc_1_button); + miscButton2 = getActivity().findViewById(R.id.main_activity_misc_2_button); + miscButton3 = getActivity().findViewById(R.id.main_activity_misc_3_button); + + pushSubscriptionEnabledRelativeLayout = getActivity().findViewById(R.id.main_activity_push_subscription_relative_layout); + pushSubscriptionEnabledTitleTextView = getActivity().findViewById(R.id.main_activity_push_subscription_info_text_view); + pushSubscriptionIdTitleTextView = getActivity().findViewById(R.id.main_activity_push_subscription_id_title_text_view); + pushSubscriptionIdTextView = getActivity().findViewById(R.id.main_activity_push_subscription_id_text_view); + pushSubscriptionEnabledSwitch = getActivity().findViewById(R.id.main_activity_push_subscription_switch); + + promptPushBottonLayout = getActivity().findViewById(R.id.main_activity_push_prompt_layout); promptPushButton = getActivity().findViewById(R.id.main_activity_push_prompt_push_button); pauseInAppMessagesRelativeLayout = getActivity().findViewById(R.id.main_activity_iam_pause_in_app_messages_relative_layout); @@ -279,6 +298,7 @@ public ActivityViewModel onActivityCreated(Context context) { triggerSet = new HashMap<>(); triggerArrayList = new ArrayList<>(); + OneSignal.getUser().getPushSubscription().addObserver(this); return this; } @@ -290,7 +310,8 @@ public ActivityViewModel setupInterfaceElements() { font.applyFont(privacyConsentAllowButton, font.saralaBold); font.applyFont(appIdTitleTextView, font.saralaBold); font.applyFont(appIdTextView, font.saralaRegular); - font.applyFont(switchUserButton, font.saralaBold); + font.applyFont(loginUserButton, font.saralaBold); + font.applyFont(logoutUserButton, font.saralaBold); font.applyFont(aliasTitleTextView, font.saralaBold); font.applyFont(noAliasesTextView, font.saralaBold); font.applyFont(emailHeaderTextView, font.saralaBold); @@ -301,22 +322,28 @@ public ActivityViewModel setupInterfaceElements() { font.applyFont(noTagsTextView, font.saralaBold); font.applyFont(addTagButton, font.saralaBold); font.applyFont(pushNotificationTitleTextView, font.saralaBold); + font.applyFont(sendPushNotificationTitleTextView, font.saralaBold); font.applyFont(outcomeTitleTextView, font.saralaBold); font.applyFont(sendOutcomeButton, font.saralaBold); font.applyFont(triggersTitleTextView, font.saralaBold); font.applyFont(noTriggersTextView, font.saralaBold); font.applyFont(addTriggerButton, font.saralaBold); font.applyFont(inAppMessagingTitleTextView, font.saralaBold); + font.applyFont(sendInAppMessagingTitleTextView, font.saralaBold); font.applyFont(locationTitleTextView, font.saralaBold); font.applyFont(locationSharedTextView, font.saralaBold); font.applyFont(locationSharedDescriptionTextView, font.saralaRegular); font.applyFont(promptLocationButton, font.saralaBold); font.applyFont(promptPushButton, font.saralaBold); - font.applyFont(subscriptionTextView, font.saralaBold); - font.applyFont(subscriptionDescriptionTextView, font.saralaRegular); + font.applyFont(pushSubscriptionEnabledTitleTextView, font.saralaBold); + font.applyFont(pushSubscriptionIdTitleTextView, font.saralaBold); font.applyFont(pauseInAppMessagesTextView, font.saralaBold); font.applyFont(pauseInAppMessagesDescriptionTextView, font.saralaRegular); font.applyFont(revokeConsentButton, font.saralaBold); + font.applyFont(miscButtonsTitleTextView, font.saralaBold); + font.applyFont(miscButton1, font.saralaBold); + font.applyFont(miscButton2, font.saralaBold); + font.applyFont(miscButton3, font.saralaBold); boolean hasConsent = SharedPreferenceUtil.getUserPrivacyConsent(context); setupConsentLayout(hasConsent); @@ -344,7 +371,7 @@ public void networkDisconnected() { } @Override - public void onPermissionChanged(@Nullable IPermissionStateChanges stateChanges) { + public void onNotificationPermissionChange(@Nullable boolean permission) { refreshSubscriptionState(); } @@ -388,37 +415,40 @@ public void onScrollChanged() { private void setupAppLayout() { revokeConsentButton.setOnClickListener(v -> togglePrivacyConsent(false)); - if(OneSignal.getUser().getAliases().containsKey("external_id")) { - isLoggedIn = true; - switchUserButton.setText(R.string.logout_user); - } - - switchUserButton.setOnClickListener(v -> { - if(isLoggedIn) { - OneSignal.logout(); - isLoggedIn = false; - switchUserButton.setText(R.string.login_user); - refreshState(); - } - else { - dialog.createUpdateAlertDialog(OneSignal.getUser().getExternalId(), Dialog.DialogAction.LOGIN, ProfileUtil.FieldType.EXTERNAL_USER_ID, new UpdateAlertDialogCallback() { - @Override - public void onSuccess(String update) { - if (update != null && !update.isEmpty()) { - OneSignal.login(update, Continue.with(r -> { - isLoggedIn = true; - switchUserButton.setText(R.string.logout_user); - refreshState(); - })); - } + loginUserButton.setOnClickListener(v -> { + dialog.createUpdateAlertDialog("", Dialog.DialogAction.LOGIN, ProfileUtil.FieldType.EXTERNAL_USER_ID, new UpdateAlertDialogCallback() { + @Override + public void onSuccess(String update) { + if (update != null && !update.isEmpty()) { + OneSignal.login(update); + refreshState(); } + } - @Override - public void onFailure() { + @Override + public void onFailure() { - } - }); - } + } + }); + }); + + logoutUserButton.setOnClickListener(v -> { + OneSignal.logout(); + refreshState(); + }); + + // Misc Buttons to help with testing + + miscButton1.setOnClickListener(v -> { + Log.v(Tag.LOG_TAG, "Fill out what you want this button to do!!"); + }); + + miscButton2.setOnClickListener(v -> { + Log.v(Tag.LOG_TAG, "Fill out what you want this button to do!!"); + }); + + miscButton3.setOnClickListener(v -> { + Log.v(Tag.LOG_TAG, "Fill out what you want this button to do!!"); }); } @@ -490,15 +520,35 @@ public void run() { }); } + @Override + public void onPushSubscriptionChange(@NonNull PushSubscriptionChangedState state) { + refreshSubscriptionState(); + } + + private class DummySubscription implements ISubscription { + + private String _id; + public DummySubscription(String id) { + _id = id; + } + + @NonNull + @Override + public String getId() { + return _id; + } + } + private void setupEmailLayout() { setupEmailRecyclerView(); + MainActivityViewModel self = this; addEmailButton.setOnClickListener(v -> dialog.createUpdateAlertDialog("", Dialog.DialogAction.ADD, ProfileUtil.FieldType.EMAIL, new UpdateAlertDialogCallback() { @Override public void onSuccess(String value) { if (value != null && !value.isEmpty()) { - OneSignal.getUser().addEmailSubscription(value.toString()); - emailArrayList.add(value); + OneSignal.getUser().addEmail(value); + emailArrayList.add(new DummySubscription(value)); toaster.makeCustomViewToast("Added email " + value, ToastType.SUCCESS); } @@ -515,12 +565,13 @@ public void onFailure() { private void setupSMSLayout() { setupSMSRecyclerView(); + MainActivityViewModel self = this; addSMSButton.setOnClickListener(v -> dialog.createUpdateAlertDialog("", Dialog.DialogAction.ADD, ProfileUtil.FieldType.SMS, new UpdateAlertDialogCallback() { @Override public void onSuccess(String value) { if (value != null && !value.isEmpty()) { - OneSignal.getUser().addSmsSubscription(value); - smsArrayList.add(value); + OneSignal.getUser().addSms(value); + smsArrayList.add(new DummySubscription(value)); toaster.makeCustomViewToast("Added SMS " + value, ToastType.SUCCESS); } @@ -545,7 +596,7 @@ public void onSuccess(Pair pair) { tagSet.remove(pair.first); toaster.makeCustomViewToast("Deleted tag " + pair.first, ToastType.SUCCESS); } else { - OneSignal.getUser().setTag(pair.first, pair.second.toString()); + OneSignal.getUser().addTag(pair.first, pair.second.toString()); tagSet.put(pair.first, pair.second); toaster.makeCustomViewToast("Added tag " + pair.first, ToastType.SUCCESS); } @@ -598,11 +649,12 @@ private void setupEmailRecyclerView() { recyclerViewBuilder.setupRecyclerView(emailsRecyclerView, 20, false, true); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); emailsRecyclerView.setLayoutManager(linearLayoutManager); - emailsRecyclerViewAdapter = new SingleRecyclerViewAdapter(context, emailArrayList, value -> { - OneSignal.getUser().removeEmailSubscription(value); + emailsRecyclerViewAdapter = new SubscriptionRecyclerViewAdapter(context, emailArrayList, value -> { + String email = ((DummySubscription)value).getId(); + OneSignal.getUser().removeEmail(email); emailArrayList.remove(value); refreshEmailRecyclerView(); - toaster.makeCustomViewToast("Deleted email " + value, ToastType.SUCCESS); + toaster.makeCustomViewToast("Deleted email " + email, ToastType.SUCCESS); }); emailsRecyclerView.setAdapter(emailsRecyclerViewAdapter); } @@ -623,11 +675,12 @@ private void setupSMSRecyclerView() { recyclerViewBuilder.setupRecyclerView(smssRecyclerView, 20, false, true); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); smssRecyclerView.setLayoutManager(linearLayoutManager); - smssRecyclerViewAdapter = new SingleRecyclerViewAdapter(context, smsArrayList, value -> { - OneSignal.getUser().removeTrigger(value); + smssRecyclerViewAdapter = new SubscriptionRecyclerViewAdapter(context, smsArrayList, value -> { + String number = ((DummySubscription)value).getId(); + OneSignal.getUser().removeSms(number); smsArrayList.remove(value); refreshSMSRecyclerView(); - toaster.makeCustomViewToast("Deleted SMS " + value, ToastType.SUCCESS); + toaster.makeCustomViewToast("Deleted SMS " + number, ToastType.SUCCESS); }); smssRecyclerView.setAdapter(smssRecyclerViewAdapter); } @@ -650,10 +703,10 @@ private void setupOutcomeLayout() { public boolean onSuccess(OutcomeEvent outcomeEvent, String name, String value) { switch (outcomeEvent) { case OUTCOME: - OneSignal.getUser().sendOutcome(name); + OneSignal.getSession().addOutcome(name); break; case UNIQUE_OUTCOME: - OneSignal.getUser().sendUniqueOutcome(name); + OneSignal.getSession().addUniqueOutcome(name); break; case OUTCOME_WITH_VALUE: if (value.isEmpty()) { @@ -661,7 +714,7 @@ public boolean onSuccess(OutcomeEvent outcomeEvent, String name, String value) { return false; } - OneSignal.getUser().sendOutcomeWithValue(name, Float.parseFloat(value)); + OneSignal.getSession().addOutcomeWithValue(name, Float.parseFloat(value)); break; } @@ -683,11 +736,11 @@ private void setupTriggersLayout() { @Override public void onSuccess(Pair pair) { if (pair.second == null || pair.second.toString().isEmpty()) { - OneSignal.getUser().removeTrigger(pair.first); + OneSignal.getInAppMessages().removeTrigger(pair.first); triggerSet.remove(pair.first); toaster.makeCustomViewToast("Deleted trigger " + pair.first, ToastType.SUCCESS); } else { - OneSignal.getUser().setTrigger(pair.first, pair.second); + OneSignal.getInAppMessages().addTrigger(pair.first, pair.second.toString()); triggerSet.put(pair.first, pair.second); toaster.makeCustomViewToast("Added trigger " + pair.first, ToastType.SUCCESS); } @@ -707,7 +760,7 @@ private void setupTriggerRecyclerView() { LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); triggersRecyclerView.setLayoutManager(linearLayoutManager); triggerPairRecyclerViewAdapter = new PairRecyclerViewAdapter(context, triggerArrayList, key -> { - OneSignal.getUser().removeTrigger(key); + OneSignal.getInAppMessages().removeTrigger(key); triggerSet.remove(key); refreshTriggerRecyclerView(); @@ -751,7 +804,7 @@ private void setupLocationSharedSwitch() { locationSharedSwitch.setChecked(isLocationShared); locationSharedSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { SharedPreferenceUtil.cacheLocationSharedStatus(context, isChecked); - OneSignal.getLocation().setLocationShared(isChecked); + OneSignal.getLocation().setShared(isChecked); }); } @@ -770,34 +823,38 @@ private void setupPushNotificationLayout() { private void setupSubscriptionSwitch() { refreshSubscriptionState(); - subscriptionRelativeLayout.setOnClickListener(v -> { - boolean isSubscriptionEnabled = !subscriptionSwitch.isChecked(); - subscriptionSwitch.setChecked(isSubscriptionEnabled); + pushSubscriptionEnabledRelativeLayout.setOnClickListener(v -> { + boolean isSubscriptionEnabled = !pushSubscriptionEnabledSwitch.isChecked(); + pushSubscriptionEnabledSwitch.setChecked(isSubscriptionEnabled); }); // Add a listener to toggle the push notification enablement for the push subscription. - subscriptionSwitch.setOnClickListener(v -> { - IPushSubscription subscription = OneSignal.getUser().getSubscriptions().getPush(); - if (subscription != null) { - subscription.setEnabled(subscriptionSwitch.isChecked()); + pushSubscriptionEnabledSwitch.setOnClickListener(v -> { + IPushSubscription subscription = OneSignal.getUser().getPushSubscription(); + if(pushSubscriptionEnabledSwitch.isChecked()) { + subscription.optIn(); + } + else { + subscription.optOut(); } }); } private void setupPromptPushButton() { promptPushButton.setOnClickListener(v -> { - OneSignal.getNotifications().requestPermission(Continue.with(r -> refreshSubscriptionState())); + OneSignal.getUser().getPushSubscription().optIn(); }); } private void refreshSubscriptionState() { - boolean isPermissionEnabled = OneSignal.getNotifications().getPermissionStatus().getNotificationsEnabled(); - IPushSubscription pushSubscription = OneSignal.getUser().getSubscriptions().getPush(); - boolean isSubscribed = pushSubscription != null && pushSubscription.getEnabled(); + boolean isPermissionEnabled = OneSignal.getNotifications().getPermission(); + IPushSubscription pushSubscription = OneSignal.getUser().getPushSubscription(); - subscriptionRelativeLayout.setEnabled(isPermissionEnabled); - subscriptionSwitch.setEnabled(isPermissionEnabled); - subscriptionSwitch.setChecked(isSubscribed); + pushSubscriptionIdTextView.setText(pushSubscription.getId()); + promptPushBottonLayout.setVisibility(isPermissionEnabled ? View.GONE : View.VISIBLE); + pushSubscriptionEnabledRelativeLayout.setEnabled(isPermissionEnabled); + pushSubscriptionEnabledSwitch.setEnabled(isPermissionEnabled); + pushSubscriptionEnabledSwitch.setChecked(pushSubscription.getOptedIn()); } private void setupSendNotificationsLayout() { @@ -822,7 +879,7 @@ private void setupPauseInAppMessagesSwitch() { pauseInAppMessagesSwitch.setChecked(SharedPreferenceUtil.getCachedInAppMessagingPausedStatus(context)); pauseInAppMessagesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - OneSignal.getIam().setPaused(isChecked); + OneSignal.getInAppMessages().setPaused(isChecked); SharedPreferenceUtil.cacheInAppMessagingPausedStatus(context, isChecked); }); } @@ -851,7 +908,7 @@ private String getOneSignalAppId() { } private void togglePrivacyConsent(boolean hasConsent) { - OneSignal.setPrivacyConsent(hasConsent); + OneSignal.setConsentGiven(hasConsent); SharedPreferenceUtil.cacheUserPrivacyConsent(context, hasConsent); shouldScrollTop = hasConsent; @@ -871,34 +928,34 @@ private void refreshState() { appIdTextView.setText(getOneSignalAppId()); // aliases - aliasSet.clear(); - for (Map.Entry aliasEntry :OneSignal.getUser().getAliases().entrySet()) { - aliasSet.put(aliasEntry.getKey(), aliasEntry.getValue()); - } - refreshAliasRecyclerView(); +// aliasSet.clear(); +// for (Map.Entry aliasEntry :OneSignal.getUser().getAliases().entrySet()) { +// aliasSet.put(aliasEntry.getKey(), aliasEntry.getValue()); +// } +// refreshAliasRecyclerView(); // email subscriptions - emailArrayList.clear(); - List emailSubs = OneSignal.getUser().getSubscriptions().getEmails(); - for (IEmailSubscription emailSub: emailSubs) { - emailArrayList.add(emailSub.getEmail()); - } - refreshEmailRecyclerView(); +// emailArrayList.clear(); +// List emailSubs = OneSignal.getUser().getSubscriptions().getEmails(); +// for (IEmailSubscription emailSub: emailSubs) { +// emailArrayList.add(emailSub); +// } +// refreshEmailRecyclerView(); // sms subscriptions - smsArrayList.clear(); - List smsSubs = OneSignal.getUser().getSubscriptions().getSmss(); - for (ISmsSubscription smsSub: smsSubs) { - smsArrayList.add(smsSub.getNumber()); - } - refreshSMSRecyclerView(); +// smsArrayList.clear(); +// List smsSubs = OneSignal.getUser().getSubscriptions().getSmss(); +// for (ISmsSubscription smsSub: smsSubs) { +// smsArrayList.add(smsSub); +// } +// refreshSMSRecyclerView(); // tags - tagSet.clear(); - for (Map.Entry tagEntry :OneSignal.getUser().getTags().entrySet()) { - tagSet.put(tagEntry.getKey(), tagEntry.getValue()); - } - refreshTagRecyclerView(); +// tagSet.clear(); +// for (Map.Entry tagEntry :OneSignal.getUser().getTags().entrySet()) { +// tagSet.put(tagEntry.getKey(), tagEntry.getValue()); +// } +// refreshTagRecyclerView(); // triggers triggerSet.clear(); diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/SplashActivityViewModel.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/SplashActivityViewModel.java index 59cbd18a0d..c3116b9058 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/SplashActivityViewModel.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/SplashActivityViewModel.java @@ -8,8 +8,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import com.onesignal.core.OneSignal; -import com.onesignal.notification.IPermissionStateChanges; +import com.onesignal.OneSignal; import com.onesignal.sdktest.constant.Tag; import com.onesignal.sdktest.constant.Text; import com.onesignal.sdktest.util.IntentTo; @@ -64,15 +63,15 @@ public void networkDisconnected() { private void setupOneSignalSDK() { boolean privacyConsent = true; - OneSignal.setRequiresPrivacyConsent(privacyConsent); + OneSignal.setConsentRequired(privacyConsent); boolean isLocationShared = SharedPreferenceUtil.getCachedLocationSharedStatus(context); - OneSignal.getLocation().setLocationShared(isLocationShared); + OneSignal.getLocation().setShared(isLocationShared); boolean isInAppMessagingPaused = SharedPreferenceUtil.getCachedInAppMessagingPausedStatus(context); - OneSignal.getIam().setPaused(isInAppMessagingPaused); + OneSignal.getInAppMessages().setPaused(isInAppMessagingPaused); - Log.d(Tag.DEBUG, Text.PRIVACY_CONSENT_REQUIRED_SET + ": " + privacyConsent); + Log.d(Tag.LOG_TAG, Text.PRIVACY_CONSENT_REQUIRED_SET + ": " + privacyConsent); // boolean isEmailCached = attemptSignIn(new EmailUpdateCallback() { // @Override @@ -142,7 +141,7 @@ private void attemptEnterApplication() { } @Override - public void onPermissionChanged(@Nullable IPermissionStateChanges stateChanges) { + public void onNotificationPermissionChange(@Nullable boolean permission) { } } diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/NotificationServiceExtension.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/NotificationServiceExtension.java index 0f5711cb74..6f1c603da5 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/NotificationServiceExtension.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/NotificationServiceExtension.java @@ -1,35 +1,28 @@ package com.onesignal.sdktest.notification; -import android.content.Context; +import android.util.Log; -import com.onesignal.core.debug.LogLevel; -import com.onesignal.core.internal.logging.Logging; -import com.onesignal.notification.IActionButton; -import com.onesignal.notification.IMutableNotification; -import com.onesignal.notification.INotification; -import com.onesignal.notification.INotificationReceivedEvent; -import com.onesignal.notification.IRemoteNotificationReceivedHandler; +import com.onesignal.notifications.IActionButton; +import com.onesignal.notifications.IDisplayableMutableNotification; +import com.onesignal.notifications.INotificationReceivedEvent; +import com.onesignal.notifications.INotificationServiceExtension; import com.onesignal.sdktest.R; +import com.onesignal.sdktest.constant.Tag; -public class NotificationServiceExtension implements IRemoteNotificationReceivedHandler { +public class NotificationServiceExtension implements INotificationServiceExtension { @Override - public void remoteNotificationReceived(Context context, INotificationReceivedEvent notificationReceivedEvent) { - Logging.log(LogLevel.VERBOSE, "OSRemoteNotificationReceivedHandler fired!" + - " with OSNotificationReceived: " + notificationReceivedEvent.toString()); + public void onNotificationReceived(INotificationReceivedEvent event) { + Log.v(Tag.LOG_TAG, "IRemoteNotificationReceivedHandler fired" + " with INotificationReceivedEvent: " + event.toString()); - INotification notification = notificationReceivedEvent.getNotification(); + IDisplayableMutableNotification notification = event.getNotification(); if (notification.getActionButtons() != null) { for (IActionButton button : notification.getActionButtons()) { - Logging.log(LogLevel.VERBOSE, "ActionButton: " + button.toString()); + Log.v(Tag.LOG_TAG, "ActionButton: " + button.toString()); } } - IMutableNotification mutableNotification = notification.mutableCopy(); - mutableNotification.setExtender(builder -> builder.setColor(context.getResources().getColor(R.color.colorPrimary))); - - // If complete isn't call within a time period of 25 seconds, OneSignal internal logic will show the original notification - notificationReceivedEvent.complete(mutableNotification); + notification.setExtender(builder -> builder.setColor(event.getContext().getResources().getColor(R.color.colorPrimary))); } } diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java index 309dfe17c7..3d00056b88 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/notification/OneSignalNotificationSender.java @@ -1,28 +1,46 @@ package com.onesignal.sdktest.notification; +import android.os.Build; import android.util.Log; -import com.onesignal.core.Continue; -import com.onesignal.core.OneSignal; -import com.onesignal.core.user.subscriptions.IPushSubscription; +import com.onesignal.OneSignal; +import com.onesignal.user.subscriptions.IPushSubscription; import com.onesignal.sdktest.constant.Tag; import com.onesignal.sdktest.type.Notification; -import org.json.JSONException; import org.json.JSONObject; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Scanner; + public class OneSignalNotificationSender { + public static void setAppId(String appId) { + _appId = appId; + } + private static String _appId = ""; + + /** + * Send a notification to this device through the OneSignal Platform. Note this form of the + * API should not be used in a production setting as it is not safe. Rather, the device should + * make an API call to it's own backend, which should handle the API call to OneSignal (where it + * can safely provide the application API Key). + * + * @param notification The notification that is to be sent. + */ public static void sendDeviceNotification(final Notification notification) { new Thread(() -> { - IPushSubscription subscription = OneSignal.getUser().getSubscriptions().getPush(); + IPushSubscription subscription = OneSignal.getUser().getPushSubscription(); - if (subscription == null || !subscription.getEnabled()) + if (!subscription.getOptedIn()) return; int pos = notification.getTemplatePos(); try { - JSONObject notificationContent = new JSONObject("{'include_player_ids': ['" + subscription.getId() + "']," + + JSONObject notificationContent = new JSONObject("{'app_id': '" + _appId + "', 'include_player_ids': ['" + subscription.getId() + "']," + "'headings': {'en': '" + notification.getTitle(pos) + "'}," + "'contents': {'en': '" + notification.getMessage(pos) + "'}," + "'small_icon': '" + notification.getSmallIconRes() + "'," + @@ -34,20 +52,46 @@ public static void sendDeviceNotification(final Notification notification) { "'android_accent_color': 'FFE9444E'," + "'android_sound': 'nil'}"); - OneSignal.getNotifications().postNotification(notificationContent, Continue.with(r -> { - if(r.isSuccess()) - { - Log.d(Tag.DEBUG, "Success sending notification: " + r.getData().toString()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + HttpURLConnection con = (HttpURLConnection) new URL("https://onesignal.com/api/v1/notifications").openConnection(); + + con.setUseCaches(false); + con.setConnectTimeout(30000); + con.setReadTimeout(30000); + con.setRequestProperty("Accept", "application/vnd.onesignal.v1+json"); + con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + con.setRequestMethod("POST"); + con.setDoOutput(true); + con.setDoInput(true); + + byte[] outputBytes = notificationContent.toString().getBytes(StandardCharsets.UTF_8); + con.setFixedLengthStreamingMode(outputBytes.length); + con.getOutputStream().write(outputBytes); + + int httpResponse = con.getResponseCode(); + + if(httpResponse == HttpURLConnection.HTTP_ACCEPTED || httpResponse == HttpURLConnection.HTTP_OK) { + InputStream inputStream = con.getInputStream(); + Scanner scanner = new Scanner(inputStream, "UTF-8"); + String responseStr = ""; + if (scanner.useDelimiter("\\A").hasNext()) + responseStr = scanner.next(); + scanner.close(); + Log.d(Tag.LOG_TAG, "Success sending notification: " + responseStr); } - else if(r.getThrowable() != null) - { - Log.d(Tag.ERROR, "Failure sending notification: ", r.getThrowable()); + else { + InputStream inputStream = con.getErrorStream(); + Scanner scanner = new Scanner(inputStream, "UTF-8"); + String responseStr = ""; + if (scanner.useDelimiter("\\A").hasNext()) + responseStr = scanner.next(); + scanner.close(); + Log.d(Tag.LOG_TAG, "Failure sending notification: " + responseStr); } - })); - } catch (JSONException e) { + } + } catch (Exception e) { e.printStackTrace(); } }).start(); } - } diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Dialog.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Dialog.java index d14127885b..797d06372e 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Dialog.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Dialog.java @@ -167,7 +167,9 @@ public void onClick(final DialogInterface dialog, int which) { Object pairValue = pairStringValue; if (Util.isBoolean(pairStringValue)) { pairValue = Boolean.parseBoolean(pairStringValue.toLowerCase()); - } else if (Util.isNumeric(pairStringValue)) { + } else if (Util.isInteger(pairStringValue)) { + pairValue = Long.parseLong(pairStringValue); + } else if (Util.isFloat(pairStringValue)) { pairValue = Double.parseDouble(pairStringValue); } diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Util.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Util.java index 12ec1f5303..737c927a78 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Util.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/Util.java @@ -7,7 +7,16 @@ public static boolean isBoolean(String string) { return (string.equals("true") || string.equals("false")); } - public static boolean isNumeric(String string) { + public static boolean isInteger(String string) { + try { + Long.parseLong(string); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + public static boolean isFloat(String string) { try { Double.parseDouble(string); return true; diff --git a/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_rectangle.png b/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_rectangle.png index 4589027cd1..8277253388 100644 Binary files a/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_rectangle.png and b/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_rectangle.png differ diff --git a/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_square.png b/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_square.png index 1efa591d34..f8fa700c4e 100644 Binary files a/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_square.png and b/Examples/OneSignalDemo/app/src/main/res/drawable-nodpi/onesignal_square.png differ diff --git a/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml b/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml index c6c41662d1..d81e37486c 100644 --- a/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml +++ b/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml @@ -245,6 +245,8 @@ android:visibility="visible"/> + +