0
votes

Background:
I am creating an internal mobile app with Xamarin.Forms, distributed via a weblink. I've had the Android and iOS up and running for a few days, but the request was made for push notifications. We decided to go with Pushwoosh to provide that service.

I have copied the example code from pushwoosh and modified it with our package names and keys, but for some reason I get the error:
The application could not be started. Ensure that the application has been installed to the target device and has a launchable activity (MainLauncher = true).
Additionally, check Build->Configuration Manager to ensure this project is set to Deploy for this configuration.

I should also note that Pushwoosh uses GCM, so it could also be related to that.

What I've tried:
1. My first step was obviously to check the Configuration manager. It is indeed set to Deploy and it is set to compile x86 (some other answers to other questions mentioned that fix)
2. I confirmed that the activity in my MainActivity.cs file is indead set with MainLauncher=true.
3. As recommended by other question/answers, I have removed the app from the virtual android. (in fact I completely reset the virtual device).
4. As mentioned in some of the GCM specific QAs, I have changed my package name to all lower case.

My relevant code:

[Activity(Label = "mobile", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
[IntentFilter(new string[] { "company.MESSAGE" }, Categories = new string[] { "android.intent.category.DEFAULT" })]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
    LocalMessageBroadcastReceiver mMessageReceiver;
    LocalRegisterBroadcastReceiver mRegisterReceiver;

    bool mBroadcastPush = true;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        mMessageReceiver = new LocalMessageBroadcastReceiver();
        mMessageReceiver.activity = this;

        mRegisterReceiver = new LocalRegisterBroadcastReceiver();
        mRegisterReceiver.activity = this;
        registerReceivers();

        PushManager manager = PushManager.GetInstance(this);
        manager.OnStartup(this);

        //Register for push!
        manager.RegisterForPushNotifications();

        checkMessage(Intent);

        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());
    }

    protected override void OnNewIntent(Intent intent)
    {
        checkMessage(intent);
    }

    public void checkMessage(Intent intent)
    {
        if (null != intent)
        {
            if (intent.HasExtra(PushManager.PushReceiveEvent))
            {
                doOnMessageReceive(intent.Extras.GetString(PushManager.PushReceiveEvent));
            }
            else if (intent.HasExtra(PushManager.RegisterEvent))
            {
                doOnRegistered(intent.Extras.GetString(PushManager.RegisterEvent));
            }
            else if (intent.HasExtra(PushManager.UnregisterEvent))
            {
                doOnUnregisteredError(intent.Extras.GetString(PushManager.UnregisterEvent));
            }
            else if (intent.HasExtra(PushManager.RegisterErrorEvent))
            {
                doOnRegisteredError(intent.Extras.GetString(PushManager.RegisterErrorEvent));
            }
            else if (intent.HasExtra(PushManager.UnregisterErrorEvent))
            {
                doOnUnregistered(intent.Extras.GetString(PushManager.UnregisterErrorEvent));
            }

            resetIntentValues();
        }
    }

    public void doOnRegistered(String registrationId)
    {
        // code to run if device has succesfully registered
    }

    public void doOnRegisteredError(String errorId)
    {
        // code to run if device failed to register
    }

    public void doOnUnregistered(String registrationId)
    {
        // code to run if device has succesfully unregistered
    }

    public void doOnUnregisteredError(String errorId)
    {
        // code to run if device failed to unregister properly
    }

    public void doOnMessageReceive(String message)
    {
        // code to run when device receives notification
    }
    private void resetIntentValues()
    {
        Intent mainAppIntent = Intent;

        if (mainAppIntent.HasExtra(PushManager.PushReceiveEvent))
        {
            mainAppIntent.RemoveExtra(PushManager.PushReceiveEvent);
        }
        else if (mainAppIntent.HasExtra(PushManager.RegisterEvent))
        {
            mainAppIntent.RemoveExtra(PushManager.RegisterEvent);
        }
        else if (mainAppIntent.HasExtra(PushManager.UnregisterEvent))
        {
            mainAppIntent.RemoveExtra(PushManager.UnregisterEvent);
        }
        else if (mainAppIntent.HasExtra(PushManager.RegisterErrorEvent))
        {
            mainAppIntent.RemoveExtra(PushManager.RegisterErrorEvent);
        }
        else if (mainAppIntent.HasExtra(PushManager.UnregisterErrorEvent))
        {
            mainAppIntent.RemoveExtra(PushManager.UnregisterErrorEvent);
        }

        Intent = mainAppIntent;
    }

    protected override void OnResume()
    {
        base.OnResume();

        registerReceivers();
    }

    protected override void OnPause()
    {
        base.OnPause();

        unregisterReceivers();
    }

    public void registerReceivers()
    {
        IntentFilter intentFilter = new IntentFilter(PackageName + ".action.PUSH_MESSAGE_RECEIVE");

        if (mBroadcastPush)
        {
            RegisterReceiver(mMessageReceiver, intentFilter);
        }

        RegisterReceiver(mRegisterReceiver, new IntentFilter(PackageName + "." + PushManager.RegisterBroadCastAction));
    }

    public void unregisterReceivers()
    {
        UnregisterReceiver(mMessageReceiver);
        UnregisterReceiver(mRegisterReceiver);
    }
}

1

        <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="com.company.mobile" android:versionCode="1" android:versionName="1.9.8">
    <!--GCM for Pushwoosh-->
    <permission android:name="PACKAGE_NAME.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="PACKAGE_NAME.permission.C2D_MESSAGE" />
    <uses-sdk android:minSdkVersion="15" />
    <application android:label="Company Mobile" android:icon="@drawable/icon">
        <meta-data android:name="com.google.android.gms.version" android:value="XXXXXXXX" />
        <meta-data android:name="PW_APPID" android:value="XXXXX-XXXXX" />
        <meta-data android:name="PW_PROJECT_ID" android:value="XXXXXXX-XXXXXX-XXXXXXX" />
        <!--GCM-->
        <receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="com.company.mobile" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

I will confess I am new to android development (but not .net or C#), so this could be something relatively obvious, but I am at a loss. I've looked through every question pertaining to this that I can find, and none of the solutions helped. Can anyone see what I am doing wrong?

1
Double check in your final manifest obj\Debug\android that there is not two main launchers set for different activities. Otherwise try to nuke your bin / obj.Jon Douglas

1 Answers

2
votes

I believe that in these two lines:

<permission android:name="PACKAGE_NAME.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="PACKAGE_NAME.permission.C2D_MESSAGE" />

that PACKAGE_NAME should be changed to your actual package name, which in your case is com.company.mobile(the package property in the <manifest> element).

so try:

<permission android:name="com.company.mobile.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.company.mobile.permission.C2D_MESSAGE" />