4

I'm using GCM Service for push notification, it's working fine when App is open or in backgourd, but when app is closed it's Crashing:

enter image description here

Exception:

FATAL EXCEPTION: main Process: br.com.siagri.SiagriAutorize, PID: 15786 android.runtime.JavaProxyThrowable: System.NotSupportedException: Could not activate JNI Handle 0xbeed8498 (key_handle 0xa7376b4) of Java type 'md5d8b390bb35897e87a51d1b4384dffa30/GcmService' as managed type 'SiagriAuth.Droid.Services.GcmService'. ---> System.InvalidOperationException: You MUST call Xamarin.Forms.Init(); prior to using it.

I have followed this tutorial and taked a look at this sample but i dont saw any about/diferent for notification works when the app is closed.

This is my method to recive and process the notification:

 private void CreateNotification(string title, string desc, string approvalCode)
        {
            try
            {
                //Create notification
                var notificationManager = GetSystemService(NotificationService) as NotificationManager;

                //Create an intent to show ui
                var uiIntent = new Intent(this, typeof(MainActivity));

                //Use Notification Builder
                var builder = new NotificationCompat.Builder(this);

                //Create the notification
                //we use the pending intent, passing our ui intent over which will get called
                //when the notification is tapped.
                var notification = builder.SetContentIntent(PendingIntent.GetActivity(this, 0, uiIntent, 0))
                        .SetSmallIcon(Resource.Drawable.icon)
                        .SetTicker(title)
                        .SetContentTitle(title)
                        .SetContentText(desc)
                        .SetPriority((int)NotificationPriority.High)
                        .SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate)
                        //Set the notification sound
                        .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification))
                        //Auto cancel will remove the notification once the user touches it
                        .SetAutoCancel(true).Build();
                //Show the notification

                int uniqueIdentifier = 0;
                for (int i = 0; i < approvalCode.Length; i++)
                {
                    uniqueIdentifier += (int)approvalCode[i];
                }
                notificationManager?.Notify(uniqueIdentifier, notification);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                App.LocalAlert("Erro", "Erro ao criar notificação.");
            }
        }

        protected override void OnMessage(Context context, Intent intent)
        {
            try
            {
                if (intent != null && intent.Extras != null)
                {
                    var messageText = intent.Extras.GetString("message");
                    var approvalCode = intent.Extras.GetString("ApprovalCode");
                    if (!string.IsNullOrEmpty(messageText) && !string.IsNullOrEmpty(approvalCode))
                        CreateNotification($"Solicitação - {approvalCode}", messageText, approvalCode);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                App.LocalAlert("Erro", "Erro ao criar notificação.");
            }
        }

I'm using these assembly:

[assembly: Permission(Name = "myProject.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "myProject.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
[assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]

And these IntentFilter:

 [BroadcastReceiver(Permission = Constants.PERMISSION_GCM_INTENTS)]
    [IntentFilter(new[] { Constants.INTENT_FROM_GCM_MESSAGE }, Categories = new[] { "br.com.siagri.SiagriAutorize" })]
    [IntentFilter(new[] { Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new[] { "br.com.siagri.SiagriAutorize" })]
    [IntentFilter(new[] { Constants.INTENT_FROM_GCM_LIBRARY_RETRY }, Categories = new[] { "br.com.siagri.SiagriAutorize" })]

Any idea of how to make this works for closed apps?

Obs.: I'm already running the app in release mode.

Pedro Franco
  • 1,926
  • 1
  • 15
  • 37
  • **`i'm gotting an error message`** And what is the error message? – SushiHangover Jan 18 '18 at 13:11
  • hi @SushiHangover sory for saying that i got a erro message, the app is crashing. i provider a image. – Pedro Franco Jan 18 '18 at 13:49
  • Review the `logcat` for details of the crash and is it crashing during the local notification creation or when the use taps on the notification? – SushiHangover Jan 18 '18 at 14:00
  • I don't know where it's crashing cause its closed so i cant debug, and when i run in debug mode, background and open, work fine. @SushiHangover – Pedro Franco Jan 18 '18 at 15:41
  • Review the `logcat` for details and/or implmenent a crash reporter – SushiHangover Jan 18 '18 at 21:59
  • What is the `SIAGRI Autorize parou`? ANR? Please add [UncaughtExceptionHandler](https://developer.android.com/reference/java/lang/Thread.UncaughtExceptionHandler.html) to get the exception. If it is ANR, please use `adb pull /data/anr/traces.txt` to get the traces file, and edit your question. – Robbit Jan 19 '18 at 07:20
  • @JoeLv SIAGRI Autorize is the name of my aplication, and "parou" is stop in portuguese. I don't know how to get exception in this case cause when the application is close i cant debug. – Pedro Franco Jan 19 '18 at 10:41
  • Please try [`UnacughtExceptionHanlder`](https://stackoverflow.com/questions/39668236/how-to-properly-write-a-custom-uncaughtexceptionhandler-in-xamarin-android) – Robbit Jan 19 '18 at 10:43
  • 1
    Visual Studio->tools->Android->Android Device Monitors, select your phone, you will see the log in console. – Robbit Jan 19 '18 at 10:49
  • @JoeLv Thanks, i got the exception, i update the question – Pedro Franco Jan 19 '18 at 11:17
  • `You MUST call Xamarin.Forms.Init(); prior to using it.`, Xamarin.Forms project? – Robbit Jan 19 '18 at 11:22
  • Yes it is a Xamarin.Forms – Pedro Franco Jan 19 '18 at 11:28
  • [Have you seen this?](https://stackoverflow.com/questions/10593022/monodroid-error-when-calling-constructor-of-custom-view-twodscrollview/10603714#10603714) maybe you need adjust the code order – Robbit Jan 19 '18 at 11:33
  • I don't, but i solve the problema, i was trying to access Database, instantiating my repository on GcmService constructor. Thank's @JoeLv u help me a lot. – Pedro Franco Jan 19 '18 at 11:43
  • I suggest you give an answer, so it will help other people. – Robbit Jan 19 '18 at 11:47

1 Answers1

2

My error was in the construct of GcmService, i was instantiating my repository there, so i was trying to access the database, i just remove from constructor and put on my registered method, that was where i used it.

 public GcmService() : base(PushHandlerBroadcastReceiver.SenderIds)
    {
        Log.Info(PushHandlerBroadcastReceiver.Tag, "PushHandlerService() constructor");
        _permissaoRepository = new PermissaoRepository(App.SiagriAuthContext);
        _loginRepository = new LoginRepository(App.SiagriAuthContext);
    }

I changed to:

public GcmService() : base(PushHandlerBroadcastReceiver.SenderIds)
    {
        Log.Info(PushHandlerBroadcastReceiver.Tag, "PushHandlerService() constructor");
    }

So i can't access my database when the app is closed, this is quite reasonable. I have make a quick search of try to use database when app is closed but i dont found, but here and here have something about use local database.

Pedro Franco
  • 1,926
  • 1
  • 15
  • 37