I want to show chromecast notification and lock screen from my app. Currently i'm using CastCampaignLibrary-android. As per the sample app initialized CastConfiguration and VideoCastManager in Application class.
String applicationId = getString(R.string.app_id);
CastConfiguration options = new CastConfiguration.Builder(applicationId)
.enableAutoReconnect()
.enableDebug()
.enableLockScreen()
.enableNotification()
.enableWifiReconnection()
.setCastControllerImmersive(true)
.setLaunchOptions(false, Locale.getDefault())
.addNamespace(NAMESPACE)
.setNextPrevVisibilityPolicy(CastConfiguration.NEXT_PREV_VISIBILITY_POLICY_DISABLED)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE, true)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_DISCONNECT, true)
.build();
VideoCastManager.initialize(this, options);
added the following lines in AndroidManifest.xml
<receiver android:name="com.google.android.libraries.cast.companionlibrary.remotecontrol.VideoIntentReceiver" />
<service android:name="com.google.android.libraries.cast.companionlibrary.notification.VideoCastNotificationService" />
<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService" />
when the application sent to background the remotecontrol notification not shown. Don't know whats wrong with my code. Help me to fix this.
MediaInfo Initialized as follow
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
movieMetadata.putString(MediaMetadata.KEY_TITLE, mEpisode.getmName());
movieMetadata.addImage(new WebImage(Uri.parse(mEpisode.getmBannerImageUrl())));
movieMetadata.addImage(new WebImage(Uri.parse(mEpisode.getmBannerSmallImageUrl())));
try {
MediaInfo mediaInfo = new MediaInfo.Builder(mEpisode.getmName() + ":" + mEpisode.getId())
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setContentType("video/mp4")
.setMetadata(movieMetadata)
.setCustomData(new JSONObject(customMessage))
.build();
mVideoManager.loadMedia(mediaInfo, false, 0);
} catch (Exception e) {
e.printStackTrace();
}
Note: I'm using CustomReceiver for casting.
Related
I would like my notifications to include the contact's image.
I am using NotificationCompat and MessagingStyle do display chat messages for contacts.
This works when using the .setIcon on the person, but the image is square, so I would like to use the setUri but it doesn't display the image, instead I see the contact's first initial in a circle.
Here is the code I'm using for the notification.
Person person = new Person.Builder()
// .setIcon(contactIcon)
.setName(displayName)
.setUri(contentLookupURI)
.setKey(contactDetail)
.build();
NotificationCompat.MessagingStyle chatMessageStyle = new NotificationCompat.MessagingStyle(person);
NotificationCompat.MessagingStyle.Message notificationMessage = new
NotificationCompat.MessagingStyle.Message(
contentText,
System.currentTimeMillis(),
person
);
chatMessageStyle.addMessage(notificationMessage);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, NOTIFICATION_MESSAGES_CHANNEL_ID)
.setSmallIcon(icon) // notification icon
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setStyle(chatMessageStyle)
.setOnlyAlertOnce(true)
.setContentTitle(displayName);
And for the contact URI used in the .setUri I'm using a library to obtain the contact id and lookupkey then use the method:
contactLookupURI =
ContactsContract.Contacts.getLookupUri(contactsList.get(0).getId(),
contactsList.get(0).getLookupKey());
Which produces this: content://com.android.contacts/contacts/lookup/3118r4-2F294339313F5B16.3789r5-2F294339313F5B16/6 which looks correct to me.
I'm not sure how new this form of the MessagingStyle method is as I can't find many examples of it's usage with a Person object.
Here is a solution for those using Remote URL with Glide
Step 1: Get Bitmap from Remote URL
private fun getAvatarFromUrl(photoUrl: String): Bitmap? {
return try {
val futureTarget = Glide.with(this)
.asBitmap()
.load(photoUrl)
.submit()
futureTarget.get()
} catch (e: Exception) {
Timber.e(e)
null
}
}
Step 2: Set Bitmap as Person.Icon
val avatar = getAvatarFromUrl(user.avatar)
val sender = Person.Builder()
.setName(msg.from?.name)
.setIcon(IconCompat.createWithBitmap(avatar))
.setImportant(true)
.build()
If you want to use resource id instead of bitmap:
val person = Person.Builder()
.setName("Name")
.setKey("Key")
.setIcon(IconCompat.createWithResource(this, R.drawable.ic_resource)).build()
I'm trying the implement cast support to my androapp, when I use normal non live links such as MP4 and even HLS non live stream it works perfectly but, when I use live stream the stream just won't play at the chromecast.
This is how I create my MediaInfo:
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
movieMetadata.putString(MediaMetadata.KEY_TITLE, "Test");
MediaInfo mediaInfo = new MediaInfo.Builder("HLS link")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE).setContentType(MimeTypes.APPLICATION_M3U8)
.setMetadata(movieMetadata).build();
This is how I load the items:
castPlayer.loadItem(new MediaQueueItem.Builder(setCastMedia()).build(), 0);
This is the logcat I get:
W/MediaControlChannel: received unexpected error: Invalid Request. W/MediaQueue: Error fetching queue item ids, statusCode=2100, statusMessage=null
Any ideas what I'm doing wrong?
Happens the same with TS type streams...
With the following code, you can cast live streams using ExoPlayer.
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_TV_SHOW);
movieMetadata.putString(MediaMetadata.KEY_TITLE, "Title");
MediaInfo mediaInfo = new MediaInfo.Builder("your_link.m3u8")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE)
.setContentType(MimeTypes.APPLICATION_M3U8)
.setMetadata(movieMetadata)
.build();
MediaQueueItem mediaQueueItem = new MediaQueueItem.Builder(mediaInfo).build();
castPlayer.loadItem(mediaQueueItem, mediaQueueItem.getMedia().getStreamDuration());
castPlayer.setPlayWhenReady(true);
My application has Videos, Audios and Photos. I'm successfully able to cast all three of them. However when I cast an image, the minicontrollerfragment, Notification and ExpandedControllerActivity shows video controls.
When I click play/pause button it just keeps spinning round for photo.
Is there a way where I can disable it for images? I looked up everywhere but for some reason I was not able to find a single example of Photo.
Any help would be appreciated.
Thank you.
Here is the code for CastOptionsProvider.
#Override
public CastOptions getCastOptions(Context context) {
NotificationOptions notificationOptions = new NotificationOptions.Builder()
.setTargetActivityClassName(ExpandedControlsActivity.class.getName())
.setActions(Arrays.asList(MediaIntentReceiver.ACTION_REWIND,MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK, MediaIntentReceiver.ACTION_FORWARD, MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{1,2,3})
.build();
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.setExpandedControllerActivityClassName(ExpandedControlsActivity.class.getName())
.build();
CastOptions castOptions = new CastOptions.Builder()
.setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
.setCastMediaOptions(mediaOptions)
.build();
return castOptions;
}
This is how I cast an image:
MediaMetadata photoMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_PHOTO);
photoMetadata.putString(MediaMetadata.KEY_TITLE, "Casting to " + mCastSession.getCastDevice().getFriendlyName());
photoMetadata.addImage(new WebImage(Uri.parse(photoItem.getImageUrl())));
MediaInfo mediaInfo = new MediaInfo.Builder(photoItem.getImageUrl())
.setContentType("image/jpeg")
.setMetadata(photoMetadata)
.setStreamDuration(0)
.setStreamType(MediaInfo.STREAM_TYPE_NONE)
.build();
MediaLoadOptions mediaLoadOptions = new MediaLoadOptions.Builder()
.setAutoplay(true)
.setPlayPosition(0)
.build();
RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(mediaInfo, mediaLoadOptions);
You can use Default Media Receiver (CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID) to give it a try as a default receiver, otherwise you need to create your own.
Inside your CastOptionProvider, create a CastOptions like below
new CastOptions.Builder()
.setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
.setCastMediaOptions(mediaOptions)
.build();
I am using CastCompanionLibrary-android for chromecast integration.
I am going to show few methods of chromecast integration
first one is configuration initalization in application cast
private void initchromecast() {
String applicationId = getString(R.string.app_id);
// Build a CastConfiguration object and initialize VideoCastManager
CastConfiguration options = new CastConfiguration.Builder(applicationId)
.enableAutoReconnect()
.enableCaptionManagement()
.enableDebug()
.enableLockScreen()
.enableNotification()
.enableWifiReconnection()
.setCastControllerImmersive(true)
.setLaunchOptions(false, Locale.getDefault())
.setNextPrevVisibilityPolicy(CastConfiguration.NEXT_PREV_VISIBILITY_POLICY_DISABLED)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_REWIND, false)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE, true)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_DISCONNECT, true)
.setForwardStep(10)
.build();
VideoCastManager.initialize(this, options);
}
and TO pass meta data
private void loadRemoteMedia(int position, boolean autoPlay) {
MediaMetadata mediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
mediaMetadata.putString(MediaMetadata.KEY_TITLE, TITLE);
MediaInfo mediaInfo = new MediaInfo.Builder(
path)
.setContentType("application/x-mpegURL")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE)
.setMetadata(mediaMetadata)
.setStreamDuration(MediaInfo.UNKNOWN_DURATION)
.build();
mCastManager.startVideoCastControllerActivity(getActivity(), mediaInfo, position, autoPlay);
}
Now my question is in below cod when i pass CastCompanion sample id 4F8B3483 ,i can successfully cast most of the videos but when i put my sample application reciver id some of the videos which works with their id does not work with mine.
For example http://iptvcanales.com/xw/peliculas.php?movie=006 url works with CastCompanion reciver id but not with mine id in my code.
Is there any way to use extras with the MediaMetadataCompat from the support library?
Using the MediaMetadata I can set extras, but with the compat one I cannot.
Hope it helps.
import android.support.v4.media.session.MediaSessionCompat;
private MediaSessionCompat mMediaSession;
//init mediasesson
mMediaSession = new MediaSessionCompat(getApplicationContext(), "AudioPlayer",new ComponentName(this, HeadsetNotificationBroadcast.class), null);
//set the metadata
mMediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, getSongDataHelper().getAlbumArt())
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, getSongDataHelper().getArtist())
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, getSongDataHelper().getAlbum())
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, getSongDataHelper().getTitle())
.build());
I have copy-pasted our code. Please tell me if you can understand it.
private static MediaInfo toCastMediaMetadata(MediaMetadataCompat track, JSONObject customData) {
MediaMetadata mediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
mediaMetadata.putString(MediaMetadata.KEY_TITLE, track.getDescription().getTitle().toString());
mediaMetadata.putString(MediaMetadata.KEY_SUBTITLE, track.getDescription().getSubtitle().toString());
mediaMetadata.putString(MediaMetadata.KEY_ALBUM_ARTIST, track.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST));
mediaMetadata.putString(MediaMetadata.KEY_ALBUM_TITLE, track.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
WebImage image = new WebImage(new Uri.Builder().encodedPath(track.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)).build());
// First image is used by the receiver for showing the audio album art.
mediaMetadata.addImage(image);
// Second image is used by Cast Companion Library on the full screen activity that is shown
// when the cast dialog is clicked.
mediaMetadata.addImage(image);
return new MediaInfo.Builder(
track.getDescription().getExtras().getString(MutableMediaMetadataCompat.
METADATA_KEY_TRACK_SOURCE)).setContentType(
MIME_TYPE_AUDIO_MPEG).setStreamType(MediaInfo.STREAM_TYPE_BUFFERED).setMetadata(mediaMetadata).setCustomData(customData).build();
}