1

I'm writing Unity mobile application which uses Android native plugin. This plugin creates background location service and notifies user when he approaches specific points on map (which are architectural monuments btw).

So Service sends push notification, and when users clicks on this notification, the app should be opened from place it paused earlier.

To create this notification, I wrote next code:

Intent intent = new Intent(this, UnityPlayerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);

Notification n = new Notification.Builder(this)
        .setContentTitle(title)
        .setContentText(text)
        .setSmallIcon(R.drawable.app_icon)
        .setDefaults(Notification.DEFAULT_ALL)
        .setPriority(Notification.PRIORITY_HIGH)
        .setContentIntent(pIntent)
        .setAutoCancel(true).build();

mNotificationManager.notify(notificationID, n);

The trick is that Unity uses one Activity (UnityPlayerActivity) during app lifecycle. But I must build standalone .jar file with my service which cannot use UnityPlayerActivity class because it don't know about that.

I can get current Activity instance only on runtime and work with it while starting service.

Question: How can I get Activity.class from Service while creating Intent?

Thank you for response.

UPD: I cannot put my service into Intent constructor. The second parameter in Intent constructor must be Activity.Class which should open when user clicks on notification. If I put Service.Class there, nothing opens.

So I need to put as a second parameter UnityPlayerActivity instance which I can get only on runtime, but don't know how to import it into service.

Ted Romanus
  • 582
  • 2
  • 10
  • 27
  • `Service extends Context`. Why do you need an Activity? – OneCricketeer Feb 28 '17 at 21:52
  • So you have `new Intent(this, this.getClass());` – OneCricketeer Feb 28 '17 at 21:59
  • @cricket_007 Oh, sorry, it's wrong answer. The second parameter in `Intent` constructor must be that `Activity.Class` which should open when user clicks on notification. If I put `Service.Class` there, nothing opens. – Ted Romanus Feb 28 '17 at 22:00
  • @cricket_007 So I need to put as a second parameter `UnityPlayerActivity` instance which I can get only on runtime, but don't know how to import it into service. – Ted Romanus Feb 28 '17 at 22:05
  • `Class.forName("package.name.UnityPlayerActivity")`? – OneCricketeer Feb 28 '17 at 22:28
  • @cricket_007 it throws `LinkageError` if dependency is absent. Thank you for trying help me! – Ted Romanus Mar 01 '17 at 07:54
  • This is a duplicate....Start with with [Activity](http://stackoverflow.com/questions/38368762/start-android-service-from-unity3d-code/38369904#38369904) or start service with [Context](http://stackoverflow.com/questions/38372910/unity3d-android-plugin-unable-to-start-service/38538715#38538715) – Programmer Mar 01 '17 at 08:31

1 Answers1

0

I implemented such thing using intent putExtra method.

Unity side:

public class GPSServiceAndroidTest : MonoBehaviour {

    private AndroidJavaObject activity = null;
    private AndroidJavaObject launcher = null;

    void Start () {

        using(AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")){
            activity = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
        }

        using(AndroidJavaClass pluginClass = new AndroidJavaClass("com.softserve.gpstest.Launcher")){
            if(pluginClass!=null){
                launcher = pluginClass.CallStatic<AndroidJavaObject>("instance");
                launcher.Call("startTustanService", activity);
            }
        }
    }
}

Launcher class:

public class Launcher {

    private static Launcher instance;

    private Launcher() {
        Launcher.instance = this;
    }

    public static Launcher instance() {
        if(instance == null) {
            instance = new Launcher();
        }
        return instance;
    }

    public void startTustanService(Activity currentActivity){
        Intent notificationIntent = new Intent(currentActivity, currentActivity.getClass());
        startServiceIntent.putExtra("notificationIntent", notificationIntent);

        currentActivity.startService(new Intent(currentActivity, TestService.class));
    }
}

And then get this intent in Service's onStartCommand method:

mNotificationIntent = intent.getParcelableExtra("notificationIntent");
Ted Romanus
  • 582
  • 2
  • 10
  • 27