0

I am trying to start an app build in Xamarin that runs normally when pushed to the emulator running android 7.1 (API 25). However when I want to start a service from the app on boot the app crashes but then still seems to be running and working? Since I have no way of debugging an emulator on reboot I am clueless as to where this is going wrong.

I have the following broadcastreceiver:

[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class BootBroadcastReceiver : BroadcastReceiver  
{

    public override void OnReceive(Context context, Intent intent)
    {
        if (intent.Action.Equals(Intent.ActionBootCompleted))
        {
            Toast.MakeText(context, "Action Boot Completed!", ToastLength.Long).Show();
            Intent i = new Intent(context, typeof(BackGroundService));       
            context.StartService(i); 
        }
    }
}

With the following permissions:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="One.Android" android:icon="@drawable/baseball">
        <receiver android:enabled="true"
        android:exported="true" 
        android-permission="android.permission.RECEIVE_BOOT_COMPLETED"
        android:name=".BootBroadcastReceiver" >

        <intent-filter >
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
</application>

And the following service:

 [Service]
public class BackGroundService : Service
{
    private Timer _checkServiceTimer;
    private Notifications notifi = new Notifications();


    public override IBinder OnBind(Intent intent)
    {
        throw new NotImplementedException();
    }

    public void MyDebugServiceTester()
    {
        int i = 0;
        _checkServiceTimer = new Timer((o) => {
            i++;
            notifi.SendLocalNotification("BackGround Booted", "notification number: " + i.ToString(), 0);
            //Log.Debug("Refreshing background service", "ammount of times: " + i.ToString());

        }, null, 0, 30000);
    }

    [return: GeneratedEnum]
    public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
    {
        Log.Debug("BackGroundReceiver", "Started Succesfully");
        MyDebugServiceTester();
        //return base.OnStartCommand(intent, flags, startId);
        return StartCommandResult.NotSticky;
    }

    public override bool StopService(Intent name)
    {
        Log.Debug("BackGroundReceiver", "Stopped Succesfully");
        return base.StopService(name);
    }

Does anyone know why it crashes and then runs anyway? any tips or solutions are appreciated.

Tvt
  • 223
  • 1
  • 3
  • 16

1 Answers1

1

You can run adb logcat from the command line after the emulator has started. Android will cache errors for a little while, so any crash report and stack trace is still there.

Investigating this output could point you to the root cause.

An easy way to store the logcat log to a file is this command adb logcat -d > logcat.txt

EDIT: There is also another thing you can try. While your debugger is attached.

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED com.example.app Change 'com.example.app' to your application name. This will will send the BOOT_COMPLETE message to your broadcast receivers.

J. Vergeer
  • 680
  • 1
  • 5
  • 12
  • If this works after it has started it's not of any use right? Because the service starts when the emulator is starting. Will try it out though. – Tvt Jan 03 '18 at 12:09
  • it seems that when i run **adb shell am broadcast -a android.intent.action.BOOT_COMPLETED com.example.app** it says it does not have permissions. Shoudln't the manifest handle this? – Tvt Jan 03 '18 at 12:23
  • Ok it seems that Vergeer is right. The last command shows me that I do not have sufficient permissions and that with an higher API then 23 you yourself explicitly need to ask for permissions like: https://blog.xamarin.com/requesting-runtime-permissions-in-android-marshmallow/ Will take a while to figure this out but this seems to be the next step. – Tvt Jan 03 '18 at 12:42
  • I'm sorry, sending the BOOT_COMPLETE action seems to require that adb runs as root. according to: https://stackoverflow.com/questions/40698450/android-trying-to-test-a-service-on-boot-java-lang-securityexception-permiss – J. Vergeer Jan 03 '18 at 12:44
  • A well root does not seem to work with debugging. it then returns: - Broadcast completed: result =0 This then still does not explain why it's crashing on boot and then launching. Might not be a permission issue then.. – Tvt Jan 03 '18 at 12:54
  • Have you inspected the logcat output, which you get with `adb logcat -d > logcat.txt`? – J. Vergeer Jan 03 '18 at 13:07
  • Right yet again. Did find it in the .Txt not in the terminal. It says : java.lang.RuntimeException: Unable to instantiate receiver One.Android.BootBroadcastReceiver: java.lang.ClassNotFoundException: Didn't find class "One.Android.BootBroadcastReceiver" This should be it or the permissions. Thank you J. Vergeer I will mark you as the answer. If you know how to fix this immediately the comment is also appreciated. – Tvt Jan 03 '18 at 13:20
  • I think you shouldn't explicitly put broadcastreiceivers in the android manifest.xml. Xamarin puts them there itself based on the attributes. Xamarin will mangle the names, so that's probasably why android cannot find the class. On my own bootbroodcastreceivers I have these attributes: `[BroadcastReceiver(Enabled = true, Exported = true, Permission = "RECEIVE_BOOT_COMPLETED")] [IntentFilter(new[] { "android.intent.action.BOOT_COMPLETED" })]` – J. Vergeer Jan 03 '18 at 13:27
  • Ok you are my hero! :) This fixed it just remove it from the manifest and use the above code people. No more problems. – Tvt Jan 03 '18 at 13:41