├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── art └── icon.png ├── cd-pipeline.yml ├── ci-pipeline.yml ├── docs ├── AndroidCustomization.md ├── FAQ.md ├── GettingStarted.md ├── LocalizedPushNotifications.md ├── NotificationActions.md ├── ReceivingNotifications.md └── iOSCustomization.md ├── nuget └── Plugin.nuspec ├── samples └── AzurePushNotificationSample │ ├── AzurePushNotificationSample.Android │ ├── Assets │ │ └── AboutAssets.txt │ ├── AzurePushNotificationSample.Android.csproj │ ├── MainActivity.cs │ ├── MainApplication.cs │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── AboutResources.txt │ │ ├── Resource.designer.cs │ │ ├── drawable-hdpi │ │ │ └── icon.png │ │ ├── drawable-xhdpi │ │ │ └── icon.png │ │ ├── drawable-xxhdpi │ │ │ └── icon.png │ │ ├── drawable │ │ │ ├── icon.png │ │ │ └── splash_screen.xml │ │ ├── layout │ │ │ ├── Main.axml │ │ │ ├── Tabbar.axml │ │ │ └── Toolbar.axml │ │ ├── mipmap-hdpi │ │ │ └── Icon.png │ │ ├── mipmap-mdpi │ │ │ └── Icon.png │ │ ├── mipmap-xhdpi │ │ │ └── Icon.png │ │ ├── mipmap-xxhdpi │ │ │ └── Icon.png │ │ ├── mipmap-xxxhdpi │ │ │ └── Icon.png │ │ └── values │ │ │ ├── Strings.xml │ │ │ ├── colors.xml │ │ │ └── styles.xml │ ├── SplashActivity.cs │ └── google-services.json │ ├── AzurePushNotificationSample.iOS │ ├── AppDelegate.cs │ ├── AzurePushNotificationSample.iOS.csproj │ ├── Entitlements.plist │ ├── Info.plist │ ├── Main.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── Default-568h@2x.png │ │ ├── Default-Portrait.png │ │ ├── Default-Portrait@2x.png │ │ ├── Default.png │ │ ├── Default@2x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-Small-40.png │ │ ├── Icon-Small-40@2x.png │ │ ├── Icon-Small-40@3x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x.png │ │ ├── Icon-Small@3x.png │ │ └── LaunchScreen.storyboard │ └── packages.config │ ├── AzurePushNotificationSample.sln │ └── AzurePushNotificationSample │ ├── App.xaml │ ├── App.xaml.cs │ ├── AzureConstants.cs │ ├── AzurePushNotificationSample.csproj │ ├── MainPage.xaml │ └── MainPage.xaml.cs └── src ├── AzurePushNotification.sln └── Plugin.AzurePushNotification ├── AzurePushNotificationManager.android.cs ├── AzurePushNotificationManager.apple.cs ├── CrossAzurePushNotification.shared.cs ├── DefaultPushNotificationHandler.android.cs ├── DefaultPushNotificationHandler.apple.cs ├── IAzurePushNotification.shared.cs ├── IPushNotificationHandler.shared.cs ├── NotificationActionType.shared.cs ├── NotificationCategoryType.shared.cs ├── NotificationPriority.shared.cs ├── NotificationResponse.shared.cs ├── NotificationUserCategory.shared.cs ├── PNMessagingService.android.cs ├── Plugin.AzurePushNotification.csproj ├── PushNotificationActionReceiver.android.cs └── PushNotificationDeletedReceiver.android.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 CrossGeeks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Azure Push Notification Plugin for Xamarin iOS and Android 2 | 3 | [![Build Status](https://dev.azure.com/CrossGeeks/Plugins/_apis/build/status/AzurePushNotification%20Plugin%20CI%20Pipeline?branchName=master)](https://dev.azure.com/CrossGeeks/Plugins/_build/latest?definitionId=10&branchName=master) 4 | 5 | Simple cross platform plugin for handling azure notification hub push notifications. 6 | 7 | ### Setup 8 | * Available on NuGet: http://www.nuget.org/packages/Plugin.AzurePushNotification [![NuGet](https://img.shields.io/nuget/v/Plugin.AzurePushNotification.svg?label=NuGet)](https://www.nuget.org/packages/Plugin.AzurePushNotification/) 9 | * Install into your .NETStandard project and Client projects. 10 | 11 | **Platform Support** 12 | 13 | |Platform|Version| 14 | | ------------------- | :------------------: | 15 | |Xamarin.iOS|iOS 8+| 16 | |Xamarin.Android|API 15+| 17 | 18 | ### API Usage 19 | 20 | Call **CrossAzurePushNotification.Current** from any project to gain access to APIs. 21 | 22 | ## Features 23 | 24 | - Receive push notifications 25 | - Tag registration 26 | - Support for push notification category actions 27 | - Customize push notifications 28 | - Localization 29 | 30 | 31 | ## Documentation 32 | 33 | Here you will find detailed documentation on setting up and using the Azure Push Notification Plugin for Xamarin 34 | 35 | * [Getting Started](docs/GettingStarted.md) 36 | * [Receiving Push Notifications](docs/ReceivingNotifications.md) 37 | * [Android Customization](docs/AndroidCustomization.md) 38 | * [iOS Customization](docs/iOSCustomization.md) 39 | * [Notification Category Actions](docs/NotificationActions.md) 40 | * [Notification Localization](docs/LocalizedPushNotifications.md) 41 | * [FAQ](docs/FAQ.md) 42 | 43 | #### Contributors 44 | 45 | * [Rendy Del Rosario](https://github.com/rdelrosario) 46 | * [Charlin Agramonte](https://github.com/char0394) 47 | * [Alberto Florenzan](https://github.com/aflorenzan) 48 | * [Angel Andres Mañon](https://github.com/AngelAndresM) 49 | * [Tymen Steur](https://github.com/TymenSteur) 50 | * [Mircea-Tiberiu MATEI](https://github.com/matei-tm) 51 | * [Pier-Lionel Sgard](https://github.com/plsgard) 52 | * [Peseur](https://github.com/Peseur) 53 | * [Zain Ahmad Khan](https://github.com/zainniazi) 54 | -------------------------------------------------------------------------------- /art/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/AzurePushNotificationPlugin/31fa9e9062fcae30881a86caa7753c6ab2777ca2/art/icon.png -------------------------------------------------------------------------------- /cd-pipeline.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | MONO_VERSION: 6_4_0 3 | NETCORE_VERSION: '3.0.x' 4 | 5 | # set the version numbering, this results in 1.0.1 for the first build incrementing that way. 6 | name: 2.1$(rev:.r) 7 | 8 | # Defines that a commit to the master branch should trigger this build 9 | trigger: 10 | - master 11 | 12 | # Defines that PRs against this branch should also trigger this build 13 | pr: 14 | - master 15 | 16 | # the machine and prerequisites to run this build on 17 | pool: 18 | vmImage: macOS-latest 19 | 20 | # The different steps in our build 21 | steps: 22 | 23 | - bash: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh $(MONO_VERSION) 24 | displayName: Switch to the latest Xamarin SDK 25 | 26 | - task: UseDotNet@2 27 | displayName: 'Use .Net Core sdk' 28 | inputs: 29 | version: $(NETCORE_VERSION) 30 | includePreviewVersions: false 31 | 32 | # build and pack a beta version of the NuGet package. Versioning is done through the name tag in this definition. 33 | - task: MSBuild@1 34 | displayName: 'Build & Pack beta build' 35 | inputs: 36 | solution: 'src/Plugin.AzurePushNotification/Plugin.AzurePushNotification.csproj' 37 | configuration: 'Release' 38 | msbuildArguments: '/restore /t:Build /p:ContinuousIntegrationBuild=true /p:Deterministic=false /t:Pack /p:PackageVersion=$(Build.BuildNumber)-beta /p:PackageOutputPath=$(build.artifactstagingdirectory)/beta /p:AssemblyFileVersion=$(Build.BuildNumber)' 39 | clean: true 40 | 41 | # build and pack a final version of the NuGet package. Versioning is done through the name tag in this definition. 42 | - task: MSBuild@1 43 | displayName: 'Build & Pack final build' 44 | inputs: 45 | solution: 'src/Plugin.AzurePushNotification/Plugin.AzurePushNotification.csproj' 46 | configuration: 'Release' 47 | msbuildArguments: '/restore /t:Build /p:ContinuousIntegrationBuild=true /p:Deterministic=false /t:Pack /p:PackageVersion=$(Build.BuildNumber) /p:PackageOutputPath=$(build.artifactstagingdirectory)/final /p:AssemblyFileVersion=$(Build.BuildNumber)' 48 | clean: true 49 | 50 | # copy all the nupkg files created to the artifact directory 51 | - task: CopyFiles@2 52 | displayName: 'Copy Files to: $(build.artifactstagingdirectory)' 53 | inputs: 54 | SourceFolder: '$(build.sourcesdirectory)' 55 | Contents: '**\*.nupkg' 56 | TargetFolder: '$(build.artifactstagingdirectory)' 57 | 58 | # publish the artifacts as results of the build 59 | - task: PublishBuildArtifacts@1 60 | displayName: 'Publish Artifact: drop' 61 | -------------------------------------------------------------------------------- /ci-pipeline.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | MONO_VERSION: 6_4_0 3 | NETCORE_VERSION: '3.0.x' 4 | XCODE_VERSION: 11.1 5 | 6 | # Starter pipeline 7 | # Start with a minimal pipeline that you can customize to build and deploy your code. 8 | # Add steps that build, run tests, deploy, and more: 9 | # https://aka.ms/yaml 10 | 11 | # Defines that a commit to the master branch should trigger this build 12 | trigger: 13 | - master 14 | 15 | # Defines that PRs against this branch should also trigger this build 16 | pr: 17 | - master 18 | 19 | # The type of machine this build should run on and what software should be on it 20 | pool: 21 | vmImage: macos-10.14 22 | 23 | # The different steps in our build 24 | steps: 25 | 26 | - bash: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh $(MONO_VERSION) 27 | displayName: Switch to the latest Xamarin SDK 28 | 29 | - bash: echo '##vso[task.setvariable variable=MD_APPLE_SDK_ROOT;]'/Applications/Xcode_$(XCODE_VERSION).app;sudo xcode-select --switch /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer 30 | displayName: Switch to the latest Xcode 31 | 32 | - task: UseDotNet@2 33 | displayName: 'Use .Net Core sdk' 34 | inputs: 35 | version: $(NETCORE_VERSION) 36 | includePreviewVersions: false 37 | 38 | - task: MSBuild@1 39 | displayName: 'Build solution' 40 | inputs: 41 | solution: 'src/**/*.sln' 42 | msbuildArguments: '/restore /t:Build /p:ContinuousIntegrationBuild=true /p:Deterministic=false /p:PackageOutputPath=$(build.artifactstagingdirectory)' 43 | clean: true 44 | -------------------------------------------------------------------------------- /docs/AndroidCustomization.md: -------------------------------------------------------------------------------- 1 | ## Android Specific Customization 2 | 3 | You can set the activity to be launched when you tap on the notification on Android project by setting **AzurePushNotificationManager.NotificationActivityType** 4 | 5 | Usage sample: 6 | 7 | ```csharp 8 | AzurePushNotificationManager.NotificationActivityType = typeof(MainActivity); 9 | ``` 10 | 11 | **Note: Uses application main launcher activity if the above is not set.** 12 | 13 | You can also set the flags for launching this activity with **AzurePushNotificationManager.NotificationActivityFlags** by default is set to: 14 | 15 | ```csharp 16 | AzurePushNotificationManager.NotificationActivityFlags = ActivityFlags.ClearTop | ActivityFlags.SingleTop 17 | ``` 18 | 19 | ### Static customization properties 20 | 21 | If plugin is not initialized with a push handler on Android by default the plugin uses the default push notification handler to create the notification ui & actions support when sending **Data messages**. 22 | 23 | By using the default push notification handler. There are a few things you can configure in Android project using the following static properties of **AzurePushNotificationManager** class: 24 | 25 | ```csharp 26 | 27 | //Sets the key associated with the value will be look for in the notification payload to be used to show the title for the notification 28 | public static string NotificationContentTitleKey { get; set; } 29 | 30 | //Sets the key associated with the value will look for in the notification payload to be used to show the text for the notification 31 | public static string NotificationContentTextKey { get; set; } 32 | 33 | //Sets the resource id for the icon will be used for the notification 34 | public static int IconResource { get; set; } 35 | 36 | //Sets the sound uri will be used for the notification 37 | public static Android.Net.Uri SoundUri { get; set; } 38 | 39 | //Sets the color will be used for the notification 40 | public static Color? Color { get; set; } 41 | 42 | //Sets the default notification channel id for Android O 43 | public static string DefaultNotificationChannelId { get; set; } = "PushNotificationChannel"; 44 | 45 | //Sets the default notification channel name for Android O 46 | public static string DefaultNotificationChannelName { get; set; } = "General"; 47 | 48 | ``` 49 | 50 | If **AzurePushNotificationManager.IconResource** not set will use default application icon. 51 | 52 | If **AzurePushNotificationManager.SoundUri** not set will use the default notification ringtone. 53 | 54 | If **NotificationContentTitleKey** not set will look for **title** key value in the notification payload to set the title. If no title key present will use the application name as the notification title. 55 | 56 | If **NotificationContentTextKey** not set will look for one of the following keys value in the notification payload using the priority order shown below to set the message for the notification: 57 | 58 | 1. **alert** 59 | 2. **body** 60 | 3. **message** 61 | 4. **subtitle** 62 | 5. **text** 63 | 6. **title** 64 | 65 | Once one of the above keys is found on the notification data message payload will show it's value as the notification message. 66 | 67 | 68 | ### Payload Keys 69 | 70 | There are also some keys you can set on the payload: 71 | 72 | * **id** : Sets the notification id 73 | * **tag** : Sets the notification tag 74 | * **priority** : Sets the notification priority 75 | * **sound** : Sets the notification sound 76 | * **icon** : Sets the notification icon 77 | * **large_icon** : Sets the notification large icon 78 | * **click_action** : Sets name for the notification action 79 | * **channel_id** : Sets id for the notification channel that will be used when notification is delivered 80 | 81 | If **sound** or **icon** keys present have priority over the **AzurePushNotificationManager.SoundUri** and **AzurePushNotificationManager.IconResource** static customization properties mentioned above. 82 | 83 | ##### Notification Id 84 | 85 | * **id** key is set as the notification id if present (integer value). 86 | 87 | 88 | Payload sample with id 89 | 90 | ```json 91 | { 92 | "data" : { 93 | "title": "hello", 94 | "body": "world", 95 | "id": 1 96 | } 97 | } 98 | ``` 99 | 100 | ##### Notification Tag 101 | 102 | * **tag** key is set as the notification tag if present. 103 | 104 | Payload sample with id and tag 105 | 106 | ```json 107 | { 108 | "data" : { 109 | "title": "hello", 110 | "body": "world", 111 | "id": 1, 112 | "tag" : "msg" 113 | 114 | } 115 | } 116 | 117 | 118 | ``` 119 | ##### Notification without UI 120 | 121 | * If you send a key called **silent** with value true it won't display a notification. 122 | 123 | Silent notification payload sample 124 | 125 | ```json 126 | { 127 | "data" : { 128 | "title": "hello", 129 | "body": "world", 130 | "silent":"true" 131 | } 132 | } 133 | ``` 134 | 135 | * For notification with actions will look for **click_action** key value as the match. More information here: [Notification Actions](NotificationActions.md) 136 | 137 | 138 | ##### Notification Priority 139 | 140 | * Depending on the value of **priority** key in your data payload. It will set the notification priority. Posible values are: "max", "high","default","low","min". 141 | 142 | The behaviour for these values: 143 | 144 | **MAX** - Use for critical and urgent notifications that alert the user to a condition that is time-critical or needs to be resolved before they can continue with a particular task. 145 | 146 | **HIGH** - Use primarily for important communication, such as message or chat events with content that is particularly interesting for the user. High-priority notifications trigger the heads-up notification display. 147 | 148 | **DEFAULT** - Use for all notifications that don't fall into any of the other priorities described here and if the application does not prioritize its own notifications 149 | 150 | **LOW** - Use for notifications that you want the user to be informed about, but that are less urgent. Low-priority notifications tend to show up at the bottom of the list, which makes them a good choice for things like public or undirected social updates: The user has asked to be notified about them, but these notifications should never take precedence over urgent or direct communication. 151 | 152 | **MIN** - Use for contextual or background information such as weather information or contextual location information. Minimum-priority notifications do not appear in the status bar. The user discovers them on expanding the notification shade. 153 | 154 | If no priority is set then "priority" is default. 155 | 156 | For heads-up notification send inside your payload data key "priority" : "high" within your other keys: 157 | 158 | Sample payload with priority 159 | 160 | ```json 161 | { 162 | "data" : { 163 | "title": "hello", 164 | "body": "world", 165 | "priority":"high" 166 | } 167 | } 168 | ``` 169 | ##### Notification Sound 170 | 171 | * You can send sound by using **sound** key, a sound with the value set should be in your *Resources/raw* folder. 172 | 173 | Payload sample with sound 174 | ```json 175 | { 176 | "data" : { 177 | "title": "hello", 178 | "body": "world", 179 | "priority":"high", 180 | "sound":"test" 181 | } 182 | } 183 | ``` 184 | If sound not set will set the **AzurePushNotificationManager.SoundUri** value if not set either will use the default notification ringtone. 185 | 186 | ##### Notification Icon 187 | 188 | * You can send the icon to be displayed on the notification by using **icon** key, an icon with the value set should be in your *Resources/drawable* folder. 189 | 190 | Payload sample with icon 191 | 192 | ```json 193 | { 194 | "data" : { 195 | "title": "hello", 196 | "body": "world", 197 | "priority":"high", 198 | "icon":"test" 199 | } 200 | } 201 | ``` 202 | 203 | Payload sample with icon and sound 204 | 205 | ```json 206 | { 207 | "data" : { 208 | "title": "hello", 209 | "body": "world", 210 | "priority":"high", 211 | "icon":"test", 212 | "sound":"test" 213 | } 214 | } 215 | ``` 216 | 217 | If icon not set will set the **AzurePushNotificationManager.IconResource** value if not set either will use the default application icon. 218 | 219 | 220 | ##### Notification Large Icon 221 | 222 | * You can send the large_icon to be displayed on the notification by using **large_icon** key, an icon with the value set should be in your *Resources/drawable* folder. 223 | 224 | Payload sample with large icon 225 | 226 | ```json 227 | { 228 | "data" : { 229 | "title": "hello", 230 | "body": "world", 231 | "priority":"high", 232 | "large_icon":"test" 233 | } 234 | } 235 | ``` 236 | 237 | Payload sample with large icon and sound 238 | 239 | ```json 240 | { 241 | "data" : { 242 | "title": "hello", 243 | "body": "world", 244 | "priority":"high", 245 | "large_icon":"test", 246 | "sound":"test" 247 | } 248 | } 249 | ``` 250 | 251 | If large icon not set will set the **AzurePushNotificationManager.LargeIconResource** value. 252 | 253 | 254 | ##### Notification Actions 255 | 256 | * For notification with actions will look for **click_action** key value as the match. More information here: [Notification Actions](NotificationActions.md) 257 | 258 | ##### Notification Channel Id 259 | 260 | * **channel_id** key is set as the notification channel id if present will use that specified notification channel for this notification. 261 | 262 | Payload sample with id and tag 263 | 264 | ```json 265 | { 266 | "data" : { 267 | "title": "hello", 268 | "body": "firebase", 269 | "channel_id" : "PushNotificationChannel" 270 | 271 | } 272 | } 273 | ``` 274 | 275 | <= Back to [Table of Contents](../README.md) 276 | 277 | -------------------------------------------------------------------------------- /docs/FAQ.md: -------------------------------------------------------------------------------- 1 | ## FAQ 2 | 3 | ### Android 4 | 5 | 1. Getting java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process {your_package_name}. 6 | 7 | **Solution 1:** 8 | 9 | Make sure the google-services.json has the GoogleServicesJson build action 10 | 11 | **Solution 2:** 12 | 13 | Make sure your firebase android app package name is the same package name on your Android project. 14 | 15 | 2. Android initialization should be done on and Android Application class to be able to handle received notifications when application is closed. Since no activity exist when application is closed. 16 | 17 | 3. You won't receive any push notifications if application is stopped while debugging, should reopen and close again for notifications to work when app closed. This is due to the application being on an unstable state when stopped while debugging. 18 | 19 | 4. On some phones android background services might be blocked by some application. This is the case of ASUS Zenfone 3 that has an Auto-start manager, which disables background services by default. You need to make sure that your push notification service is not being blocked by some application like this one, since you won't receive push notifications when app is closed if so. 20 | 21 | 5. Must compile against 26+ as plugin is using API 26 specific things. Here is a great breakdown: http://redth.codes/such-android-api-levels-much-confuse-wow/ (Android project must be compiled using 8.0+ target framework) 22 | 23 | 6. The package name of your Android aplication must start with lower case or you will get the build error: Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED 24 | 25 | 7. Make sure you have updated your Android SDK Manager libraries: 26 | 27 | ![image](https://cloud.githubusercontent.com/assets/2547751/6440604/1b0afb64-c0b5-11e4-93b8-c496e2bfa588.png) 28 | 29 | 9. Error 1589 NotificationService Not posting notification without small icon
30 | It happen when the message is received, but the notification isn't displayed. If you got this error, it mean you need to tell which one is your app icon on Android Project Properties > Android Manifest > application Icon or in the AndroidManifext.xml file and put android:icon="@drawable/{replace with your icon file name}" in the 31 | 32 | 33 | ... 34 | 35 | -------------------------------------------------------------------------------- /docs/GettingStarted.md: -------------------------------------------------------------------------------- 1 | ## Starting with Android 2 | 3 | ### Android Configuration 4 | 5 | First, make sure you setup everthing on Firebase portal and Azure portal. 6 | 7 | Also add this permission: 8 | 9 | ```xml 10 | 11 | ``` 12 | 13 | Add google-services.json to Android project. Make sure build action is GoogleServicesJson 14 | 15 | ![ADD JSON](https://github.com/CrossGeeks/FirebasePushNotificationPlugin/blob/master/images/android-googleservices-json.png?raw=true) 16 | 17 | Must compile against 26+ as plugin is using API 26 specific things. Here is a great breakdown: http://redth.codes/such-android-api-levels-much-confuse-wow/ (Android project must be compiled using 8.0+ target framework) 18 | 19 | ### Android Initialization 20 | 21 | You should initialize the plugin on an Android Application class if you don't have one on your project, should create an application class. Then call **AzurePushNotificationManager.Initialize** method on OnCreate. 22 | 23 | There are 3 overrides to **AzurePushNotificationManager.Initialize**: 24 | 25 | - **AzurePushNotificationManager.Initialize(Context context,string notificationHubConnectionString,string notificationHubPathName, bool resetToken,bool autoRegistration)** : Default method to initialize plugin without supporting any user notification categories. Uses a DefaultPushHandler to provide the ui for the notification. 26 | 27 | - **AzurePushNotificationManager.Initialize(Context context,string notificationHubConnectionString,string notificationHubPathName, NotificationUserCategory[] categories, bool resetToken,bool autoRegistration)** : Initializes plugin using user notification categories. Uses a DefaultPushHandler to provide the ui for the notification supporting buttons based on the action_click send on the notification 28 | 29 | - **AzurePushNotificationManager.Initialize(Context context,string notificationHubConnectionString,string notificationHubPathName,IPushNotificationHandler pushHandler, bool resetToken,bool autoRegistration)** : Initializes the plugin using a custom push notification handler to provide custom ui and behaviour notifications receipt and opening. 30 | 31 | **Important: While debugging set resetToken parameter to true.** 32 | 33 | Example of initialization: 34 | 35 | ```csharp 36 | 37 | [Application] 38 | public class MainApplication : Application 39 | { 40 | public MainApplication(IntPtr handle, JniHandleOwnership transer) :base(handle, transer) 41 | { 42 | } 43 | 44 | public override void OnCreate() 45 | { 46 | base.OnCreate(); 47 | 48 | //Set the default notification channel for your app when running Android Oreo 49 | if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O) 50 | { 51 | //Change for your default notification channel id here 52 | AzurePushNotificationManager.DefaultNotificationChannelId = "DefaultChannel"; 53 | 54 | //Change for your default notification channel name here 55 | AzurePushNotificationManager.DefaultNotificationChannelName = "General"; 56 | } 57 | 58 | //If debug you should reset the token each time. 59 | #if DEBUG 60 | AzurePushNotificationManager.Initialize(this,"Notification Hub Connection String","Notification Hub Path Name",true); 61 | #else 62 | AzurePushNotificationManager.Initialize(this,"Notification Hub Connection String","Notification Hub Path Name",false); 63 | #endif 64 | 65 | //Handle notification when app is closed here 66 | CrossAzurePushNotification.Current.OnNotificationReceived += (s,p) => 67 | { 68 | 69 | 70 | }; 71 | 72 | 73 | } 74 | } 75 | 76 | ``` 77 | 78 | By default the plugin launches the main launcher activity when you tap at a notification, but you can change this behaviour by setting the type of the activity you want to be launch on **AzurePushNotificationManager.NotificationActivityType** 79 | 80 | If you set **AzurePushNotificationManager.NotificationActivityType** then put the following call on the **OnCreate** of activity of the type set. If not set then put it on your main launcher activity **OnCreate** method (On the Activity you got MainLauncher= true set) 81 | 82 | ```csharp 83 | protected override void OnCreate(Bundle bundle) 84 | { 85 | base.OnCreate(bundle); 86 | 87 | //Other initialization stuff 88 | 89 | AzurePushNotificationManager.ProcessIntent(this,Intent); 90 | } 91 | 92 | ``` 93 | 94 | **Note: When using Xamarin Forms do it just after LoadApplication call.** 95 | 96 | By default the plugin launches the activity where **ProcessIntent** method is called when you tap at a notification, but you can change this behaviour by setting the type of the activity you want to be launch on **AzurePushNotificationManager.NotificationActivityType** 97 | 98 | You can change this behaviour by setting **AzurePushNotificationManager.NotificationActivityFlags**. 99 | 100 | If you set **AzurePushNotificationManager.NotificationActivityFlags** to ActivityFlags.SingleTop or using default plugin behaviour then make this call on **OnNewIntent** method of the same activity on the previous step. 101 | 102 | ```csharp 103 | protected override void OnNewIntent(Intent intent) 104 | { 105 | base.OnNewIntent(intent); 106 | AzurePushNotificationManager.ProcessIntent(this,intent); 107 | } 108 | ``` 109 | 110 | More information on **AzurePushNotificationManager.NotificationActivityType** and **AzurePushNotificationManager.NotificationActivityFlags** and other android customizations here: 111 | 112 | [Android Customization](../docs/AndroidCustomization.md) 113 | 114 | ## Starting with iOS 115 | 116 | First, make sure you set everything on Apple Developer Portal and Azure portal. You can follow this guide: 117 | 118 | https://docs.microsoft.com/en-us/azure/notification-hubs/notification-hubs-push-notification-http2-token-authentification 119 | 120 | ### iOS Configuration 121 | 122 | On Info.plist enable remote notification background mode 123 | 124 | ![Remote notifications](https://github.com/CrossGeeks/FirebasePushNotificationPlugin/blob/master/images/iOS-enable-remote-notifications.png?raw=true) 125 | 126 | ### iOS Initialization 127 | 128 | There are 3 overrides to **AzurePushNotificationManager.Initialize**: 129 | 130 | - **AzurePushNotificationManager.Initialize(string notificationHubConnectionString,string notificationHubPathName, NSDictionary options,bool autoRegistration,bool autoRegistration, bool enableDelayedResponse)** : Default method to initialize plugin without supporting any user notification categories. Auto registers for push notifications if second parameter is true. 131 | 132 | - **AzurePushNotificationManager.Initialize(string notificationHubConnectionString,string notificationHubPathName,NSDictionary options, NotificationUserCategory[] categories,bool autoRegistration, bool enableDelayedResponse)** : Initializes plugin using user notification categories to support iOS notification actions. 133 | 134 | - **AzurePushNotificationManager.Initialize(string notificationHubConnectionString,string notificationHubPathName,NSDictionary options,IPushNotificationHandler pushHandler,bool autoRegistration, bool enableDelayedResponse)** : Initializes the plugin using a custom push notification handler to provide native feedback of notifications event on the native platform. 135 | 136 | 137 | Call **AzurePushNotificationManager.Initialize** on AppDelegate FinishedLaunching 138 | ```csharp 139 | 140 | AzurePushNotificationManager.Initialize("Notification Hub Connection String","Notification Hub Path Name",options,true); 141 | 142 | ``` 143 | **Note: When using Xamarin Forms do it just after LoadApplication call.** 144 | 145 | Also should override these methods and make the following calls: 146 | ```csharp 147 | public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) 148 | { 149 | AzurePushNotificationManager.DidRegisterRemoteNotifications(deviceToken); 150 | } 151 | 152 | public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) 153 | { 154 | AzurePushNotificationManager.RemoteNotificationRegistrationFailed(error); 155 | 156 | } 157 | // To receive notifications in foregroung on iOS 9 and below. 158 | // To receive notifications in background in any iOS version 159 | public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action completionHandler) 160 | { 161 | 162 | AzurePushNotificationManager.DidReceiveMessage(userInfo); 163 | } 164 | 165 | 166 | ``` 167 | 168 | 169 | ## Using Push Notification APIs 170 | It is drop dead simple to gain access to the PushNotification APIs in any project. All you need to do is get a reference to the current instance of IPushNotification via `CrossPushNotification.Current`: 171 | 172 | Register tags 173 | 174 | ```csharp 175 | /// 176 | /// Registers tags in Azure Notification hub 177 | /// 178 | await CrossAzurePushNotification.Current.RegisterAsync(new string[]{"crossgeeks","general"}); 179 | ``` 180 | 181 | Note: The method above cleans all previous registered tags when called. So it kind of replaces the tags each time you call it. 182 | 183 | Unregister tags 184 | 185 | ```csharp 186 | /// 187 | /// Unregister all tags in Azure Notification hub 188 | /// 189 | await CrossAzurePushNotification.Current.UnregisterAsync(); 190 | ``` 191 | 192 | ### On Demand Registration 193 | 194 | When plugin initializes by default auto request permission the device for push notifications. If needed you can do on demand permisssion registration by turning off auto registration when initializing the plugin. 195 | 196 | Use the following method for on demand permission registration: 197 | 198 | ```csharp 199 | CrossAzurePushNotification.Current.RegisterForPushNotifications(); 200 | ``` 201 | 202 | 203 | ### Events 204 | 205 | Once token is registered/refreshed you will get it on **OnTokenRefresh** event. 206 | 207 | 208 | ```csharp 209 | /// 210 | /// Event triggered when token is refreshed 211 | /// 212 | event AzurePushNotificationTokenEventHandler OnTokenRefresh; 213 | ``` 214 | 215 | Note: Don't call **RegisterAsync** in the event above because it is called automatically each time the token changes 216 | 217 | ```csharp 218 | /// 219 | /// Event triggered when a notification is received 220 | /// 221 | event AzurePushNotificationResponseEventHandler OnNotificationReceived; 222 | ``` 223 | 224 | 225 | ```csharp 226 | /// 227 | /// Event triggered when a notification is opened 228 | /// 229 | event AzurePushNotificationResponseEventHandler OnNotificationOpened; 230 | ``` 231 | 232 | ```csharp 233 | /// 234 | /// Event triggered when a notification is deleted (Android Only) 235 | /// 236 | event AzurePushNotificationDataEventHandler OnNotificationDeleted; 237 | ``` 238 | 239 | ```csharp 240 | /// 241 | /// Event triggered when there's an error 242 | /// 243 | event AzurePushNotificationErrorEventHandler OnNotificationError; 244 | ``` 245 | 246 | Token event usage sample: 247 | ```csharp 248 | 249 | CrossAzurePushNotification.Current.OnTokenRefresh += (s,p) => 250 | { 251 | System.Diagnostics.Debug.WriteLine($"TOKEN : {p.Token}"); 252 | }; 253 | 254 | ``` 255 | 256 | Push message received event usage sample: 257 | ```csharp 258 | 259 | CrossAzurePushNotification.Current.OnNotificationReceived += (s,p) => 260 | { 261 | 262 | System.Diagnostics.Debug.WriteLine("Received"); 263 | 264 | }; 265 | 266 | ``` 267 | 268 | Push message opened event usage sample: 269 | ```csharp 270 | 271 | CrossAzurePushNotification.Current.OnNotificationOpened += (s,p) => 272 | { 273 | System.Diagnostics.Debug.WriteLine("Opened"); 274 | foreach(var data in p.Data) 275 | { 276 | System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}"); 277 | } 278 | 279 | if(!string.IsNullOrEmpty(p.Identifier)) 280 | { 281 | System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}"); 282 | } 283 | 284 | }; 285 | ``` 286 | Push message deleted event usage sample: (Android Only) 287 | ```csharp 288 | 289 | CrossAzurePushNotification.Current.OnNotificationDeleted+= (s,p) => 290 | { 291 | 292 | System.Diagnostics.Debug.WriteLine("Deleted"); 293 | 294 | }; 295 | 296 | ``` 297 | 298 | Plugin by default provides some notification customization features for each platform. Check out the [Android Customization](AndroidCustomization.md) and [iOS Customization](iOSCustomization.md) sections. 299 | 300 | <= Back to [Table of Contents](../README.md) 301 | -------------------------------------------------------------------------------- /docs/LocalizedPushNotifications.md: -------------------------------------------------------------------------------- 1 | ## Localized Push Notifications 2 | 3 | When having an application available in multiple countries is very common to have multilingual support to provide the best user experience posible. That's why we provided this guide in case you need support for localization on your push notifications. 4 | 5 | ### iOS - Push Notifications Localization 6 | 7 | On iOS push notifications are associated with iOS default platform localization. 8 | 9 | > If you use a consistent set of messages for your notifications, you can store localized versions of the message text in your app bundle and use the loc-key and loc-args keys in your payload to specify which message to display. The loc-key and loc-args keys define the message content of the notification. When present, the local system searches the app’s Localizable.strings files for a key string matching the value in loc-key. It then uses the corresponding value from the strings file as the basis for the message text, replacing any placeholder values with the strings specified by the loc-args key. (You can also specify a title string for the notification using the title-loc-key and title-loc-args keys.). [Apple documentation](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW9) 10 | 11 | So you can use iOS default platform localization by following this brief guide: 12 | 13 | On the iOS project you have to add **Localizable.strings** (Build action for these files should be Bundle Resource) for each language you need to support. This is the file where you will define your keys and values based on the language. 14 | 15 | These files are organized by language, in specially named directories with an **.lproj** suffix. 16 | 17 | **Base.lproj** is the directory that contains resources for the default language. It is often located in the project root (but can also be placed in the Resources folder). 18 | 19 | **.lproj** directories are created for each supported language, usually in the Resources folder. 20 | 21 | Once you add this files your structure should look similar to this: 22 | 23 | ![image](https://user-images.githubusercontent.com/2547751/32307919-f2d3131e-bf37-11e7-8f14-041585071342.png) 24 | 25 | This is an example Base.lproj/Localizable.strings (default language) file: 26 | 27 | ``` 28 | "NOTIFICATION_TITLE" = "Hello World"; 29 | "NOTIFICATION_MESSAGE" = "This is a message"; 30 | ``` 31 | 32 | 33 | This is an example es.lproj/Localizable.strings (ie. Spanish) file: 34 | 35 | ``` 36 | "NOTIFICATION_TITLE" = "Hola Mundo"; 37 | "NOTIFICATION_MESSAGE" = "Esto es un mensaje"; 38 | ``` 39 | 40 | On the payload instead of using **title** and **message** keys, we will use **title-loc-key** to represent the key for our localized title and **loc-key** to represent the key for our localized message. 41 | 42 | Finally, when sending the payload would look like this: 43 | 44 | ```json 45 | { 46 | "aps" : { 47 | "alert" : { 48 | "title-loc-key" : "NOTIFICATION_TITLE", 49 | "loc-key" : "NOTIFICATION_MESSAGE" 50 | } 51 | } 52 | } 53 | ``` 54 | 55 | That works out just fine for a static message but if you have variable parameters in the content then you will need some extra keys on your payloads and define the value for your Localizable.strings differently. Let's say my payload have variable content on the title and message, then there are two additional keys we need to add **title-loc-args** (represents the variable parameters for the title) and **loc-args** (represents the variable parameters for the message). 56 | 57 | ```json 58 | { 59 | "aps" : { 60 | "alert" : { 61 | "title-loc-key" : "NOTIFICATION_TITLE", 62 | "loc-key" : "NOTIFICATION_MESSAGE", 63 | "title-loc-args" : ["Dominican Republic"], 64 | "loc-args" : ["Rendy"] 65 | } 66 | } 67 | } 68 | ``` 69 | Each of this two payload keys is a string array so you can have as many string arguments as you need. Here's how should **Localizable.strings** files look like when using arguments: 70 | 71 | This is an example Base.lproj/Localizable.strings (default language) file: 72 | 73 | ``` 74 | "NOTIFICATION_TITLE" = "Hello %@"; 75 | "NOTIFICATION_MESSAGE" = "This is a message for %@"; 76 | ``` 77 | 78 | 79 | This is an example es.lproj/Localizable.strings (ie. Spanish) file: 80 | 81 | ``` 82 | "NOTIFICATION_TITLE" = "Hola %@"; 83 | "NOTIFICATION_MESSAGE" = "Esto es un mensaje para %@"; 84 | ``` 85 | Each %@ represents a parameter or parameters if more than one. 86 | 87 | 88 | More information on iOS localization here: 89 | 90 | [Apple Remote Notifications Localization](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW9) 91 | 92 | [Xamarin iOS Localization](https://developer.xamarin.com/guides/ios/advanced_topics/localization_and_internationalization/) 93 | 94 | 95 | ### Android - Push Notifications Localization 96 | 97 | On Android the plugin has localization support by default using Android platform localization. Uses specific keys to be sent on the payload that will then be resolved with values on string files depending on the android language set to the device. 98 | 99 | First, you have to add a **strings.xml** (Build action for these files should be Android Resource) for each language you need to support. This is the file where you will define your keys and values based on the language. 100 | 101 | These files are organized by language, in specially named directories with an **values** and a language suffix (For example values-en, values-fr, values-es). Naming must conform specifications on [AlternativeResources](https://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources). 102 | 103 | **values**: without any suffix is the directory that contains resources for the default language. Placed in the Resources folder. 104 | 105 | **values-{language code}**: directories are created for each supported language, placed in the Resources folder. Examples : **values-ja**, **values-fr**, **values-es**. 106 | 107 | Notes: 108 | 109 | - If device set to a language that has a strings.xml file (ex. Resources/values-es/strings.xml) and have the requested key defined in this file then will use the value for this file. 110 | - If device set to a language that doesn't have strings.xml file then will fallback to default string.xml on **values** without suffix. 111 | - If device set to a language that has a strings.xml file (ex. Resources/values-es/strings.xml) but doesn't have a specific key requested then will fallback to default string.xml on **values** without suffix to look for this key/value. 112 | 113 | 114 | Example: 115 | 116 | Let's say we need to support 2 languages: English, Spanish. In this case, you could create two alternative strings.xml files, each stored in a locale-specific resource directory: 117 | 118 | 1. Resources/values/strings.xml (default file) 119 | 120 | ```xml 121 | Hello world 122 | This is a message 123 | ``` 124 | 2. Resources/values-es/strings.xml (Spanish strings file) 125 | 126 | ```xml 127 | Hola mundo 128 | Esto es un mensaje 129 | ``` 130 | On the payload instead of using **title** and **message** / **body** keys, we will use **title_loc_key** to represent the key for our localized title and **body_loc_key** to represent the key for our localized message. 131 | 132 | When sending the payload would look like this: 133 | 134 | ```json 135 | { 136 | "data": { 137 | "title_loc_key": "notification_title_string", 138 | "body_loc_key": "notification_message_string" 139 | }, 140 | "priority": "high", 141 | "registration_ids" : ["eoPr8fUIPns:APA91bEVYODiWaL9a9JidumLRcFjVrEC4iHY80mHSE1e-udmPB32RjMiYL2P2vWTIUgYCJYVOx9SGSN_R4Ksau3vFX4WvkDj4ZstxqmcBhM3K-NMrX8P6U0sdDEqDpr-lD_N5JWBLCoV"] 142 | } 143 | ``` 144 | 145 | When using parameters in the content you will need some extra keys on your payload and define the value for your strings.xml differently. Let's say the payload have variable content on the title and message, then there are two additional keys we need to add **title_loc_args** (represents the variable parameters for the title) and **body_loc_args** (represents the variable parameters for the message). 146 | 147 | ```json 148 | { 149 | "data": { 150 | "title_loc_key" : "notification_title_string", 151 | "body_loc_key" : "notification_message_string", 152 | "title_loc_args" : ["Dominican Republic"], 153 | "body_loc_args" : ["Rendy"] 154 | }, 155 | "priority": "high", 156 | "registration_ids" : ["eoPr8fUIPns:APA91bEVYODiWaL9a9JidumLRcFjVrEC4iHY80mHSE1e-udmPB32RjMiYL2P2vWTIUgYCJYVOx9SGSN_R4Ksau3vFX4WvkDj4ZstxqmcBhM3K-NMrX8P6U0sdDEqDpr-lD_N5JWBLCoV"] 157 | } 158 | ``` 159 | 160 | Each of this two payload keys is a string array so you can have as many string arguments as you need. 161 | 162 | Here's how should **strings.xml** files look like when using arguments: 163 | 164 | 1. Resources/values/strings.xml (default file) 165 | 166 | ```xml 167 | Hola %1$s 168 | Esto es un mensaje para %1$s 169 | ``` 170 | 171 | 2. Resources/values-es/strings.xml (Spansih strings file) 172 | 173 | ```xml 174 | Hello %1$s 175 | This is a message for %1$s 176 | ``` 177 | 178 | The format for parameter replacement is: %[parameter index]$[format type]. 179 | 180 | - Parameter index: Starts at 1. For example, if you have 2 parameters: %1 and %2. The order you place them in the resource string doesn't matter, only the order that you supply the parameters. 181 | - Format type: Most common types are : $s (string), $d (decimal integer), $f (floating point number) 182 | 183 | More information on string format for parameter replacing here: 184 | 185 | [Dynamic string](https://stackoverflow.com/questions/3656371/dynamic-string-using-string-xml) 186 | 187 | [Formatting Resource Strings](https://code.tutsplus.com/tutorials/android-sdk-quick-tip-formatting-resource-strings--mobile-1775) 188 | 189 | More information on localization here: 190 | 191 | [Android Localization](https://developer.android.com/guide/topics/resources/localization.html) 192 | 193 | <= Back to [Table of Contents](../README.md) 194 | 195 | -------------------------------------------------------------------------------- /docs/NotificationActions.md: -------------------------------------------------------------------------------- 1 | ## Notification Category Actions 2 | 3 | You can initialize the plugin with notification user categories to provide button options within the notification. Depending on the notification category received you can provide different button options. 4 | 5 | ### Notification User Category: 6 | 7 | Each notification user category can have it's own options 8 | 9 | ```csharp 10 | public class NotificationUserCategory 11 | { 12 | public string Category { get; } 13 | 14 | public List Actions { get; } 15 | 16 | public NotificationCategoryType Type { get; } 17 | 18 | public NotificationUserCategory(string category, List actions, NotificationCategoryType type = NotificationCategoryType.Default) 19 | { 20 | Category = category; 21 | Actions = actions; 22 | Type = type; 23 | } 24 | } 25 | ``` 26 | 27 | ```csharp 28 | //This just applies for iOS on Android is always set as default when used 29 | public enum NotificationCategoryType 30 | { 31 | Default, 32 | Custom, 33 | Dismiss 34 | } 35 | ``` 36 | 37 | ### Notification User Action: 38 | 39 | Each user action represents a button option of the notification user category 40 | 41 | ```csharp 42 | public class NotificationUserAction 43 | { 44 | public string Id { get; } // Action Identifier 45 | 46 | public string Title { get; } //Title to be displayed for the option 47 | 48 | public NotificationActionType Type { get; } //Determines the behaviour when action is executed 49 | 50 | public string Icon { get; } //Applies only for Android 51 | 52 | public NotificationUserAction(string id, string title, NotificationActionType type = NotificationActionType.Default, string icon = "") 53 | { 54 | Id = id; 55 | Title = title; 56 | Type = type; 57 | Icon = icon; 58 | } 59 | } 60 | ``` 61 | There are a few types of notification user actions which determines the behaviour of it when the button option is tapped: 62 | 63 | ```csharp 64 | public enum NotificationActionType 65 | { 66 | Default, 67 | AuthenticationRequired, //Only applies for iOS 68 | Foreground, 69 | Destructive //Only applies for iOS 70 | } 71 | ``` 72 | 73 | **Default** : When a button with this notification action type is tapped will handle the notification on background won't bring the application to foreground. Action will take place without launching the application. 74 | 75 | **Foreground** : When a button with this notification action type is tapped will bring the application to foreground and receive the notification once application is in foreground. 76 | 77 | **AuthenticationRequired** : If set the user needs to insert the unlock code to launch the action in background. This action is iOS specific will be ignored on Android. 78 | 79 | **Destructive** : Action button will have a red color. This action is iOS specific will be ignored on Android. 80 | 81 | ### Initialize using a User Category Notifications 82 | 83 | Android on **Application** class **OnCreate** method: 84 | 85 | ```csharp 86 | #if DEBUG 87 | AzurePushNotificationManager.Initialize(this, 88 | "Notification Hub Connection String", 89 | "Notification Hub Path Name", 90 | new NotificationUserCategory[] 91 | { 92 | new NotificationUserCategory("message",new List { 93 | new NotificationUserAction("Reply","Reply", NotificationActionType.Foreground), 94 | new NotificationUserAction("Forward","Forward", NotificationActionType.Foreground) 95 | 96 | }), 97 | new NotificationUserCategory("request",new List { 98 | new NotificationUserAction("Accept","Accept", NotificationActionType.Default, "check"), 99 | new NotificationUserAction("Reject","Reject", NotificationActionType.Default, "cancel") 100 | }) 101 | }, true); 102 | #else 103 | AzurePushNotificationManager.Initialize(this, 104 | "Notification Hub Connection String", 105 | "Notification Hub Path Name", 106 | new NotificationUserCategory[] 107 | { 108 | new NotificationUserCategory("message",new List { 109 | new NotificationUserAction("Reply","Reply", NotificationActionType.Foreground), 110 | new NotificationUserAction("Forward","Forward", NotificationActionType.Foreground) 111 | 112 | }), 113 | new NotificationUserCategory("request",new List { 114 | new NotificationUserAction("Accept","Accept", NotificationActionType.Default, "check"), 115 | new NotificationUserAction("Reject","Reject", NotificationActionType.Default, "cancel") 116 | }) 117 | }, false); 118 | #endif 119 | 120 | ``` 121 | 122 | iOS on **AppDelegate** FinishLaunching: 123 | 124 | ```csharp 125 | 126 | AzurePushNotificationManager.Initialize( 127 | "Notification Hub Connection String", 128 | "Notification Hub Path Name", 129 | options, 130 | new NotificationUserCategory[] 131 | { 132 | new NotificationUserCategory("message",new List { 133 | new NotificationUserAction("Reply","Reply",NotificationActionType.Foreground) 134 | }), 135 | new NotificationUserCategory("request",new List { 136 | new NotificationUserAction("Accept","Accept"), 137 | new NotificationUserAction("Reject","Reject",NotificationActionType.Destructive) 138 | }) 139 | }); 140 | 141 | ``` 142 | 143 | You will get the identifier of the action that was tapped on **OnNotificationOpened** event: 144 | 145 | ```csharp 146 | CrossAzurePushNotification.Current.OnNotificationOpened += (s,p) => 147 | { 148 | System.Diagnostics.Debug.WriteLine("Opened"); 149 | 150 | 151 | if(!string.IsNullOrEmpty(p.Identifier)) 152 | { 153 | System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}"); 154 | } 155 | 156 | foreach(var data in p.Data) 157 | { 158 | System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}"); 159 | } 160 | 161 | }; 162 | ``` 163 | 164 | On Android should use **click_action** key inside the data payload when sending notification with categories. The value for this key will be the category. 165 | 166 | Android Notification Sample Payload: 167 | ```json 168 | { 169 | "data": { 170 | "body" : "hello!", 171 | "title": "push", 172 | "click_action":"message" 173 | } 174 | } 175 | ``` 176 | 177 | On iOS should use **category** key inside the aps payload when sending notification with categories. The value for this key will be the category. 178 | 179 | iOS Notification Sample Payload: 180 | ```json 181 | { 182 | "aps" : { 183 | "category" : "message", 184 | "alert" : { 185 | "body" : "hello!" 186 | }, 187 | "badge" : 3 188 | } 189 | } 190 | ``` 191 | 192 | <= Back to [Table of Contents](../README.md) 193 | -------------------------------------------------------------------------------- /docs/ReceivingNotifications.md: -------------------------------------------------------------------------------- 1 | ## Android Firebase Push Notifications 2 | 3 | **Data messages** - Handled by the client app. These messages trigger the onMessageReceived() callback even if your app is in foreground/background/killed. When using this type of message you are the one providing the UI and handling when push notification is received on an Android device. 4 | 5 | ```json 6 | { 7 | "data": { 8 | "message" : "my_custom_value", 9 | "other_key" : true, 10 | "body":"test" 11 | } 12 | } 13 | ``` 14 | 15 | ## iOS APS Push Notifications 16 | 17 | https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW1 18 | 19 | ## Configuring a Silent Notification 20 | 21 | On iOS to get a silent notification you should send "content-available" : 1 inside the "aps" payload key. 22 | 23 | iOS Silent Payload Sample: 24 | ```json 25 | { 26 | "aps" : { 27 | "content-available" : 1 28 | }, 29 | "acme1" : "bar", 30 | "acme2" : 42 31 | } 32 | ``` 33 | 34 | On Android to get a silent notification you should send "silent" : true inside the "data" payload key. 35 | 36 | Android Silent Payload Sample: 37 | ```json 38 | { 39 | "data": { 40 | "message" : "my_custom_value", 41 | "other_key" : true, 42 | "body":"test", 43 | "silent" : true 44 | } 45 | } 46 | ``` 47 | 48 | ### Notification Events 49 | 50 | **OnNotificationReceived** 51 | ```csharp 52 | 53 | CrossAzurePushNotification.Current.OnNotificationReceived += (s,p) => 54 | { 55 | 56 | System.Diagnostics.Debug.WriteLine("Received"); 57 | 58 | }; 59 | 60 | ``` 61 | 62 | **OnNotificationOpened** 63 | ```csharp 64 | 65 | CrossAzurePushNotification.Current.OnNotificationOpened += (s,p) => 66 | { 67 | System.Diagnostics.Debug.WriteLine("Opened"); 68 | foreach(var data in p.Data) 69 | { 70 | System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}"); 71 | } 72 | 73 | if(!string.IsNullOrEmpty(p.Identifier)) 74 | { 75 | System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}"); 76 | } 77 | 78 | }; 79 | ``` 80 | 81 | **Note: This is the event were you will navigate to an specific page/activity/viewcontroller, if needed** 82 | 83 | **OnNotificationDeleted** (Android Only) 84 | ```csharp 85 | 86 | CrossAzurePushNotification.Current.OnNotificationDeleted += (s,p) => 87 | { 88 | 89 | System.Diagnostics.Debug.WriteLine("Deleted"); 90 | 91 | }; 92 | 93 | ``` 94 | 95 | ### Push Notification Handler 96 | 97 | A push notification handler is the way to provide ui push notification customization(on Android) and events feedback on native platforms by using **IPushNotificationHandler** interface. The plugin has a default push notification handler implementation and it's the one used by default. 98 | 99 | On most common use cases the default implementation might be enough so a custom implementation might not be needed at all. 100 | 101 | ```csharp 102 | public interface IPushNotificationHandler 103 | { 104 | //Method triggered when an error occurs 105 | void OnError(string error); 106 | //Method triggered when a notification is opened 107 | void OnOpened(NotificationResponse response); 108 | //Method triggered when a notification is received 109 | void OnReceived(IDictionary parameters); 110 | } 111 | ``` 112 | An example of a custom handler use is the [DefaultPushNotificationHandler](../src/Plugin.AzurePushNotification.Android/DefaultPushNotificationHandler.cs) which is the plugin default implementation to render the push notification ui when sending data messages and supporting notification actions on Android. 113 | 114 | ### Initialize using a PushHandler on Application class on Android and AppDelegate on iOS: 115 | 116 | Application class **OnCreate** on Android: 117 | 118 | ```csharp 119 | #if DEBUG 120 | AzurePushNotificationManager.Initialize(this,new CustomPushHandler(),true); 121 | #else 122 | AzurePushNotificationManager.Initialize(this,new CustomPushHandler(),false); 123 | #endif 124 | ``` 125 | To keep the default push notification handler functionality but make small adjustments or customizations to the notification. You can inherit from **DefaultPushNotificationHandler** and implement **OnBuildNotification** method which can be used to e.g. load an image from the web and set it as the 'LargeIcon' of a notification (notificationBuilder.SetLargeIcon) or other modifications to the resulting notification. 126 | 127 | **Note: If you use a custom push notification handler on Android, you will have full control on the notification arrival, so will be in charge of creating the notification ui for data messages when needed.** 128 | 129 | AppDelegate **FinishLaunching** on iOS: 130 | ```csharp 131 | AzurePushNotificationManager.Initialize(options,new CustomPushHandler()); 132 | ``` 133 | 134 | <= Back to [Table of Contents](../README.md) 135 | 136 | -------------------------------------------------------------------------------- /docs/iOSCustomization.md: -------------------------------------------------------------------------------- 1 | ### iOS Specifics Customization 2 | 3 | #### Notification Sound 4 | 5 | You can set the sound to be played when notification arrive by setting **sound** key on th payload. A sound file with the value set should be in your should be on *Library/Sounds*. 6 | 7 | Valid extensions are: aiff, wav, or caf file 8 | 9 | ```json 10 | { 11 | "aps" : { 12 | "alert" : { 13 | "title" : "hello", 14 | "body" : "world" 15 | }, 16 | "sound" : "test.aiff" 17 | } 18 | } 19 | ``` 20 | #### Notification on Foreground 21 | 22 | You can set UNNotificationPresentationOptions to get an alert, badge, sound when notification is received in foreground by setting static property **AzurePushNotificationManager.CurrentNotificationPresentationOption**. By default is set to UNNotificationPresentationOptions.None. 23 | 24 | ```csharp 25 | public enum UNNotificationPresentationOptions 26 | { 27 | Alert, //Display the notification as an alert, using the notification text. 28 | Badge, //Display the notification badge value in the application's badge. 29 | None, //No options are set. 30 | Sound //Play the notification sound. 31 | } 32 | ``` 33 | 34 | Usage sample on iOS Project: 35 | 36 | ```csharp 37 | //To set for alert 38 | AzurePushNotificationManager.CurrentNotificationPresentationOption = UNNotificationPresentationOptions.Alert; 39 | 40 | //You can also combine them 41 | AzurePushNotificationManager.CurrentNotificationPresentationOption = UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Badge; 42 | ``` 43 | 44 | A good place to do this would be on the **OnReceived** method of a custom push notification handler if it changes depending on the notification, if not you can just set it once on the AppDelegate **FinishLaunching**. 45 | 46 | <= Back to [Table of Contents](../README.md) 47 | 48 | -------------------------------------------------------------------------------- /nuget/Plugin.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Plugin.AzurePushNotification 5 | 1.1.0 6 | Azure Push Notification Plugin for Xamarin 7 | Rendy Del Rosario 8 | crossgeeks,rdelrosario 9 | https://raw.githubusercontent.com/CrossGeeks/AzurePushNotificationPlugin/master/LICENSE 10 | https://github.com/CrossGeeks/AzurePushNotificationPlugin 11 | https://github.com/CrossGeeks/AzurePushNotificationPlugin/blob/master/art/icon.png?raw=true 12 | false 13 | Receive and handle azure push notifications across Xamarin.iOS and Xamarin.Android 14 | Receive and handle push azure notifications across Xamarin.iOS and Xamarin.Android 15 | On demand registration, persistent token, better error handling and other minor fixes 16 | Copyright 2017 17 | iOS,Android,azure,notifications hub,push notifications,pcl,xamarin,plugins,xam.pcl,fcm,apn 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/AzurePushNotificationSample.Android.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {81FBC96F-CA10-4D03-B76A-C94E7A87F844} 7 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8 | Library 9 | AzurePushNotificationSample.Droid 10 | AzurePushNotificationSample.Android 11 | v9.0 12 | True 13 | Resources\Resource.designer.cs 14 | Resource 15 | Properties\AndroidManifest.xml 16 | Resources 17 | Assets 18 | 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug 26 | DEBUG; 27 | prompt 28 | 4 29 | None 30 | 31 | 32 | true 33 | pdbonly 34 | true 35 | bin\Release 36 | prompt 37 | 4 38 | true 39 | false 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 2.0.18 51 | 52 | 53 | 28.0.0.3 54 | 55 | 56 | 28.0.0.3 57 | 58 | 59 | 28.0.0.3 60 | 61 | 62 | 28.0.0.3 63 | 64 | 65 | 28.0.0.3 66 | 67 | 68 | 28.0.0.3 69 | 70 | 71 | 28.0.0.3 72 | 73 | 74 | 28.0.0.3 75 | 76 | 77 | 28.0.0.3 78 | 79 | 80 | 0.6.0 81 | 82 | 83 | 71.1740.0 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 71.1620.0 93 | 94 | 95 | 71.1601.0 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | Designer 124 | 125 | 126 | 127 | 128 | {D752C30D-5472-46DE-8256-E959BFF373FD} 129 | AzurePushNotificationSample 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Android.App; 4 | using Android.Content.PM; 5 | using Android.Runtime; 6 | using Android.Views; 7 | using Android.Widget; 8 | using Android.OS; 9 | using Plugin.AzurePushNotification; 10 | using Android.Content; 11 | 12 | namespace AzurePushNotificationSample.Droid 13 | { 14 | [Activity(Label = "AzurePushNotificationSample", Icon = "@drawable/icon", Theme = "@style/MainTheme", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 15 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 16 | { 17 | protected override void OnCreate(Bundle bundle) 18 | { 19 | TabLayoutResource = Resource.Layout.Tabbar; 20 | ToolbarResource = Resource.Layout.Toolbar; 21 | 22 | base.OnCreate(bundle); 23 | 24 | global::Xamarin.Forms.Forms.Init(this, bundle); 25 | LoadApplication(new App()); 26 | AzurePushNotificationManager.ProcessIntent(this,Intent); 27 | } 28 | 29 | protected override void OnNewIntent(Intent intent) 30 | { 31 | base.OnNewIntent(intent); 32 | AzurePushNotificationManager.ProcessIntent(this,intent); 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/MainApplication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Android.App; 7 | using Android.Content; 8 | using Android.OS; 9 | using Android.Runtime; 10 | using Android.Views; 11 | using Android.Widget; 12 | using Plugin.AzurePushNotification; 13 | using AzurePushNotificationSample; 14 | namespace AzurePushNotificationSample.Droid 15 | { 16 | [Application] 17 | public class MainApplication : Application 18 | { 19 | protected MainApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) 20 | { 21 | } 22 | 23 | public override void OnCreate() 24 | { 25 | base.OnCreate(); 26 | 27 | //Set the default notification channel for your app when running Android Oreo 28 | if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O) 29 | { 30 | //Change for your default notification channel id here 31 | AzurePushNotificationManager.DefaultNotificationChannelId = "DefaultChannel"; 32 | 33 | //Change for your default notification channel name here 34 | AzurePushNotificationManager.DefaultNotificationChannelName = "General"; 35 | } 36 | 37 | #if DEBUG 38 | AzurePushNotificationManager.Initialize(this, AzureConstants.ListenConnectionString, AzureConstants.NotificationHubName, true); 39 | #else 40 | AzurePushNotificationManager.Initialize(this, AzureConstants.ListenConnectionString, AzureConstants.NotificationHubName, false); 41 | #endif 42 | 43 | 44 | //Handle notification when app is closed here 45 | CrossAzurePushNotification.Current.OnNotificationReceived += (s, p) => 46 | { 47 | 48 | 49 | }; 50 | } 51 | 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("AzurePushNotificationSample.Android")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("AzurePushNotificationSample.Android")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | 32 | // Add some common permissions, these can be removed if not needed 33 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)] 34 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] 35 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. 51 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/AzurePushNotificationPlugin/31fa9e9062fcae30881a86caa7753c6ab2777ca2/samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/AzurePushNotificationPlugin/31fa9e9062fcae30881a86caa7753c6ab2777ca2/samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/AzurePushNotificationPlugin/31fa9e9062fcae30881a86caa7753c6ab2777ca2/samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrossGeeks/AzurePushNotificationPlugin/31fa9e9062fcae30881a86caa7753c6ab2777ca2/samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable/icon.png -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /samples/AzurePushNotificationSample/AzurePushNotificationSample.Android/Resources/layout/Main.axml: -------------------------------------------------------------------------------- 1 |  2 | 3 |