mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 18:08:26 +03:00
switch from GCM to FCM
This commit is contained in:
parent
2b4ffaa357
commit
582e6ee322
12 changed files with 4875 additions and 4406 deletions
|
@ -81,6 +81,8 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AutofillActivity.cs" />
|
<Compile Include="AutofillActivity.cs" />
|
||||||
<Compile Include="AutofillCredentials.cs" />
|
<Compile Include="AutofillCredentials.cs" />
|
||||||
|
<Compile Include="FirebaseInstanceIdService.cs" />
|
||||||
|
<Compile Include="FirebaseMessagingService.cs" />
|
||||||
<Compile Include="Autofill\Field.cs" />
|
<Compile Include="Autofill\Field.cs" />
|
||||||
<Compile Include="Autofill\FieldCollection.cs" />
|
<Compile Include="Autofill\FieldCollection.cs" />
|
||||||
<Compile Include="Autofill\AutofillService.cs" />
|
<Compile Include="Autofill\AutofillService.cs" />
|
||||||
|
@ -103,13 +105,14 @@
|
||||||
<Compile Include="Controls\ExtendedPickerRenderer.cs" />
|
<Compile Include="Controls\ExtendedPickerRenderer.cs" />
|
||||||
<Compile Include="Controls\ExtendedEntryRenderer.cs" />
|
<Compile Include="Controls\ExtendedEntryRenderer.cs" />
|
||||||
<Compile Include="MyVaultTileService.cs" />
|
<Compile Include="MyVaultTileService.cs" />
|
||||||
|
<Compile Include="Services\AndroidPushNotificationService.cs" />
|
||||||
|
<Compile Include="Services\GoogleAnalyticsService.cs" />
|
||||||
<Compile Include="Services\HttpService.cs" />
|
<Compile Include="Services\HttpService.cs" />
|
||||||
<Compile Include="Services\AndroidKeyStoreStorageService.cs" />
|
<Compile Include="Services\AndroidKeyStoreStorageService.cs" />
|
||||||
<Compile Include="Services\LocalizeService.cs" />
|
<Compile Include="Services\LocalizeService.cs" />
|
||||||
<Compile Include="MainApplication.cs" />
|
<Compile Include="MainApplication.cs" />
|
||||||
<Compile Include="Resources\Resource.Designer.cs" />
|
<Compile Include="Resources\Resource.Designer.cs" />
|
||||||
<Compile Include="Services\DeviceInfoService.cs" />
|
<Compile Include="Services\DeviceInfoService.cs" />
|
||||||
<Compile Include="Services\GoogleAnalyticsService.cs" />
|
|
||||||
<Compile Include="Services\AppInfoService.cs" />
|
<Compile Include="Services\AppInfoService.cs" />
|
||||||
<Compile Include="Services\DeviceActionService.cs" />
|
<Compile Include="Services\DeviceActionService.cs" />
|
||||||
<Compile Include="Services\BouncyCastleKeyDerivationService.cs" />
|
<Compile Include="Services\BouncyCastleKeyDerivationService.cs" />
|
||||||
|
@ -117,7 +120,6 @@
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Services\LogService.cs" />
|
<Compile Include="Services\LogService.cs" />
|
||||||
<Compile Include="Services\MemoryService.cs" />
|
<Compile Include="Services\MemoryService.cs" />
|
||||||
<Compile Include="Services\AndroidPushNotificationService.cs" />
|
|
||||||
<Compile Include="Services\ReflectionService.cs" />
|
<Compile Include="Services\ReflectionService.cs" />
|
||||||
<Compile Include="Services\SqlService.cs" />
|
<Compile Include="Services\SqlService.cs" />
|
||||||
<Compile Include="SplashActivity.cs" />
|
<Compile Include="SplashActivity.cs" />
|
||||||
|
@ -127,6 +129,8 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="8bit.keystore.enc" />
|
<None Include="8bit.keystore.enc" />
|
||||||
|
<GoogleServicesJson Include="google-services.json" />
|
||||||
|
<None Include="google-services.json.enc" />
|
||||||
<None Include="increment-version.ps1" />
|
<None Include="increment-version.ps1" />
|
||||||
<None Include="Resources\AboutResources.txt" />
|
<None Include="Resources\AboutResources.txt" />
|
||||||
<None Include="Assets\AboutAssets.txt" />
|
<None Include="Assets\AboutAssets.txt" />
|
||||||
|
@ -891,11 +895,11 @@
|
||||||
<PackageReference Include="SimpleInjector">
|
<PackageReference Include="SimpleInjector">
|
||||||
<Version>4.0.12</Version>
|
<Version>4.0.12</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Xamarin.GooglePlayServices.Analytics">
|
<PackageReference Include="Xamarin.Firebase.Messaging">
|
||||||
<Version>29.0.0.2</Version>
|
<Version>42.1021.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Xamarin.GooglePlayServices.Gcm">
|
<PackageReference Include="Xamarin.GooglePlayServices.Analytics">
|
||||||
<Version>29.0.0.2</Version>
|
<Version>42.1021.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="XLabs.IoC.SimpleInjector" Version="2.0.5782" />
|
<PackageReference Include="XLabs.IoC.SimpleInjector" Version="2.0.5782" />
|
||||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.3" />
|
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.3" />
|
||||||
|
|
23
src/Android/FirebaseInstanceIdService.cs
Normal file
23
src/Android/FirebaseInstanceIdService.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
|
using Bit.App;
|
||||||
|
using Bit.App.Abstractions;
|
||||||
|
using Firebase.Iid;
|
||||||
|
using Plugin.Settings.Abstractions;
|
||||||
|
using XLabs.Ioc;
|
||||||
|
|
||||||
|
namespace Bit.Android
|
||||||
|
{
|
||||||
|
[Service]
|
||||||
|
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
|
||||||
|
public class FirebaseInstanceIdService : Firebase.Iid.FirebaseInstanceIdService
|
||||||
|
{
|
||||||
|
public override void OnTokenRefresh()
|
||||||
|
{
|
||||||
|
var settings = Resolver.Resolve<ISettings>();
|
||||||
|
settings.AddOrUpdateValue(Constants.PushRegisteredToken, FirebaseInstanceId.Instance.Token);
|
||||||
|
Resolver.Resolve<IPushNotificationService>()?.Register();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
src/Android/FirebaseMessagingService.cs
Normal file
42
src/Android/FirebaseMessagingService.cs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
using System;
|
||||||
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
|
using Bit.App.Abstractions;
|
||||||
|
using Firebase.Messaging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using XLabs.Ioc;
|
||||||
|
|
||||||
|
namespace Bit.Android
|
||||||
|
{
|
||||||
|
[Service]
|
||||||
|
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
|
||||||
|
public class FirebaseMessagingService : Firebase.Messaging.FirebaseMessagingService
|
||||||
|
{
|
||||||
|
public override void OnMessageReceived(RemoteMessage message)
|
||||||
|
{
|
||||||
|
if(message?.Data == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = message.Data.ContainsKey("data") ? message.Data["data"] : null;
|
||||||
|
if(data == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var obj = JObject.Parse(data);
|
||||||
|
var listener = Resolver.Resolve<IPushNotificationListener>();
|
||||||
|
listener.OnMessage(obj, Device.Android);
|
||||||
|
}
|
||||||
|
catch(JsonReaderException ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,55 +61,6 @@ namespace Bit.Android
|
||||||
|
|
||||||
RegisterActivityLifecycleCallbacks(this);
|
RegisterActivityLifecycleCallbacks(this);
|
||||||
AppContext = ApplicationContext;
|
AppContext = ApplicationContext;
|
||||||
StartPushService();
|
|
||||||
HandlePushReregistration();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandlePushReregistration()
|
|
||||||
{
|
|
||||||
var pushNotification = Resolver.Resolve<IPushNotificationService>();
|
|
||||||
var settings = Resolver.Resolve<ISettings>();
|
|
||||||
|
|
||||||
// Reregister for push token based on certain conditions
|
|
||||||
// ref https://github.com/rdelrosario/xamarin-plugins/issues/65
|
|
||||||
|
|
||||||
var reregister = false;
|
|
||||||
|
|
||||||
// 1. First time starting the app after a new install
|
|
||||||
if(settings.GetValueOrDefault(FirstLaunchKey, true))
|
|
||||||
{
|
|
||||||
settings.AddOrUpdateValue(FirstLaunchKey, false);
|
|
||||||
reregister = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. App version changed (installed update)
|
|
||||||
var versionCode = Context.ApplicationContext.PackageManager.GetPackageInfo(Context.PackageName, 0).VersionCode;
|
|
||||||
if(settings.GetValueOrDefault(LastVersionCodeKey, -1) != versionCode)
|
|
||||||
{
|
|
||||||
settings.AddOrUpdateValue(LastVersionCodeKey, versionCode);
|
|
||||||
reregister = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. In debug mode
|
|
||||||
if(App.Utilities.Helpers.InDebugMode())
|
|
||||||
{
|
|
||||||
reregister = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Doesn't have a push token currently
|
|
||||||
if(string.IsNullOrWhiteSpace(pushNotification.Token))
|
|
||||||
{
|
|
||||||
reregister = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(reregister)
|
|
||||||
{
|
|
||||||
pushNotification.Unregister();
|
|
||||||
if(Resolver.Resolve<IAuthService>().IsAuthenticated)
|
|
||||||
{
|
|
||||||
pushNotification.Register();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnTerminate()
|
public override void OnTerminate()
|
||||||
|
@ -149,30 +100,6 @@ namespace Bit.Android
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StartPushService()
|
|
||||||
{
|
|
||||||
AppContext.StartService(new Intent(AppContext, typeof(AndroidPushService)));
|
|
||||||
if(Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
|
|
||||||
{
|
|
||||||
PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext,
|
|
||||||
typeof(AndroidPushService)), 0);
|
|
||||||
AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(AlarmService);
|
|
||||||
alarm.Cancel(pintent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void StopPushService()
|
|
||||||
{
|
|
||||||
AppContext.StopService(new Intent(AppContext, typeof(AndroidPushService)));
|
|
||||||
if(Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
|
|
||||||
{
|
|
||||||
PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext,
|
|
||||||
typeof(AndroidPushService)), 0);
|
|
||||||
AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(AlarmService);
|
|
||||||
alarm.Cancel(pintent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetIoc(Application application)
|
public static void SetIoc(Application application)
|
||||||
{
|
{
|
||||||
UserDialogs.Init(application);
|
UserDialogs.Init(application);
|
||||||
|
@ -237,10 +164,8 @@ namespace Bit.Android
|
||||||
container.RegisterSingleton(CrossFingerprint.Current);
|
container.RegisterSingleton(CrossFingerprint.Current);
|
||||||
|
|
||||||
// Push
|
// Push
|
||||||
var pushListener = new PushNotificationListener();
|
container.RegisterSingleton<IPushNotificationListener, PushNotificationListener>();
|
||||||
container.RegisterSingleton<IPushNotificationListener>(pushListener);
|
container.RegisterSingleton<IPushNotificationService, AndroidPushNotificationService>();
|
||||||
CrossPushNotification.Initialize(pushListener, "962181367620");
|
|
||||||
container.RegisterSingleton(CrossPushNotification.Current);
|
|
||||||
|
|
||||||
container.Verify();
|
container.Verify();
|
||||||
Resolver.SetResolver(new SimpleInjectorResolver(container));
|
Resolver.SetResolver(new SimpleInjectorResolver(container));
|
||||||
|
|
|
@ -8,11 +8,6 @@
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||||
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
|
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
||||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
|
|
||||||
<uses-permission android:name="com.x8bit.bitwarden.permission.C2D_MESSAGE" />
|
|
||||||
<permission android:name="com.x8bit.bitwarden.permission.C2D_MESSAGE" android:protectionLevel="signature" />
|
|
||||||
|
|
||||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||||
|
@ -28,6 +23,17 @@
|
||||||
android:resource="@xml/filepaths" />
|
android:resource="@xml/filepaths" />
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
|
||||||
|
android:exported="false" />
|
||||||
|
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
|
||||||
|
android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
||||||
|
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
|
||||||
|
<category android:name="${applicationId}" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
<activity android:name="net.hockeyapp.android.UpdateActivity" android:exported="false" android:icon="@drawable/icon" />
|
<activity android:name="net.hockeyapp.android.UpdateActivity" android:exported="false" android:icon="@drawable/icon" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
8482
src/Android/Resources/Resource.Designer.cs
generated
8482
src/Android/Resources/Resource.Designer.cs
generated
File diff suppressed because it is too large
Load diff
|
@ -1,560 +1,38 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using Bit.App;
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using Bit.App.Utilities;
|
using Plugin.Settings.Abstractions;
|
||||||
using System.Threading;
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Android.Gms.Gcm.Iid;
|
|
||||||
using Android.Gms.Gcm;
|
|
||||||
using Java.IO;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Android.Support.V4.App;
|
|
||||||
using Android.Media;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Bit.Android.Services
|
namespace Bit.Android.Services
|
||||||
{
|
{
|
||||||
public class AndroidPushNotificationService : IPushNotificationService
|
public class AndroidPushNotificationService : IPushNotificationService
|
||||||
{
|
{
|
||||||
private const string GcmPreferencesKey = "GCMPreferences";
|
private readonly IPushNotificationListener _pushNotificationListener;
|
||||||
private const string Tag = "PushNotification";
|
private readonly ISettings _settings;
|
||||||
|
|
||||||
internal static IPushNotificationListener Listener { get; set; }
|
public AndroidPushNotificationService(
|
||||||
public string Token => GetRegistrationId();
|
IPushNotificationListener pushNotificationListener,
|
||||||
|
ISettings settings)
|
||||||
|
{
|
||||||
|
_pushNotificationListener = pushNotificationListener;
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Token => _settings.GetValueOrDefault(Constants.PushCurrentToken, null);
|
||||||
|
|
||||||
public void Register()
|
public void Register()
|
||||||
{
|
{
|
||||||
|
var registeredToken = _settings.GetValueOrDefault(Constants.PushRegisteredToken, null);
|
||||||
System.Diagnostics.Debug.WriteLine(
|
if(!string.IsNullOrWhiteSpace(registeredToken) && registeredToken != Token)
|
||||||
$"{PushNotificationContants.DomainName} - Register - Registering push notifications");
|
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(CrossPushNotification.SenderId))
|
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine(
|
_pushNotificationListener.OnRegistered(registeredToken, Device.Android);
|
||||||
$"{PushNotificationContants.DomainName} - Register - SenderId is missing.");
|
|
||||||
|
|
||||||
CrossPushNotification.PushNotificationListener.OnError(
|
|
||||||
$"{PushNotificationContants.DomainName} - Register - Sender Id is missing.", Device.Android);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine(
|
|
||||||
$"{PushNotificationContants.DomainName} - Register - Registering for Push Notifications");
|
|
||||||
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Intent intent = new Intent(global::Android.App.Application.Context,
|
|
||||||
typeof(PushNotificationRegistrationIntentService));
|
|
||||||
|
|
||||||
global::Android.App.Application.Context.StartService(intent);
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine($"{Tag} - Error : {ex.Message}");
|
|
||||||
CrossPushNotification.PushNotificationListener.OnError($"{Tag} - Register - {ex.Message}",
|
|
||||||
Device.Android);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unregister()
|
public void Unregister()
|
||||||
{
|
{
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
// Do we ever need to unregister?
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine(
|
|
||||||
$"{PushNotificationContants.DomainName} - Unregister - Unregistering push notifications");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var instanceID = InstanceID.GetInstance(global::Android.App.Application.Context);
|
|
||||||
instanceID.DeleteToken(CrossPushNotification.SenderId, GoogleCloudMessaging.InstanceIdScope);
|
|
||||||
|
|
||||||
CrossPushNotification.PushNotificationListener.OnUnregistered(Device.Android);
|
|
||||||
StoreRegistrationId(global::Android.App.Application.Context, string.Empty);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(IOException ex)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine($"{Tag} - Error : {ex.Message}");
|
|
||||||
CrossPushNotification.PushNotificationListener.OnError(
|
|
||||||
$"{Tag} - Unregister - {ex.Message}", Device.Android);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetRegistrationId()
|
|
||||||
{
|
|
||||||
var context = global::Android.App.Application.Context;
|
|
||||||
var prefs = GetGCMPreferences(context);
|
|
||||||
var registrationId = prefs.GetString(PushNotificationContants.Token, string.Empty);
|
|
||||||
if(string.IsNullOrEmpty(registrationId))
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine($"{PushNotificationContants.DomainName} - Registration not found.");
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if app was updated; if so, it must clear the registration ID
|
|
||||||
// since the existing registration ID is not guaranteed to work with
|
|
||||||
// the new app version.
|
|
||||||
var registeredVersion = prefs.GetInt(PushNotificationContants.AppVersion, Java.Lang.Integer.MinValue);
|
|
||||||
var currentVersion = GetAppVersion(context);
|
|
||||||
if(registeredVersion != currentVersion)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine($"{PushNotificationContants.DomainName} - App version changed.");
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return registrationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static ISharedPreferences GetGCMPreferences(Context context)
|
|
||||||
{
|
|
||||||
return context.GetSharedPreferences(GcmPreferencesKey, FileCreationMode.Private);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static int GetAppVersion(Context context)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var packageInfo = context.PackageManager.GetPackageInfo(context.PackageName, 0);
|
|
||||||
return packageInfo.VersionCode;
|
|
||||||
}
|
|
||||||
catch(global::Android.Content.PM.PackageManager.NameNotFoundException e)
|
|
||||||
{
|
|
||||||
// should never happen
|
|
||||||
throw new Java.Lang.RuntimeException("Could not get package name: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void StoreRegistrationId(Context context, string regId)
|
|
||||||
{
|
|
||||||
var prefs = GetGCMPreferences(context);
|
|
||||||
var appVersion = GetAppVersion(context);
|
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine(
|
|
||||||
$"{PushNotificationContants.DomainName} - Saving token on app version {appVersion}");
|
|
||||||
|
|
||||||
var editor = prefs.Edit();
|
|
||||||
editor.PutString(PushNotificationContants.Token, regId);
|
|
||||||
editor.PutInt(PushNotificationContants.AppVersion, appVersion);
|
|
||||||
editor.Commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Service(Exported = false)]
|
|
||||||
public class PushNotificationRegistrationIntentService : IntentService
|
|
||||||
{
|
|
||||||
private const string Tag = "PushNotificationRegistationIntentService";
|
|
||||||
private string[] _topics = new string[] { "global" };
|
|
||||||
private readonly object _syncLock = new object();
|
|
||||||
|
|
||||||
protected override void OnHandleIntent(Intent intent)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var extras = intent.Extras;
|
|
||||||
lock(_syncLock)
|
|
||||||
{
|
|
||||||
var instanceID = InstanceID.GetInstance(global::Android.App.Application.Context);
|
|
||||||
var token = instanceID.GetToken(CrossPushNotification.SenderId,
|
|
||||||
GoogleCloudMessaging.InstanceIdScope, null);
|
|
||||||
CrossPushNotification.PushNotificationListener.OnRegistered(token, Device.Android);
|
|
||||||
AndroidPushNotificationService.StoreRegistrationId(global::Android.App.Application.Context, token);
|
|
||||||
SubscribeTopics(token);
|
|
||||||
System.Diagnostics.Debug.WriteLine($"{token} - Device registered, registration ID={Tag}");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine($"{ex.Message} - Error : {Tag}");
|
|
||||||
CrossPushNotification.PushNotificationListener.OnError(
|
|
||||||
$"{ex.ToString()} - Register - {Tag}", Device.Android);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SubscribeTopics(string token)
|
|
||||||
{
|
|
||||||
var pubSub = GcmPubSub.GetInstance(this);
|
|
||||||
foreach(var topic in _topics)
|
|
||||||
{
|
|
||||||
pubSub.Subscribe(token, "/topics/" + topic, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Service(Exported = false)]
|
|
||||||
[IntentFilter(new string[] { "com.google.android.gms.iid.InstanceID" })]
|
|
||||||
public class PushNotificationInstanceIDListenerService : InstanceIDListenerService
|
|
||||||
{
|
|
||||||
private const string Tag = "PushNotificationInstanceIDLS";
|
|
||||||
|
|
||||||
public override void OnTokenRefresh()
|
|
||||||
{
|
|
||||||
base.OnTokenRefresh();
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var intent = new Intent(global::Android.App.Application.Context,
|
|
||||||
typeof(PushNotificationRegistrationIntentService));
|
|
||||||
global::Android.App.Application.Context.StartService(intent);
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine($"{ex.Message} - Error : {Tag}");
|
|
||||||
CrossPushNotification.PushNotificationListener.OnError(
|
|
||||||
$"{ex.ToString()} - Register - {Tag}", Device.Android);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Service(Exported = false, Name = "pushnotification.plugin.PushNotificationGcmListener")]
|
|
||||||
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" },
|
|
||||||
Categories = new string[] { "com.x8bit.bitwarden" })]
|
|
||||||
public class PushNotificationGcmListener : GcmListenerService
|
|
||||||
{
|
|
||||||
public override void OnMessageReceived(string from, Bundle extras)
|
|
||||||
{
|
|
||||||
if(extras != null && !extras.IsEmpty)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine(
|
|
||||||
$"{PushNotificationContants.DomainName} - GCM Listener - Push Received");
|
|
||||||
|
|
||||||
var parameters = new Dictionary<string, object>();
|
|
||||||
var values = new JObject();
|
|
||||||
foreach(var key in extras.KeySet())
|
|
||||||
{
|
|
||||||
var value = extras.Get(key).ToString();
|
|
||||||
|
|
||||||
if(ValidateJSON(value))
|
|
||||||
{
|
|
||||||
values.Add(key, JObject.Parse(value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
values.Add(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
parameters.Add(key, extras.Get(key));
|
|
||||||
System.Diagnostics.Debug.WriteLine(
|
|
||||||
$"{PushNotificationContants.DomainName} - GCM Listener - Push Params {key} : {extras.Get(key)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
var context = global::Android.App.Application.Context;
|
|
||||||
CrossPushNotification.PushNotificationListener.OnMessage(values, Device.Android);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var notifyId = 0;
|
|
||||||
var title = context.ApplicationInfo.LoadLabel(context.PackageManager);
|
|
||||||
var message = string.Empty;
|
|
||||||
var tag = string.Empty;
|
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTextKey) &&
|
|
||||||
parameters.ContainsKey(CrossPushNotification.NotificationContentTextKey))
|
|
||||||
{
|
|
||||||
message = parameters[CrossPushNotification.NotificationContentTextKey].ToString();
|
|
||||||
}
|
|
||||||
else if(parameters.ContainsKey(PushNotificationContants.Alert))
|
|
||||||
{
|
|
||||||
message = parameters[PushNotificationContants.Alert].ToString();
|
|
||||||
}
|
|
||||||
else if(parameters.ContainsKey(PushNotificationContants.Message))
|
|
||||||
{
|
|
||||||
message = parameters[PushNotificationContants.Message].ToString();
|
|
||||||
}
|
|
||||||
else if(parameters.ContainsKey(PushNotificationContants.Subtitle))
|
|
||||||
{
|
|
||||||
message = parameters[PushNotificationContants.Subtitle].ToString();
|
|
||||||
}
|
|
||||||
else if(parameters.ContainsKey(PushNotificationContants.Text))
|
|
||||||
{
|
|
||||||
message = parameters[PushNotificationContants.Text].ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTitleKey) &&
|
|
||||||
parameters.ContainsKey(CrossPushNotification.NotificationContentTitleKey))
|
|
||||||
{
|
|
||||||
title = parameters[CrossPushNotification.NotificationContentTitleKey].ToString();
|
|
||||||
}
|
|
||||||
else if(parameters.ContainsKey(PushNotificationContants.Title))
|
|
||||||
{
|
|
||||||
if(!string.IsNullOrEmpty(message))
|
|
||||||
{
|
|
||||||
title = parameters[PushNotificationContants.Title].ToString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message = parameters[PushNotificationContants.Title].ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(message))
|
|
||||||
{
|
|
||||||
var data = (
|
|
||||||
!string.IsNullOrEmpty(CrossPushNotification.NotificationContentDataKey) &&
|
|
||||||
values[CrossPushNotification.NotificationContentDataKey] != null) ?
|
|
||||||
values[CrossPushNotification.NotificationContentDataKey] :
|
|
||||||
values[PushNotificationContants.Data];
|
|
||||||
|
|
||||||
if(data != null)
|
|
||||||
{
|
|
||||||
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTextKey) &&
|
|
||||||
data[CrossPushNotification.NotificationContentTextKey] != null)
|
|
||||||
{
|
|
||||||
message = data[CrossPushNotification.NotificationContentTextKey].ToString();
|
|
||||||
}
|
|
||||||
else if(data[PushNotificationContants.Alert] != null)
|
|
||||||
{
|
|
||||||
message = data[PushNotificationContants.Alert].ToString();
|
|
||||||
}
|
|
||||||
else if(data[PushNotificationContants.Message] != null)
|
|
||||||
{
|
|
||||||
message = data[PushNotificationContants.Message].ToString();
|
|
||||||
}
|
|
||||||
else if(data[PushNotificationContants.Subtitle] != null)
|
|
||||||
{
|
|
||||||
message = data[PushNotificationContants.Subtitle].ToString();
|
|
||||||
}
|
|
||||||
else if(data[PushNotificationContants.Text] != null)
|
|
||||||
{
|
|
||||||
message = data[PushNotificationContants.Text].ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(CrossPushNotification.NotificationContentTitleKey) &&
|
|
||||||
data[CrossPushNotification.NotificationContentTitleKey] != null)
|
|
||||||
{
|
|
||||||
title = data[CrossPushNotification.NotificationContentTitleKey].ToString();
|
|
||||||
}
|
|
||||||
else if(data[PushNotificationContants.Title] != null)
|
|
||||||
{
|
|
||||||
if(!string.IsNullOrEmpty(message))
|
|
||||||
{
|
|
||||||
title = data[PushNotificationContants.Title].ToString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message = data[PushNotificationContants.Title].ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parameters.ContainsKey(PushNotificationContants.Id))
|
|
||||||
{
|
|
||||||
var str = parameters[PushNotificationContants.Id].ToString();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
notifyId = Convert.ToInt32(str);
|
|
||||||
}
|
|
||||||
catch(Exception)
|
|
||||||
{
|
|
||||||
// Keep the default value of zero for the notify_id, but log the conversion problem.
|
|
||||||
System.Diagnostics.Debug.WriteLine("Failed to convert {0} to an integer", str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parameters.ContainsKey(PushNotificationContants.Tag))
|
|
||||||
{
|
|
||||||
tag = parameters[PushNotificationContants.Tag].ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!parameters.ContainsKey(PushNotificationContants.Silent) ||
|
|
||||||
!System.Boolean.Parse(parameters[PushNotificationContants.Silent].ToString()))
|
|
||||||
{
|
|
||||||
if(CrossPushNotification.PushNotificationListener.ShouldShowNotification())
|
|
||||||
{
|
|
||||||
CreateNotification(title, message, notifyId, tag, extras);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(Java.Lang.Exception ex)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine(ex.ToString());
|
|
||||||
}
|
|
||||||
catch(Exception ex1)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine(ex1.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateNotification(string title, string message, int notifyId, string tag, Bundle extras)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine(
|
|
||||||
$"{PushNotificationContants.DomainName} - PushNotification - Message {title} : {message}");
|
|
||||||
|
|
||||||
NotificationCompat.Builder builder = null;
|
|
||||||
var context = global::Android.App.Application.Context;
|
|
||||||
|
|
||||||
if(CrossPushNotification.SoundUri == null)
|
|
||||||
{
|
|
||||||
CrossPushNotification.SoundUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(CrossPushNotification.IconResource == 0)
|
|
||||||
{
|
|
||||||
CrossPushNotification.IconResource = context.ApplicationInfo.Icon;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var name = context.Resources.GetResourceName(CrossPushNotification.IconResource);
|
|
||||||
if(name == null)
|
|
||||||
{
|
|
||||||
CrossPushNotification.IconResource = context.ApplicationInfo.Icon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(global::Android.Content.Res.Resources.NotFoundException ex)
|
|
||||||
{
|
|
||||||
CrossPushNotification.IconResource = context.ApplicationInfo.Icon;
|
|
||||||
System.Diagnostics.Debug.WriteLine(ex.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultIntent = context.PackageManager.GetLaunchIntentForPackage(context.PackageName);
|
|
||||||
if(extras != null)
|
|
||||||
{
|
|
||||||
resultIntent.PutExtras(extras);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a PendingIntent; we're only using one PendingIntent (ID = 0):
|
|
||||||
const int pendingIntentId = 0;
|
|
||||||
var resultPendingIntent = PendingIntent.GetActivity(context, pendingIntentId,
|
|
||||||
resultIntent, PendingIntentFlags.OneShot);
|
|
||||||
|
|
||||||
// Build the notification
|
|
||||||
builder = new NotificationCompat.Builder(context)
|
|
||||||
.SetAutoCancel(true) // dismiss the notification from the notification area when the user clicks on it
|
|
||||||
.SetContentIntent(resultPendingIntent) // start up this activity when the user clicks the intent.
|
|
||||||
.SetContentTitle(title) // Set the title
|
|
||||||
.SetSound(CrossPushNotification.SoundUri)
|
|
||||||
.SetSmallIcon(CrossPushNotification.IconResource) // This is the icon to display
|
|
||||||
.SetContentText(message); // the message to display.
|
|
||||||
|
|
||||||
if(Build.VERSION.SdkInt >= BuildVersionCodes.JellyBean)
|
|
||||||
{
|
|
||||||
// Using BigText notification style to support long message
|
|
||||||
var style = new NotificationCompat.BigTextStyle();
|
|
||||||
style.BigText(message);
|
|
||||||
builder.SetStyle(style);
|
|
||||||
}
|
|
||||||
|
|
||||||
var notificationManager = (NotificationManager)context.GetSystemService(NotificationService);
|
|
||||||
notificationManager.Notify(tag, notifyId, builder.Build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool ValidateJSON(string s)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
JObject.Parse(s);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch(JsonReaderException ex)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine(ex.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[BroadcastReceiver(Exported = true, Permission = "com.google.android.c2dm.permission.SEND")]
|
|
||||||
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" },
|
|
||||||
Categories = new string[] { "com.x8bit.bitwarden" })]
|
|
||||||
public class PushNotificationsReceiver : GcmReceiver
|
|
||||||
{ }
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
public class AndroidPushService : Service
|
|
||||||
{
|
|
||||||
public override void OnCreate()
|
|
||||||
{
|
|
||||||
base.OnCreate();
|
|
||||||
System.Diagnostics.Debug.WriteLine("Push Notification Service - Created");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine("Push Notification Service - Started");
|
|
||||||
return StartCommandResult.Sticky;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IBinder OnBind(Intent intent)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine("Push Notification Service - Binded");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDestroy()
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine("Push Notification Service - Destroyed");
|
|
||||||
base.OnDestroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class CrossPushNotification
|
|
||||||
{
|
|
||||||
private static Lazy<IPushNotificationService> Implementation = new Lazy<IPushNotificationService>(
|
|
||||||
() => new AndroidPushNotificationService(),
|
|
||||||
LazyThreadSafetyMode.PublicationOnly);
|
|
||||||
public static bool IsInitialized => PushNotificationListener != null;
|
|
||||||
public static IPushNotificationListener PushNotificationListener { get; private set; }
|
|
||||||
|
|
||||||
public static string SenderId { get; set; }
|
|
||||||
public static string NotificationContentTitleKey { get; set; }
|
|
||||||
public static string NotificationContentTextKey { get; set; }
|
|
||||||
public static string NotificationContentDataKey { get; set; }
|
|
||||||
public static int IconResource { get; set; }
|
|
||||||
public static global::Android.Net.Uri SoundUri { get; set; }
|
|
||||||
|
|
||||||
public static void Initialize<T>(T listener, string senderId) where T : IPushNotificationListener
|
|
||||||
{
|
|
||||||
SenderId = senderId;
|
|
||||||
|
|
||||||
if(PushNotificationListener == null)
|
|
||||||
{
|
|
||||||
PushNotificationListener = listener;
|
|
||||||
System.Diagnostics.Debug.WriteLine("PushNotification plugin initialized.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.WriteLine("PushNotification plugin already initialized.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Initialize<T>(string senderId) where T : IPushNotificationListener, new()
|
|
||||||
{
|
|
||||||
Initialize(new T(), senderId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IPushNotificationService Current
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if(!IsInitialized)
|
|
||||||
{
|
|
||||||
throw new Exception("Not initialized.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var ret = Implementation.Value;
|
|
||||||
if(ret == null)
|
|
||||||
{
|
|
||||||
throw new Exception("Not in PCL");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
src/Android/google-services.json
Normal file
42
src/Android/google-services.json
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "1093287226212",
|
||||||
|
"firebase_url": "https://bitwarden-dev.firebaseio.com",
|
||||||
|
"project_id": "bitwarden-dev",
|
||||||
|
"storage_bucket": "bitwarden-dev.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:1093287226212:android:f8d67b786db1b844",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.x8bit.bitwarden"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "1093287226212-m4mv8ho387tdgosc9lsltnmruul7ouo0.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyA4Xkn0do7Ky_OLff2L_7MXeNK6s-JVgXg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"analytics_service": {
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"appinvite_service": {
|
||||||
|
"status": 1,
|
||||||
|
"other_platform_oauth_client": []
|
||||||
|
},
|
||||||
|
"ads_service": {
|
||||||
|
"status": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
BIN
src/Android/google-services.json.enc
Normal file
BIN
src/Android/google-services.json.enc
Normal file
Binary file not shown.
|
@ -26,7 +26,7 @@
|
||||||
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.0.3" />
|
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.0.3" />
|
||||||
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
|
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
|
||||||
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.2.9" />
|
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.2.9" />
|
||||||
<PackageReference Include="Xamarin.Forms" Version="2.4.0.91020" />
|
<PackageReference Include="Xamarin.Forms" Version="2.5.0.121934" />
|
||||||
<PackageReference Include="XLabs.IoC" Version="2.0.5782" />
|
<PackageReference Include="XLabs.IoC" Version="2.0.5782" />
|
||||||
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.1.47" />
|
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.1.47" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
public const string PushInitialPromptShown = "push:initialPromptShown";
|
public const string PushInitialPromptShown = "push:initialPromptShown";
|
||||||
public const string PushLastRegistrationDate = "push:lastRegistrationDate";
|
public const string PushLastRegistrationDate = "push:lastRegistrationDate";
|
||||||
|
public const string PushCurrentToken = "push:currentToken";
|
||||||
|
public const string PushRegisteredToken = "push:registeredToken";
|
||||||
|
|
||||||
public const string ExtensionStarted = "extension:started";
|
public const string ExtensionStarted = "extension:started";
|
||||||
public const string ExtensionActivated = "extension:activated";
|
public const string ExtensionActivated = "extension:activated";
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Bit.App.Models;
|
||||||
using Plugin.Settings.Abstractions;
|
using Plugin.Settings.Abstractions;
|
||||||
using System;
|
using System;
|
||||||
using XLabs.Ioc;
|
using XLabs.Ioc;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Bit.App.Services
|
namespace Bit.App.Services
|
||||||
{
|
{
|
||||||
|
@ -52,13 +53,21 @@ namespace Bit.App.Services
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JToken dataToken;
|
PushNotificationDataPayload data = null;
|
||||||
if(!value.TryGetValue("data", StringComparison.OrdinalIgnoreCase, out dataToken) || dataToken == null)
|
if(deviceType == Device.Android)
|
||||||
{
|
{
|
||||||
return;
|
data = value.ToObject<PushNotificationDataPayload>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!value.TryGetValue("data", StringComparison.OrdinalIgnoreCase, out JToken dataToken) ||
|
||||||
|
dataToken == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data = dataToken.ToObject<PushNotificationDataPayload>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = dataToken.ToObject<PushNotificationDataPayload>();
|
|
||||||
if(data?.Payload == null)
|
if(data?.Payload == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -159,6 +168,10 @@ namespace Bit.App.Services
|
||||||
{
|
{
|
||||||
Debug.WriteLine("Registered device with server.");
|
Debug.WriteLine("Registered device with server.");
|
||||||
_settings.AddOrUpdateValue(Constants.PushLastRegistrationDate, DateTime.UtcNow);
|
_settings.AddOrUpdateValue(Constants.PushLastRegistrationDate, DateTime.UtcNow);
|
||||||
|
if(deviceType == Device.Android)
|
||||||
|
{
|
||||||
|
_settings.AddOrUpdateValue(Constants.PushCurrentToken, token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue