Unable to save push notification in SQLite when Xamarin Android App is Swiped or closed

天涯浪子 提交于 2021-01-07 01:32:17

问题


I am having issues saving and displaying push notification in my apps UI when the app is swiped from memory or closed. I still receive the notifications in this state, but upon opening the app or tapping the notification to open the app, the message does not display. Everything works fine when the app is running or in the background. I've followed the documentation here https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/azure-services/azure-notification-hub with a few modification to save the notification in a SQLite file. I finally got this to work for iOS but no such luck on Android. Here is my code.

FireBaseService class

  [Service]
        [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
        public class FirebaseService : FirebaseMessagingService
        {

        public override void OnMessageReceived(RemoteMessage message)
        {
            base.OnMessageReceived(message);
            string messageBody = string.Empty;

            if (message.GetNotification() != null)
            {
                messageBody = message.GetNotification().Body;
            }

            // NOTE: test messages sent via the Azure portal will be received here
            else
            {
                messageBody = message.Data.Values.First();
            }

            // convert the incoming message to a local notification
            SendLocalNotification(messageBody);


            // send the incoming message directly to the MainPage
            SendMessageToMainPage(messageBody);
        }

        //public override void HandleIntent(Intent intent)
        //{
        //    base.HandleIntent(intent);


        //    //Create your notification
        //}


        public override void OnNewToken(string token)
        {
            // TODO: save token instance locally, or log if desired

            SendRegistrationToServer(token);
        }

        void SendLocalNotification(string body)
        {
            var intent = new Intent(this, typeof(MainActivity));
            intent.AddFlags(ActivityFlags.ClearTop);
            intent.PutExtra("message", body);
            var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 
PendingIntentFlags.OneShot);
            var notificationBuilder = new NotificationCompat.Builder(this, 
AppConstants.NotificationChannelName)
               .SetContentTitle("MyMessage")
                .SetSmallIcon(Resource.Drawable.pushimageicon)
                .SetContentText(body)
                .SetAutoCancel(true)
                .SetWhen(JavaSystem.CurrentTimeMillis())
                .SetShowWhen(true)
                .SetStyle(new NotificationCompat.BigTextStyle())
                .SetContentIntent(pendingIntent);

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
            }
            int m = (int)((new Date().Time / 1000L) % Integer.MaxValue);
            var notificationManager = NotificationManager.FromContext(this);
            notificationManager.Notify(m, notificationBuilder.Build());
        }


        void SendMessageToMainPage(string body)
        {
            //send to AppShell to save in SQLite
            (Xamarin.Forms.Application.Current.MainPage as AppShell)?.AddMessage(body);
        }

        void SendRegistrationToServer(string token)
        {
            try
            {
                NotificationHub hub = new NotificationHub(AppConstants.NotificationHubName, 
AppConstants.ListenConnectionString, this);

                // register device with Azure Notification Hub using the token from FCM
                Registration registration = hub.Register(token, AppConstants.SubscriptionTags);

                // subscribe to the SubscriptionTags list with a simple template.
                string pnsHandle = registration.PNSHandle;
                TemplateRegistration templateReg = hub.RegisterTemplate(pnsHandle, "defaultTemplate", 
AppConstants.FCMTemplateBody, AppConstants.SubscriptionTags);
            }
            catch (System.Exception e)
            {
                Log.Error(AppConstants.DebugTag, $"Error registering device: {e.Message}");
            }
        }
    }

MainActivity.cs

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        Rg.Plugins.Popup.Popup.Init(this, savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

        //SQLite Code
        string fileName = "sample.db";
        string folderPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
        string completePath = Path.Combine(folderPath, fileName);

        if (!File.Exists(completePath))
        {
            using (var binaryReader = new BinaryReader(Android.App.Application.Context.Assets.Open(fileName)))
            {
                using (var binaryWriter = new BinaryWriter(new FileStream(completePath, FileMode.Create)))
                {
                    byte[] buffer = new byte[2048];
                    int length = 0;
                    while ((length = binaryReader.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        binaryWriter.Write(buffer, 0, length);
                    }
                }

            }
        }
        //End SQLite Code
        LoadApplication(new App(completePath));

        //For azure push notification
        if (!IsPlayServiceAvailable())
        {
            throw new Exception("This device does not have Google Play Services and cannot receive push notifications.");
        }

        CreateNotificationChannel();

        //END azure push notification

    }

    //For azure push notification
    protected override void OnNewIntent(Intent intent)
    {
        if (intent.Extras != null)
        {
            var message = intent.GetStringExtra("message");
            // save message in SQLite on AppShell
            (Xamarin.Forms.Application.Current.MainPage as AppShell)?.AddMessage(message);
        }

        base.OnNewIntent(intent);
    }


    bool IsPlayServiceAvailable()
    {
        int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.Success)
        {
            if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
                Log.Debug(AppConstants.DebugTag, GoogleApiAvailability.Instance.GetErrorString(resultCode));
            else
            {
                Log.Debug(AppConstants.DebugTag, "This device is not supported");
            }
            return false;
        }
        return true;
    }

    void CreateNotificationChannel()
    {
        // Notification channels are new as of "Oreo".
        // There is no need to create a notification channel on older versions of Android.
        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            var channelName = AppConstants.NotificationChannelName;
            var channelDescription = String.Empty;
            var channel = new NotificationChannel(channelName, channelName, NotificationImportance.Default)
            {
                Description = channelDescription
            };

            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.CreateNotificationChannel(channel);
        }
    }


    //END azure push notification


    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
android:versionCode="1" android:versionName="1.0" 
package="YOUR_PACKAGE_NAME" 
android:installLocation="auto">
  <uses-sdk android:minSdkVersion="21" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission 
android:name="com.google.android.c2dm.permission.RECEIVE" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
  <application android:label="Notification Hub Sample">
    <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>
  </application>
</manifest>

Any help would be appreciated. So far everything I find says to use onHandleIntent method but my application says there is no override for this method.

来源:https://stackoverflow.com/questions/61639866/unable-to-save-push-notification-in-sqlite-when-xamarin-android-app-is-swiped-or

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!