Невозможно сохранить уведомление pu sh в SQLite, когда приложение Xamarin Android перемещено или закрыто - PullRequest
0 голосов
/ 06 мая 2020

У меня возникают проблемы с сохранением и отображением уведомления pu sh в пользовательском интерфейсе моих приложений, когда приложение извлекается из памяти или закрывается. Я все еще получаю уведомления в этом состоянии, но после открытия приложения или нажатия на уведомление, чтобы открыть приложение, сообщение не отображается. Все работает нормально, когда приложение работает или в фоновом режиме. Я следил за документацией здесь https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/azure-services/azure-notification-hub с небольшими изменениями, чтобы сохранить уведомление в файле SQLite. Наконец-то я заставил это работать для iOS, но на Android не повезло. Вот мой код.

Класс FireBaseService

  [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>

Любая помощь приветствуется. Пока все, что я нашел, говорит об использовании метода onHandleIntent, но мое приложение говорит, что для этого метода нет переопределения.

...