Recently posted a question how to get the current song playing from the music app spotify, there seems by the response that there are no easy way of doing this.
The android lockscreen at least in 4.0+ will show the current song and works with almost any music player including spotify. So my question is how does the lockscreen get this information?
On Android 4.0 and 4.1, the portion of the lockscreen you are seeing is called the "remote controls". You can call registerRemoteControlClient() to supply information to it.
On Android 4.2+, you are welcome to create your own lockscreen-capable app widget instead.
Through a broadcast receiver, you can create a broadcast receiver and define filters for it in the manifest. Then all the music applications that send this broadcast will trigger your onReceive method, along with the information sent from the app.
EDIT:
Intent intent = new Intent("com.android.music.playstatechanged");
intent.putExtra("playing", (mState & FLAG_PLAYING) != 0);
if (song != null) {
intent.putExtra("track", song.title);
intent.putExtra("album", song.album);
intent.putExtra("artist", song.artist);
intent.putExtra("songid", song.id);
intent.putExtra("albumid", song.albumId);
}
sendBroadcast(intent);
This is the code in the stock player used to send broadcast, Look into broadcast receiver and you able be able to figure out how to get the data needed.
Also You will need to find the filter for spotify, AFIK This one works for soptify.
"com.android.music.metachanged" or look here http://pastebin.com/ukfPnZwg
Related
I would like to cause an alarm on a remote iphone/android device when the app is running or not running.
How do I achieve it ?
I can only think of Whatsapp/Skype when there is incoming call, its ringing.
Or would it be possible to cause the phone to play a looping alarm sound on Push Notification.
Another very clear example is "Find My iPhone" app which can trigger a loud alarm to an iPhone.
How can I achieve this programmatically on ios and android ?
Its possible using FireBase Notification Services with JobService & FirebaseMessagingService.
Download the FireBase samples from here .Run module "messaging".I tested it and I was able to receive the notification , even in the Application killed state.
To manage events periodically/scheduled you must implement & deploy your Server somewhere.You can also check FireBase Functions (Beta) to easily implement Server.
To show something (Alaram/UI like calling screen) to user start your custom Activity while receiving FireBase notification.Override handleIntent from FirebaseMessagingService.So that you can receive data from your killed/idle Application.
FireBase Service is System Service & it will be always running.Please have a read.
Code snippet
#Override
public void handleIntent(Intent intent) {
super.handleIntent(intent);
// Get Data here
Log.d(TAG, "intent.."+intent.getExtras());
Intent intent1=new Intent(this,MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
Note : Some devices (Eg; ASUS's Mobile Manager) may reject to start Application's receiver while , Notification arrives.In that case please provide appropriate permissions.
1 possible solution could be schedule alarm event with repeatInterval on receiving push notification.
EDIT
We can create custom notifications using Notification extensions.They are called as soon as notification arrives & we can present customized view with image/video downloading. So you can try there to schedule events.
For iOS, you will need a server to deliver a push notification to your app, where the notification references a custom audio alert to be played. The audio alert has to be included within the app's bundle as stated in Apple docs.
This alert can't be longer than 30 seconds. If you want the alert to be played longer, you can send send another push notification times roughly 30-seconds after and stop sending the alert when a) user open the app or b) you've reached the maximum threshold.
It's generally not good practise to send multiple notification containing the same payload, unless there is a good reason.
I would suggest splitting up this question into two: one for iOS, and another for Android.
I want to be able to detect when an application is opened and notify the user of something at the moment related to that same application but I don't know how to do this.
The user opens my app
I intent the service (background / foreground) and it successfully starts
Whenever the user opens another application I want to "catch it" and present a notification to the user
How can this be made? Are there any event listeners i need to use? Thank you very much.
If you are trying to catch "open app" intents in general, then it depends on how the app defined the intent. If it specified a class (explicit intent) then it will generally not be visible to your app unless the device is rooted, for example.
Implicit intents are broadcast and you simply need to define an intent filter in order to receive them. These are intents that allow Android and/or the user to select the appropriate app target based on data sent with the intent.
There are both useful and malicious motivations to do the kind of thing you are asking about. Read this:
Android Intent Security
And also the posted comment on learning about intents overall.
This is really simple. Here I am trying to figure out the solution. When your app goes on onPause() state then broadcast a message using BroadcastReceiver. On the other hand in another app just register for that broadcast.
I'm trying to build an Android app that uses a broadcast receiver to detect when music playback starts, and then offer gesture control to trigger sending a skip track intent back out.
To begin, I just want to set the receiver up to trigger a notification when audio playback starts so that I can check this concept will work. I've declared a service and a receiver in my manifest file, and I've created a service class that (hopefully) creates a notification via onCreate().
I've crawled a tonne of documentation though and can't seem to find the correct intent to listen in for with my receiver. Surely something exists for this?
Regards.
It turns out there's a new security feature in Android 3.1 and above, where broadcast receivers don't register until the user manually opens the app at least once. Since I was trying to build a service-only app that had no UI to be opened, this was preventing all my intent listener attempts from working.
I've amended to have a splash-screen activity and now everything is working as I'd hoped. I'm now working to collate a list of player-specific intents to work from but for those trying to build something similar, com.android.music.playstatechanged seems to be the best start. This one is triggered by the default player (Google Play Music) when music either starts, pauses, or resumes and bundles itself with extra data including a boolean 'playing' property to differentiate between the play and pause states.
Essentially, this is the core receiver I'm now using. Have fun!
public class MainReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start the service when music plays, stop the service when music ends.
if(intent.hasExtra("playing")) {
if(intent.getBooleanExtra("playing", false)) {
Intent service = new Intent(context, MainService.class);
context.startService(service);
} else {
Intent service = new Intent(context, MainService.class);
context.stopService(service);
}
}
}
}
Surely something exists for this?
There are thousands of music players. None are obligated to broadcast anything, let alone information about tracks. And none are obligated to allow you to "skip track" via any means.
You are welcome to search for specific music players that offer a documented and supported API for this sort of thing.
I have a requirement in an android app, where the app should open automatically in the following 2 cases
-when the user with android device reaches some particular location.
-When the app receives some push notification from the server.
Im new to android, Is there any possibility that the app opens up automatically in the above 2 cases.
For location based app use Android's LocationManger
This class provides access to the system location services. These services allow applications to obtain periodic updates of the device's geographical location, or to fire an application-specified Intent when the device enters the proximity of a given geographical location.
For Push message use GCM
I bumped into this problem (the second one) a few days ago and came up with a "temporary" solution (maybe not the cleanest and coolest). Even though this question is old, somebody might have the same problem and find some value here.
Regarding your second question on how you can open and android app automatically when a push notification is received, from inside the service class just put this:
Intent dialogIntent = new Intent(this, myActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
Keep in mind that the code from above will cut off the notification sound so it might be a good idea to check the Screen state and play some sound if it's locked:
/* Check if the device is locked, play ring tone and vibrator */
if (!(((PowerManager) getSystemService(Context.POWER_SERVICE)).isScreenOn())){
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
Sound = MediaPlayer.create(getApplicationContext(), R.raw.sound);
try { Sound.start(); }
catch(Exception e){ Log.i("intentService", "Error Playing sound");}
vibrator.vibrate(3000);
}
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
Also, don't forget to release mediaplayer !! just do some research and you'll find an answer, there are different ways but one way could be to wait until the sound is played:
Sound.isPlaying()
And then release:
Sound.release()
P.S: You can set the notificationSound to null and remove the "if" condition so the ringtone will always be played (even when the screen is ON and the app is opened automatically)
setSound(null)
I am trying to create widget that can control music playback. Basically the same as the widget that appears on lockscreen when music is playing. (Which as I read somewhere, is connected to the Remote Control Client - is that true?) My problem:
I was able to create Media Buttons using the following code
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
synchronized (this) {
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT));
sendOrderedBroadcast(i, null);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT));
sendOrderedBroadcast(i, null);
First, I thought this was the solution used also in the lockscreen widget. But then I noticed that this solution works only with some music players, but certainly not with all that can be controlled by default lockscreen widget(f.e. DoubleTwist responds to lockscreen widget, but not to my Media Buttons). So I spent last few days digging in the Android sources, Logcat outputs and various forums, but I was not able to find any difference between intents called by my buttons and by buttons on the lockscreen widget.
What exactly is lockscreen widget doing to control apps that are not listening to my Media Button intents?
Or, can somebody at least help me to find the source code of this widget? I tried default music app, audio service, remote control client, widgets, but I can't find it anywhere.
While working on my app I've actually found how to implement your own RemoteControlDisplay which can control music player the same way the lockscreen does.
Basically, you extend IRemoteControlDisplay$Stub, which sends messages to special handler, this handler updates metadata and thing. Then you register your own class extended from IRemoteControlDisplay$Stub by calling to AudioManager#registerRemoteControlDisplay().
And then you unregister it by calling AudioManager#unregisterRemoteControlDisplay().
It's fairly complex, but I've wrote an article on how to this.
I've published it on XDA, check it here:
http://forum.xda-developers.com/showthread.php?p=44513199
What exactly is lockscreen widget doing to control apps that are not listening to my Media Button intents?
Based on the docs, it is doing what those apps asked it to do -- execute the PendingIntent supplied to it by the RemoteControlClient. Notably:
it will not be an ordered broadcast, as PendingIntent does not support it
it may be one targeted at the specific media client, via setComponent()
it may or may not have the extras you are trying (incorrectly) to use
(The "incorrectly" part is because you are sending two ACTION_UP operations some of the time, as sendOrderedBroadcast() is asynchronous with respect to the calling thread, and therefore you may be replacing your ACTION_DOWN with ACTION_UP before the first ordered broadcast is sent. You are better off using a separate Intent object for each broadcast.)
However, while the docs claim that the PendingIntent needs to be set up for ACTION_MEDIA_BUTTON, I would not be surprised if this is a documentation error, and that no specific action is needed, as setComponent() is sufficient to deliver the broadcast to the right receiver.