I have a very strange problem with both YouTubePlayerView and the YouTubePlayerFragment.
My app is an alarm clock and i want my users to be able to set a youtube video as their alarm.
Here is the alert fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="#dimen/standard_button_size"
android:gravity="center_vertical">
<TextView
android:id="#+id/tvSep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:text="-"
android:textColor="#color/white_secondary_text"
android:textSize="#dimen/title_bold" />
<TextView
android:id="#+id/tvNotificationHourYoutube"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_toStartOf="#id/tvSep"
android:gravity="end"
android:text="7:00"
android:textColor="#color/white_secondary_text"
android:textSize="#dimen/title_bold" />
<TextView
android:id="#+id/tvAlarmLabelYoutube"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="#id/tvSep"
android:gravity="center"
android:maxLines="1"
android:text="Wake up"
android:textColor="#color/white_secondary_text"
android:textSize="#dimen/title_bold" />
</RelativeLayout>
<fragment
android:name="com.google.android.youtube.player.YouTubePlayerFragment"
android:id="#+id/ypvAlert"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginBottom="#dimen/half_activity_vertical_margin"
android:layout_marginTop="#dimen/half_activity_vertical_margin"
android:minWidth="200dp"
android:minHeight="110dp"/>
<LinearLayout
android:id="#+id/llYoutubeButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatButton
android:id="#+id/btnStopAlarmBigYoutube"
android:layout_width="0dp"
android:layout_height="#dimen/standard_button_size"
android:layout_weight="1"
android:backgroundTint="#color/dark_primary_accent"
android:text="#string/stop_alarm"
android:textColor="?android:colorBackground"
android:textSize="#dimen/title_bold"
android:visibility="visible" />
<Button
android:id="#+id/btnSnoozeYoutube"
android:layout_width="0dp"
android:layout_height="#dimen/standard_button_size"
android:layout_weight="1"
android:text="#string/snooze"
android:textSize="#dimen/title_bold" />
</LinearLayout>
</LinearLayout>
And this is the layout xml file of the activity that contains the fragment:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I tested the alarm on 2 smartphones (Nexus 5 and huawei) and on one tablet (Asus). At first i tried to force the app to be on landscape if it is a youtueb alarm by using:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
The thing is that on the nexus 5 the video is almost always stops after 1 second. If i set an alarm for 2 minutes from now it will play ok for 50% of the attempts, and if i set an alarm for tomorrow morning it always stops after 1 second. On the Huawei it almost always play ok and on the tablet it's 50/50.
This is the message i get when the video stops:
YouTube video playback stopped due to unauthorized overlay on top of player.
The YouTubePlayerView is not contained inside its ancestor
android.widget.FrameLayout{89c240f V........ ......I. 0,0-0,0}. The
distances between the ancestor's edges and that of the YouTubePlayerView is:
left: 0, top: 0, right: 0, bottom: 0 (these should all be positive).
I don't have any FrameLayout on the alarm alert fragment but i have a FrameLayout on the activity xml file that contains the fragment so i replaced the FrameLayout with fragment, so the xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/articles_list"
android:name="com.sux.alarmclock.AlarmNotificationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/fragment_alarm_alert_material_youtube" />
But i still get the same error message even though now there is not any FrameLayout in the xml. I have interstitial ads in my app so i canceled the ads but the error still occurs.
So i tried to set the activity to portrait instead of landscape and now it's working on the nexus and on huawei most of the times but almost always stops on the tablet after 1 second.
I also noticed that when i include the YouTubePlayerFragment inside my Activity , or when i extend the YouTubeBaseActivity, every time i start the activity, it creates 2 instances of the activity instead of 1, regardless to the flags i add to the intent or the launch mode (I don't know if it has something to do with the issue)
I can play YouTube on WebView using the RTSP links, but in order to extract the RTSP link i need to use this project:
https://github.com/HaarigerHarald/android-youtubeExtractor
And the developer told me that they are extracting the RTSP urls through backdoor which might be aganist the Yotube policies.
I want the YouTube player to work on all devices all the times. Does anyone has an idea?
These are the possible reasons for this issue. Please check the logcat to find out which is your issue
UNAUTHORIZED_OVERLAY - Other views overlapping with youtube view
PLAYER_VIEW_TOO_SMALL - Youtube view too small
USER_DECLINED_RESTRICTED_CONTENT - Trying to play restricted content
BLOCKED_FOR_APP - Certain videos are blocked for app.
When i had the issue, it was because of UNAUTHORIZED_OVERLAY.
<RelativeLayout
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/scImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<FrameLayout
andriod:id"#+id/youtube_parent
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
The imageview was below the framelayout which had the youtube player. I moved it to the top (The final, fixed layout is the example above) and it started to work.(I tried setting the Zindex it didnt help).
Based from this documentation, be noted that while videos are playing, View has a minimum size of 200x110 dp. If you make the view any smaller, videos will automatically stop playing. Also, it is not permitted to overlay the view with other views while a video is playing.
Additional reference which might help:
Pausing youtube video after 1-2 seconds
It is not possible to add buttons as overlays above the player as specified by Google, otherwise the player will stop.
Padding is also not supported on YouTubePlayer.
To overlay your view on video, I will recommend you to use ExoPlayer, It is not part of the android sdk, but it's recommended by google and included in android developer documentation :
http://google.github.io/ExoPlayer/
Views overlayed above YouTubePlayerFragment or YouTubePlayerView in the layout hierarchy cause playback to pause immediately
Overlays on top of any of our YouTube players (including the YouTube Android Player) are not supported. When an overlay is detected, playback stops and the log contains information helpful in debugging the issue. We do support Action Bar overlays, take a look at this demo to learn more: https://developers.google.com/youtube/android/player/sample-applications#Overlay_ActionBar_Demo.
Hope this helps!
Related
I am working on an Android TV Application using leanback library. I was able to integrate VideoPlaybackActivty using Exoplayer. One of my requirement is when there is about 1 minute left for current video to end, I need to make a Rest call to the server to fetch next video to play and than I would like to show the Next Video thumbnail at the bottom right of the screen. Very much similar to the Netflix functionality of "Next Episode playing in....".
My questions is, how can I find out if there is just 1 minute left in the video. Also, how can I show that "Play Next overlay" on the screen? Currently my activity_videoplayback.xml look as follows.
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextureView
android:id="#+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<fragment
android:id="#+id/playback_controls_fragment"
android:name="com.myapp.ui.playback.VideoPlaybackFragment"
android:tag="#string/playback_tag"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="#+id/stream_progressbar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminateTint="#color/orange"
android:visibility="gone" />
</merge>
Really appreciate the help.
ExoPlayer does not provide a progress update listener at the moment - the reason cited is that it would eat up too much CPU to keep raising progress events. See the discussion on the ExoPlayer issue tracker here and note that the issue is considered closed at this time (Feb 2021):
https://github.com/google/ExoPlayer/issues/3980
The suggested approach is to build a handler to poll the player and query the current position using player.getCurrentPosition().
For completeness, in case you are also looking at HTML5 video, in a WebView for example, you can check the video length and then use the progress event to check for 1 second from the end - this is 'standard' HTML5 and javascript so should work with any framework using the HTML5 video element.
The code might look something like this:
const yourVideo = document.querySelector('yourVideoID');
//Create the event handler
function handleProgressEvent(event) {
//Check if video has reached last 10 seconds
if (yourVideo.currentTime > (yourVideo.duration - 10.0)) {
// DO your work to prepare the next video here
}
}
// Add the event listener to your video
yourVideo.addEventListener('progress', handleProgressEvent);
I'm trying to write a Camera app in android. I wanted to use a SeekBar for zoom in/zoom out of the camera. Here goes my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
>
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<SeekBar android:id="#+id/sliderZoom"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center"
/>
</LinearLayout>
<RelativeLayout
android:orientation="vertical"
android:layout_width="50dp"
android:layout_height="fill_parent"
android:background="#000000">
<ImageButton
android:layout_height="50dp"
android:layout_width="wrap_content"
android:src="#drawable/flash"
android:scaleType="fitXY"
android:layout_alignParentTop="true"
android:onClick="onFlashClick" />
<ImageButton
android:layout_height="50dp"
android:layout_width="wrap_content"
android:src="#drawable/zoom"
android:scaleType="fitXY"
android:layout_centerInParent="true"
android:onClick="onZoomClick" />
</RelativeLayout>
</LinearLayout>
If I remove either of the ImageButton, my SeekBar moves smoothly. But it doesn't move smoothly if I've both of the ImageButton. I tried to run the app both in portrait and landscape mode. The problem remains same in both mode.
How can I solve it?
EDIT: As per some comment, I feel to add some more information. Right now there is no event handler for the SeekBar. It doesn't zoom in or zoom out the camera. It is just one simple SeekBar' with maximum value set to some random integer. For my case I tried 5 to 500. In every case I've the problem. By smooth move I mean when I try to slide it with touch it should move easily, should not halt. If there is one ImageButton, I can slide the SeekBar pointer left/right without any problem. But if there are two ImageButton, the pointer doesn't move that easily. It looks like each time the the pointer is moved by one unit, some time consuming operation runs on the UI thread which halts the UI from capturing touch event. Though the fact is there is no time consuming operation in UI thread. There is not a single function written for any type of computation. I didn't even add the camera preview in the FrameLayout or camera isn't initialized
More Edit: I just found out one interesting turn of event. If the image source is same image(doesn't matter which one) for both ImageButton, then it works perfectly. But if I've two different image for two ImageButton, then it starts causing the problem. I hope this new information will help to get some idea of what is happening. The resolution of the images are 1299x1299 and less than 40kb in size.
Actually this is not a problem. Camera zoom level is not so much. Basically zoom level is 5-7. So, as you have used SeekBar as your zoom controller it means your seekbar's max level is 7(suppoose). For this reason, it buffer per level when you pull the bar.
For your test, you can set value seekBar.setMax(30) and then pull your seekbar. I hope you will get that smooth
I am working on a scrollview that contain a webview, it works perfect on the 2.3, 4.1 , but when I try it on the 4.4 emulator, it show
View too large to fit into drawing cache, needs 5744640 bytes, only 3932160 available
The webview is just blank.
And it is the layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="#+id/newsTitle"
android:textSize="18sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/last_update" />
<WebView
android:id="#+id/newsContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/last_update" />
<TextView
android:id="#+id/newsDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/last_update" />
</LinearLayout>
</ScrollView>
</LinearLayout>
I tried to use mywebView.setDrawingCacheEnabled(false); but it just return the same warning.
Also, I find the problem occur when the webpage is overscreen size , but when I show it , I find the layout of the web is slightly different, on 2.3 , 4.1 , it can simply start the new line if the word is exceed the page, however , in 4.4 it does not , so part of the word is out of the screen .
How to fix it? Thanks
My Suggestion is give layout height to webview so that it wont exceed the your specified height
<LinearLayout
android:id="#+id/webview1"
android:layout_width="fill_parent"
android:layout_height="150dip" >
<WebView
android:id="#+id/sampletxt"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
In your activity just include the below lines
SampleTxt.getSettings().setLoadWithOverviewMode(true);
SampleTxt.getSettings().setJavaScriptEnabled(true);
SampleTxt.loadData("Your Text To show the Webview",
"text/html; charset=UTF-8", null);
It will work fine. any doubts let me know
I suggest you to use your own WebView client. In android we can use WebViewClient or WebChromeClient. Using this you would get better result that you want. Just try it and check.
For WebViews in Android, you should start from the assumption that things are buggy. They shouldn't be, but as you discovered, if you make the background a flat color, it "resolves" the issue.
Having said that, it is still a good idea to keep in mind that you're dealing with a wide range of mobile devices with wildly different processing and memory allocations when you're coding for Android phones, so always be sure to test on a real device.
If you don't have at least 4 or 5 different physical Android devices that you can test on, then look around for services that allow you to use their devices to test remotely. Never believe that because you have tested something in an emulator, it will behave the same on a real device.
I am completely stumped on something that I thought would be the easiest thing ever. I am trying to play a video inside a frame in a relative layout.
Note that the application is meant to run on a very specific device (Archos 101 internet tab) in landscape mode, and the videos are pre-encoded with a very specific size of 480x360, which is why the layout has some fixed sizes.
Here is the layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Background -->
<ImageView
android:layout_width="980dp"
android:layout_height="568dp"
android:src="#drawable/bg_video" />
<TextView
android:id="#+id/video_headtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="73dp"
android:layout_marginLeft="255dp"
android:textColor="#FFFFFF"
android:textSize="16dp" />
<TextView
android:id="#+id/video_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:layout_centerHorizontal="true"
android:layout_marginTop="112dp" />
<VideoView
android:id="#+id/video_videocontainer"
android:layout_width="480dp"
android:layout_height="360dp"
android:layout_below="#id/video_title"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true" />
</RelativeLayout>
I load the video using this code
player = (VideoPlayer) findViewById(R.id.video_videocontainer);
player.setVideoURI(videoUri);
The code works, but while the videoView is correctly inside the frame, the video itself plays somewhere in the top of the screen, and only part of it is shown in the VideoView.
Example of what happens here (This is only a temp video for debugging).
Screenshot of the video at the same moment here.
As you can see, the VideoView only shows part of the video, filling the rest with black.
I'm pretty sure I'm missing something really simple, but I can't figure out what at all.
Thanks in advance.
EDIT : I have tried writing a VideoPlayer class that extends VideoView and overrides onMeasure like this
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
setMeasuredDimension(480, 360);
}
public void changeVideoSize()
{
getHolder().setFixedSize(480, 360);
requestLayout();
invalidate();
}
But it doesn't help a single bit.
EDIT 2 : Tried with a SurfaceView and MediaPlayer, same result. I have the feeling I haven't understood the principle of playing a video on Android. Getting quite stuck here.
EDIT 3 : I have tried on a Samsung Galaxy HD and the video shows correctly inside the frame. I wonder if this is a problem with the tablet, or with 2.2?
EDIT 4 : AVD running under 2.2 doesn't render the video properly. AVD running 4.1 does. I guess that narrows it down a tad.
I had similar problem with a video that had a high too profile for that particular device (2.1) to be handled and it worked fine for android 4.0.
Other than that, I am using SurfaceView and the trick was to add listeners to the events for the MediaPlayer (setOnVideoSizeChangedListener in particular) and the callback to the surface linked to the mediaplayer events.
Set the VideoView attribute setZOrderOnTop to true and see if it works.
For instance if I have a videoview called qvideo
qvideo.setZOrderOnTop(true);
I've got a problem with Admob not showing up Ads...
Here's the LogCat:
WARN/AdMobSDK(502): Ignoring requestFreshAd() because we are requesting an ad right now already.
INFO/AdMobSDK(502): No fill. Server replied that no ads are available (1164ms)
INFO/AdMobSDK(502): No fill. Server replied that no ads are available (846ms)
I've tried test mode, no test mode, emulator, real phone, etc. It never shows anything up, but I get requests and prints on Admob stats, like if it ever worked...
AFAIK, I did everything in the Admob Android SDK... the only thing that could be the cause of any problems, IMHO, would be the fact that I'm using tabbed layout with scrollview and then a relativelayout where the ad shows...
Here's a sample of the layout for a tab:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res/com.xxx.xxx"
android:id="#+id/tababout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF000000">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF000000"
android:padding="10px">
<ImageView
android:id="#+id/label_img"
android:src="#drawable/about_header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside" />
<TextView android:id="#+id/label_know_more_desc"
style="#style/Desc"
android:layout_below="#id/label_img"
android:text="#string/tab_about_know_more_desc" />
<Button android:id="#+id/bt_know_more"
style="#style/Button"
android:gravity="center_vertical|center_horizontal"
android:layout_below="#id/label_know_more_desc"
android:text="#string/tab_about_know_more_bt" />
<com.admob.android.ads.AdView android:id="#+id/ad" android:layout_width="fill_parent" android:layout_height="wrap_content" myapp:backgroundColor="#000000" myapp:primaryTextColor="#FFFFFF" myapp:secondaryTextColor="#CCCCCC" />
</RelativeLayout>
</ScrollView>
And here's the main.xml, not that I think you need it:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF000000">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF000000"
android:paddingTop="5px">
</FrameLayout>
</LinearLayout>
</TabHost>
I've read in Admob ads will not display when placed inside a tabview that the problem could be the 10px padding I'm throwing in, but even if I disable that, it doesn't work.
I even tried moving the xmlns:myapp to RelativeLayout, but obviously didn't change anything....
Also, I've made my first live ad request over 24 hours ago...
EDIT
Ok, now I'm getting somewhere, I've managed to get test ads showing up (my setTestDevices was too late in the onCreate code, I pushed it up to the first lines), but not real ones... am I missing something? I obviously commented out the setTestDevices line and no ads show up
EDIT 2
Well, I added two internal ads (I already had internal ads enabled, but no internal ads set), and suddenly ads started showing on my app (not only internal ads).
I guess everything altogether made it work?! :)
Thanks everyone!
You aren't positioning the ad's in the RelativeLayout (they need a layout_above or layout_below or whatever to specify where to put them).
Also there is a minimum size for admob that you might want to ensure you match, I think it's like 48dip in height at least, not sure what the horizontal is.
Lastly I don't know where you are trying to place your ad's, but it probably would make more sense in your main frame-layout, I have a padding at the bottom of my app which I use for the ad-view.
Edit: also if your app is public check for ad-revenue. Android pre 2.3 allowed ad's to be hidden behind views and still register clicks. I actually made my initial $1 before my ad's were even visible by anyone.
Another reason that the AdMob Ads won't show up is that you haven't declared the AdActivity which will display the ads when they are clicked on. Without the AdActivity declared in my AndroidManifest.xml, I don't see the ads. With it declared, the Ads show up.
...AndroidManifest.xml...
<!-- AdMob -->
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation"/>