Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make C# Xamarin.Android app run at phone start-up?

I have been trying to get an app to run when phone starts, and eventually run app when I press KeyCode.CameraButton. I am using a class called BootReceiver, inherited from BroadcastReceiver. Here is my class:

namespace ColorPoint.Xamarin.XAndroid
{
    [BroadcastReceiver]
    [IntentFilter(new[] { Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
    public class BootReceiver : BroadcastReceiver
    { 
        public override void OnReceive(Context context, Intent intent)
        {
            Intent serviceStart = new Intent(context, typeof(MainActivity));
            context.StartActivity(serviceStart);                
        }
    }
}

At the moment the app restarts when broadcast received. I run this from adb command prompt to emulate boot up and phone restarts!

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED

Here is my manifest file, not sure if its correct at all!

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ColorPoint.Xamarin.XAndroid" android:installLocation="auto" android:versionCode="1" android:versionName="1.0">
    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
    <application android:label="Rexson Barcode Scanner" android:icon="@drawable/icon">
        <receiver android:name=".BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_INPUT_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <activity android:name="MainActivity" />
    <activity android:name="com.google.zxing.client.android.CaptureActivity" android:exported="false" android:windowSoftInputMode="stateAlwaysHidden">
        <intent-filter>
            <action android:name="com.phonegap.plugins.barcodescanner.SCAN" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
</manifest>

Need to go through this step by step but can't debug it very well, just so weird how phone resets when I emulate boot up!

I just tried a manual reboot and app tried to start but said unfortunately [myapp] has stopped working then phone reboots again.

Seems like it tries to open but crashes immediatley, then reboots phone.

Found this from another example but same thing, just reboots phone..

public override void OnReceive(Context context, Intent intent)
{
    if (intent.Action == Intent.ActionBootCompleted)
    {
        bool autoRestart = false;
        var sp = context.GetSharedPreferences("preferences", FileCreationMode.Private);
        autoRestart = sp.GetBoolean("autoRestart", false);
        if (autoRestart)
        {
            Intent serviceStart = new Intent(context, typeof(MainActivity));
            serviceStart.AddFlags(ActivityFlags.NewTask);
            context.StartActivity(serviceStart);
        }
    }
}
like image 398
Sam Ra Avatar asked Feb 08 '23 11:02

Sam Ra


1 Answers

You need to add the ActivityFlags.NewTask flag to the intent because you are launching an activity outside of an activity context.

The crash is because a Android.Util.AndroidRuntimeException is generated by the boot receiver.

The solution:

[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
public class BootReceiver : BroadcastReceiver
{ 
    public override void OnReceive(Context context, Intent intent)
    {
        Intent serviceStart = new Intent(context, typeof(MainActivity));
        serviceStart.AddFlags (ActivityFlags.NewTask);
        context.StartActivity(serviceStart);                
    }
}
like image 145
matthewrdev Avatar answered Feb 15 '23 09:02

matthewrdev