How to detect backbutton/home press from a service like messenger chat head service? - service

I have been looking through several stackoverflow question to find out how can I listen to backpress button on a service using windows manager. Most of the answers proposes that it's not possible, however I can see that messenger handle it very well.
How does messenger handle the backpress button on it's head chat service? (Or I am completely wrong and they are not a service using windows manager?)

To achieve what you need, you need to extend some ViewGroup that you are going to use as a root container for your views. Let's start with this:
public class BackButtonAwareLinearLayout extends LinearLayout {
public interface BackButtonListener {
void onBackButtonPressed();
}
#Nullable
private BackButtonListener mListener;
public BackButtonAwareLinearLayout(Context context) {
super(context);
}
public BackButtonAwareLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BackButtonAwareLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setBackButtonListener(#Nullable BackButtonListener listener) {
mListener = listener;
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK
&& mListener != null) {
mListener.onBackButtonPressed();
return true;
}
return super.dispatchKeyEvent(event);
}
}
Basically, overriding dispatchKeyEvent is what does a trick for us here.
Then make a use of it in some xml (I have called it chat_head_container.xml):
<?xml version="1.0" encoding="utf-8"?>
<com.pablo432.myapplication.BackButtonAwareLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="48sp"
android:text="Hello, world!"
android:textColor="#000"
android:background="#f5f5f5"
android:gravity="center"/>
</com.pablo432.myapplication.BackButtonAwareLinearLayout>
Next, create a Service that adds our view to the WindowManager (though I suppose you know how to do it, I'll post it anyway for the sake of completeness):
public class ChatHeadService extends Service
implements BackButtonAwareLinearLayout.BackButtonListener {
private WindowManager mWindowManager;
private BackButtonAwareLinearLayout mRootContainer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRootContainer = (BackButtonAwareLinearLayout) inflater.inflate(
R.layout.chat_head_container, null, false);
mRootContainer.setBackButtonListener(this);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSPARENT);
mWindowManager.addView(mRootContainer, layoutParams);
}
#Override
public void onBackButtonPressed() {
mRootContainer.setBackButtonListener(null);
mWindowManager.removeView(mRootContainer);
}
#Override
public void onDestroy() {
super.onDestroy();
if (mRootContainer != null) mWindowManager.removeView(mRootContainer);
}
}
So long story short, BackButtonAwareLinearLayout exposes a listener interface, that our service needs to implement and subscribe itself to the Layout.
Also have in mind that this addresses handling back button. To handle home button, you may want to take a look at https://stackoverflow.com/a/31340960 and https://stackoverflow.com/a/33580971 - basically my answer is a bit of a summary from those two links + https://stackoverflow.com/a/15980900 but contains few tweaks (like, for example, you can't set FLAG_NOT_FOCUSABLE in WindowManager.LayoutParams).
Of course you need to start your service somewhere by calling startService, declare this service in AndroidManifest.xml and add a SYSTEM_ALERT_WINDOW permission.

Related

SupportMapFragmentManagers getMapAsync() does not trigger onMapReady(GoogleMap map)

I have a
public abstract class MyMapFragment implements OnMapReadyCallback
{
//
public GoogleMap googleMap;
SupportMapFragment mapFragment;
#IdRes
public abstract int getSupportMapFragId();
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// http://stackoverflow.com/a/36592000/5102206
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
// Do something for lollipop and above versions
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(getSupportMapFragId());
} else {
// do something for phones running an SDK before lollipop
mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(getSupportMapFragId());
}
mapFragment.getMapAsync(this);
}
//..
#Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
}
}
According to my breakpoints onViewCreated() is called, but onMapReady() is not called (breakpoint on this.googleMap = map not triggered)
On Android 5, 6 and 7 it works fine so far and I can see the Map..
On Android 4.X (API 16 - API 19) devices my app starts up, but then it seem to freeze there... I see a white blank screen.
On Android 4.X OS devices:
1. With getFragmentManager(), the mapFragment object is null after the else condition.
2. With getChildFragmentMenager() the mapfragment seem to be valid and non-null, but onMapReady not triggered.
What am I missing here?
Note: You cannot inflate a layout into a fragment when that layout includes a . Nested fragments are only supported when added to a fragment dynamically
If you want to inflate a map in a fragment you can either do it in xml or do it in java code like this:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentManager fm = getChildFragmentManager();
SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentByTag("mapFragment");
if (mapFragment == null) {
mapFragment = new SupportMapFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.mapFragmentContainer, mapFragment, "mapFragment");
ft.commit();
fm.executePendingTransactions();
}
mapFragment.getMapAsync(callback);
}
And also the simple container
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
Also, you don't need to implement the onMapReadyCallback in the class definition. Instead of callback you create a new OnMapReadyCallback() right there:
MapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
googleMap = mMap;
}
});
You also need these
MapView mMapView;
private GoogleMap googleMap;
I hope this helps somehow !
There was an issue with a blocking thread from RxJava on main thread. So it was not an Google Maps issue.
I don't quite understand why you are nesting fragments, specially because it can cause performance issues.
If you take a look at Google Samples, the Google Maps examples uses an Activity and SupportMapFragment:
public class MapsActivityCurrentPlace extends AppCompatActivity
implements OnMapReadyCallback, ConnectionCallbacks,
OnConnectionFailedListener {
#Override
public void onMapReady(GoogleMap map) {
mMap = map;
// Use a custom info window adapter to handle multiple lines of text in the
// info window contents.
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
// Return null here, so that getInfoContents() is called next.
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
// Inflate the layouts for the info window, title and snippet.
View infoWindow = getLayoutInflater().inflate(R.layout.custom_info_contents,
(FrameLayout)findViewById(R.id.map), false);
TextView title = ((TextView) infoWindow.findViewById(R.id.title));
title.setText(marker.getTitle());
TextView snippet = ((TextView) infoWindow.findViewById(R.id.snippet));
snippet.setText(marker.getSnippet());
return infoWindow;
}
});
// Turn on the My Location layer and the related control on the map.
updateLocationUI();
// Get the current location of the device and set the position of the map.
getDeviceLocation();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mLastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION);
mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION);
}
setContentView(R.layout.activity_maps);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */,
this /* OnConnectionFailedListener */)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle connectionHint) {
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult result) {
Log.d(TAG, result.getErrorMessage());
}
#Override
public void onConnectionSuspended(int cause) {
Log.d(TAG, "Play services connection suspended");
}
}

Pushing data from one user to another in Vaadin web app

I get the fact that it might take more than 10 lines of code (hopefully not more than 50), but I was wondering if you could help me anyway.
I'm trying to update one user's UI thread at runtime, based on another user's input. I've created a basic project which implements three predefined users (jim, tom and threeskin). I'd like to send a message from jim to tom and have it appear as a new Label object in tom's UI, without threeskin ever knowing about it, even though they're all logged in. Oh, and jim shouldn't have to refresh his page. The label should just spawn on screen out of it's own accord.
To say that I'd appreciate some help would be the understatement of the decade.
public class User {
public String nume;
public User(String nume) {
super();
this.nume = nume;
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
public class Engine implements ServletContextListener {
public static ArrayList<User>userbase;
public void contextDestroyed(ServletContextEvent arg0) { }
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("This code is running at startup");
userbase =new ArrayList<User>();
userbase.add(new User("jim"));userbase.add(new User("tom"));userbase.add(new User("threeskin"));
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
public class InfigeUI extends UI {
User us3r;
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = InfigeUI.class)
public static class Servlet extends VaadinServlet {}
protected void init(VaadinRequest request) {
VerticalLayout everything=new VerticalLayout();
setContent(everything);
if (us3r==null){everything.addComponent(auth());}else{everything.addComponent(main());}
}
ComponentContainer auth(){
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
TextField userField=new TextField();
Button login = new Button("Log in");
login.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
us3r=login(userField.getValue());
if (us3r!=null){
saveValue(InfigeUI.this, us3r);
layout.removeAllComponents();
layout.addComponent(main());
}else{Notification.show("I only know jim, tom and threeskin. Which one are you?");}}
});
layout.addComponent(userField);
layout.addComponent(login);
return layout;
}
User login(String nume){
for (int i=0;i<Engine.userbase.size();i++){
if (nume.equals(Engine.userbase.get(i).nume)){return Engine.userbase.get(i);}
}
return null;
}
static void saveValue(InfigeUI ui,User value){
ui.us3r=value;
ui.getSession().setAttribute("something", value);
VaadinService.getCurrentRequest().getWrappedSession().setAttribute("something", value);
}
ComponentContainer main(){
VerticalLayout vl=new VerticalLayout();
Label label=new Label("This is the post-login screen");
String name=new String(us3r.nume);
Label eticheta=new Label(name);
TextField to=new TextField("Send to");
TextField message=new TextField("Message");
Button sendNow=new Button("Send now!");
vl.addComponent(eticheta);
vl.addComponent(label);
vl.addComponent(eticheta);
vl.addComponent(to);
vl.addComponent(message);
vl.addComponent(sendNow);
return vl ;
}
}
Basically you want three things
UI updates for a user which does no action himself, or in other words a message sent from the server to the browser. To enable this, you need to annotate the UI class using #Push. Otherwise, the update will only be shown when the user does something which causes a server visit, e.g. clicks a button
Some way of sending messages between UI instances (there is one UI instance per user). You can use some message bus implementation for this (CDI, Spring, ...) or you can make a simple on using a static field (static fields are shared between all users). See e.g. https://github.com/Artur-/SimpleChat for one way of doing it. It's also a good idea here to avoid all *.getCurrent methods as they in many cases will refer to another UI than you think (e.g. sender when you are in the receiver code), and you will do something else than you intend.
Safely update a UI when a message arrives. This is done using UI.access, also visible in the chat example.
First of all you need to enable the server push on your project help
based on Vaadin Documentation.
However, below code example will give what you want:
Create an Broadcast Listener Interface:
public interface BroadcastListener {
public void receiveBroadcast(final String message);
}
The Broadcaster Class:
public class Broadcaster {
private static final List<BroadcastListener> listeners = new CopyOnWriteArrayList<BroadcastListener>();
public static void register(BroadcastListener listener) {
listeners.add(listener);
}
public static void unregister(BroadcastListener listener) {
listeners.remove(listener);
}
public static void broadcast(final String message) {
for (BroadcastListener listener : listeners) {
listener.receiveBroadcast(message);
}
}
}
Your UI with Push Enalbed (via Annotation):
#Push
public class BroadcasterUI extends UI implements BroadcastListener {
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
final TextArea message = new TextArea("",
"The system is going down for maintenance in 10 minutes");
layout.addComponent(message);
final Button button = new Button("Broadcast");
layout.addComponent(button);
button.addClickListener(new Button.ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
Broadcaster.broadcast(message.getValue());
}
});
// Register broadcast listener
Broadcaster.register(this);
}
#Override
public void detach() {
Broadcaster.unregister(this);
super.detach();
}
#Override
public void receiveBroadcast(final String message) {
access(new Runnable() {
#Override
public void run() {
Notification n = new Notification("Message received",
message, Type.TRAY_NOTIFICATION);
n.show(getPage());
}
});
}
you can find the full link here.

Android - Top Back Button not working

I have this button on the topmost left part. And for some reason it is not going back to it's previous page when I click it. I've checked the other links already but it is not working.
The activity code on that one
public class CardListActivity extends Activity {
private static final String LOG_TAG = CardListActivity.class.getSimpleName();
private EventBus eventBus;
private Activity activity;
private CardListRequest cardListRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
public void init() {
Log.e(LOG_TAG, "XXXX Start : init XXXX");
setUpActionBar();
activity = this;
setContentView(R.layout.activity_card_list);
Log.e(LOG_TAG, "XXXX Finish : init XXXX");
}
private void setUpActionBar() {
getActionBar().setTitle(CardListActivity.class.getSimpleName());
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
AndroidManifest.xml
...
<activity
android:name=".CardListActivity"
android:label="#string/title_activity_card_list"
android:parentActivityName=".HomeActivity2">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.pw.mccdealsapp.HomeActivity2" />
</activity>
...
This page contains all the information to create an Up button that works correctly.
You need to add, in your activity, something like:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
first on your onCreate method put this
//action bar back icon
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
then override this method and make back opetion go to its parent
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home){
finish();
}
return super.onOptionsItemSelected(item);
}

My selection listener doesn't seem to be registering properly

I am creating an Eclipse RCP application with multiple views. One of my views is a multi-page editor view. Each of those pages has a a master/details block. I need to register all of those TableViewers as selection providers for my other view to listen to.
After much research online, I came across this article about multiple selection providers in a single view. I followed the instructions to create this selection provider for multiple viewers.
class MyMultipleSelectionProvider implements ISelectionProvider {
private final ListenerList selectionListeners = new ListenerList();
private ISelectionProvider delegate;
private final ISelectionChangedListener selectionListener = new ISelectionChangedListener() {
#Override
public void selectionChanged(final SelectionChangedEvent event) {
if (event.getSelectionProvider() == AdaptabilityProfileSelectionProvider.this.delegate) {
fireSelectionChanged( event.getSelection() );
}
}
};
/**
* Sets a new selection provider to delegate to. Selection listeners
* registered with the previous delegate are removed before.
*
* #param newDelegate new selection provider
*/
public void setSelectionProviderDelegate(final ISelectionProvider newDelegate) {
if (this.delegate == newDelegate) {
return;
}
if (this.delegate != null) {
this.delegate.removeSelectionChangedListener(this.selectionListener);
}
this.delegate = newDelegate;
if (newDelegate != null) {
newDelegate.addSelectionChangedListener(this.selectionListener);
fireSelectionChanged(newDelegate.getSelection());
}
}
#Override
public void addSelectionChangedListener(final ISelectionChangedListener listener) {
this.selectionListeners.add(listener);
}
#Override
public ISelection getSelection() {
return this.delegate == null ? null : this.delegate.getSelection();
}
#Override
public void removeSelectionChangedListener(final ISelectionChangedListener listener) {
this.selectionListeners.remove(listener);
}
#Override
public void setSelection(final ISelection selection) {
if (this.delegate != null) {
this.delegate.setSelection(selection);
}
}
protected void fireSelectionChanged(final ISelection selection) {
fireSelectionChanged(this.selectionListeners, selection);
}
private void fireSelectionChanged(final ListenerList list, final ISelection selection) {
final SelectionChangedEvent event = new SelectionChangedEvent(this.delegate, selection);
final Object[] listeners = list.getListeners();
for (int i = 0; i < listeners.length; i++) {
final ISelectionChangedListener listener = (ISelectionChangedListener) listeners[i];
listener.selectionChanged(event);
}
}
}
I added a focusListener on all of the edior's viewers so they become the delegate:
tree.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(final FocusEvent e) {
editor.getSelectionProvider().setSelectionProviderDelegate(MyEditorPage.this.treeViewer);
}
});
And I registered this as the selection provider for my editor:
site.setSelectionProvider( this.selectionProvider );
Then, within my view that needs to hear about the selection, I registered a selection listener for this editor:
getSite().getPage().addSelectionListener(MyEditor.ID, this.selectionListener);
When I run the application, I see that the delegate is being changed and the selection events are being fired. However, the listener list is empty.
I am never calling addSelectionChangeListener() directly. I was under the impression that that was what the selection service is for. Am I wrong? Should I be calling it? If so, when? If not, who is supposed to be adding the listener, and why isn't it happening?
If your code is based on FormEditor (or MultiPageEditorPart) then the selection provider is set to MultiPageSelectionProvider at the end of the init method. This may be overriding your site.setSelectionProvider call.
Using:
#Override
public void init(IEditorSite site, IEditorInput input)
throws PartInitException {
super.init(site, input);
site.setSelectionProvider(this.selectionProvider);
}
should make sure your provider is the one used.

Video customview in full screen exits when toggling the device screen in android

I am developing an android application which is purely web based. It needs to display HTML5 based webpages using webview which is rich in multimedia contents. when I try to play video content embedded in the webpage its all gone fine and i am also able to play video in full screen.
But my main problem starts here: When I toggled the device screen while playing fullscreen video, it suddenly exits from playback to its current web page. I am stucked here and here I am including all codes that I used as I can in hopes someone can help me.
Activity that is used: MainActivity.java
`
public class MainActivity extends Activity {
private WebView webView;
private FrameLayout customViewContainer;
private WebChromeClient.CustomViewCallback customViewCallback;
private View mCustomView;
private MyWebViewClient mWebViewClient;
private MyWebChromeClient mWebChromeClient;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customViewContainer = (FrameLayout) findViewById(R.id.customViewContainer);
webView = (WebView) findViewById(R.id.webView);
mWebViewClient = new MyWebViewClient();
webView.setWebViewClient(mWebViewClient);
mWebChromeClient = new MyWebChromeClient();
webView.setWebChromeClient(mWebChromeClient);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setSaveFormData(true);
webView.loadUrl("http://yuotube.com");
}
public boolean inCustomView() {
return (mCustomView != null);
}
public void hideCustomView() {
mWebChromeClient.onHideCustomView();
}
#Override
protected void onPause() {
super.onPause(); //To change body of overridden methods use File | Settings | File Templates.
webView.onPause();
}
#Override
protected void onResume() {
super.onResume(); //To change body of overridden methods use File | Settings | File Templates.
webView.onResume();
}
#Override
protected void onStop() {
super.onStop(); //To change body of overridden methods use File | Settings | File Templates.
if (inCustomView()) {
hideCustomView();
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (inCustomView()) {
hideCustomView();
return true;
}
if ((mCustomView == null) && webView.canGoBack()) {
webView.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
// WebChromeClient Class
public class MyWebChromeClient extends WebChromeClient {
private Bitmap mDefaultVideoPoster;
private View mVideoProgressView;
#Override
public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
onShowCustomView(view, callback); //To change body of overridden methods use File | Settings | File Templates.
}
#Override
public void onShowCustomView(View view,CustomViewCallback callback) {
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomView = view;
webView.setVisibility(View.GONE);
customViewContainer.setVisibility(View.VISIBLE);
customViewContainer.addView(view);
customViewCallback = callback;
}
#Override
public View getVideoLoadingProgressView() {
if (mVideoProgressView == null) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
mVideoProgressView = inflater.inflate(R.layout.video_progress, null);
}
return mVideoProgressView;
}
#Override
public void onHideCustomView() {
super.onHideCustomView(); //To change body of overridden methods use File | Settings | File Templates.
if (mCustomView == null)
return;
webView.setVisibility(View.VISIBLE);
customViewContainer.setVisibility(View.GONE);
// Hide the custom view.
mCustomView.setVisibility(View.GONE);
// Remove the custom view from its container.
customViewContainer.removeView(mCustomView);
customViewCallback.onCustomViewHidden();
mCustomView = null;
}
}
// WebViewClient Class
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url); //To change body of overridden methods use File | Settings | File Templates.
}
ProgressDialog dialog = ProgressDialog.show(MainActivity.this, "",
"Loading multimedia! Please wait...", true);
#Override
public void onPageFinished(WebView view, String url) {
dialog.dismiss();
}
}
}
web_activity.xml
<!-- View that will be hidden when video goes fullscreen -->
<RelativeLayout
android:id="#+id/nonVideoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.iptvmodified.VideoEnabledWebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="#+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- View that will be shown while the fullscreen video loads (maybe include a spinner and a "Loading..." message) -->
<View
android:id="#+id/videoLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="invisible" />
</RelativeLayout>
`activity_main.xml
<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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
I am searching for a solution for thisand googled this to death with no progress made. Any help would be greatly appreciated.
Normally when the device is rotated your activity gets destroyed and recreated. This is probably causing the WebView to get 'kicked out of' fullscreen playback.
You need to override Activity.onConfigurationChanged and declare you want to handle orientation changes in your manifest. See the docs for details.