I’m developing an app, and one of its features is the ability to play music. I would like my app to continue to play music when, for instance, the user goes to a lock screen. Is there any way to do this in Unity?
I’m not sure if I’ll have to step out of Unity and learn how to write Android plugins. If that is the path I need to take, any pointers for how I might get started?
I’m honestly not sure if you can do this from within Unity at all, but you can at least try AudioSource’s ignoreListenerPause. On PC, that will continue to play audio even when the app is not in focus.
I still need to poke around to see if I have all of the features I need, but I do have my Unity app playing music that continues on the lock screen. Some of this may be obvious to folks with more Android experience, but I’ll explain it for other noobs like me, at least so people will know what to google for.
Android has a notion of Activities and Services. Services can continue to run when you go to the lock screen, or minimize your application, but activities will run when the application has focus. Unity runs as an Activity.
I created a new Java project in Eclipse, and created a new Activity that extends UnityPlayerActivity (I had to copy Unity’s classes.jar into my project). I also created a Service class that plays music using Android’s MediaPlayer object. My Activity mostly defers to the behavior of its base class, but it kicks off my Service, and provides hooks into it’s PlaySong methods.
I created a class in my Unity project that talks to my Activity. My Java Activity maintains a static reference to the Activity that just kicked off, and you can grab that static reference and call instance methods on it, letting me talk to my service.
I had to export my Java project as a jar file and put it in Assets/Plugins/Android, and I had to update my Android manifest file to run my activity instead of Unity’s and to kick off my service. I also had to add several permissions to the manifest, in my case, READ_EXTERNAL_STORAGE and WAKE_LOCK.
It was actually pretty easy once I learned the vocabulary of things.
Mark can you expound on any of that? Some of us aren’t that advanced simply because we’ve never had to deal with jars and very little xml. What you said makes sense, but it’s begging for more info
It is true when you’re working on Unity, you develop at a level where many low level things not need to be known, but if you need to create a new activity, be included in your AndroidManifest thru Unity, compiled, linked it, and invoked it from the code, that’s not going to be as easy as see here some piece of code. Unless you want something to do copy & paste. My suggestion is to take a look to the Unity documentation about how to develop Plugins for Unity. That step will forced to you to understand the link between the Xcode (iOS), and Eclipse (Java-Android) tools, which you will need to develop plugins. For people, as me, who has developed games or apps, in Xcode or Eclipse for Android, before jump to Unity this level of understanding is easier, but I understand the limitations for others.
That would be a good start point.
That’s what i did:
I’ve created a BroadcastReceiver to set a bool with screen state. Then, on UnityPlayerActivity, at onCreate Method, instantiated a IntentFilter to get the Screen On / Off action and BroadcastReceiver as well.
At onPause method, i check if it was called by a screen On / Off action, if so, only super on Pause is executed, if not,
mUnityPlayer.pause() is executed as well.
Maybe not the best practice, but works!
BroadcastReceiver class:
public class ScreenStateReceiver extends BroadcastReceiver {
public static boolean setUnityPlayerOnPause = false;
@
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenStateReceiver();
registerReceiver(mReceiver, filter);
moveTaskToBack(true);
mUnityPlayer = new UnityPlayer(this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
}
@ protected void onPause()
{
super.onPause();
if (!ScreenStateReceiver.setUnityPlayerOnPause) {
System.out.println(“SCREEN OFF OR LOCKED”);
} else {
// THIS IS WHEN ONPAUSE() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
mUnityPlayer.pause();
}
}