Reputation: 625
I am working in an Android app and I want to preload splash screen while the webView is loading the webpage BUT i have a local .mp4 video instead of a picture.
So once the user clicks the app, the .mp4 will start playing (4 seconds). During that 4 seconds the webView should pre-load the webpage SO when the video is finished show my web page (if the web page is already loaded), otherwise wait in the splash screen until the webpage is ready and then load it.
Here is my MainActivity:
public class MainActivity extends AppCompatActivity {
private WebView webView;
public static final Object SPLASH_LOCK = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
String myURL = "https://www.testpage.com";
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
/** tell the webView to enable javascript execution */
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
/** Load the HTML page */
webView.loadUrl(myURL);
/** Call the JavaScriptInterface within the WebView */
webView.addJavascriptInterface(this, "jsinterface");
startActivity(new Intent(this, AnimationScreenActivity.class));
/** Enable Javascript in WebView
/ callback for browser events */
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished (WebView webView, String url) {
synchronized (SPLASH_LOCK) {
SPLASH_LOCK.notifyAll();
}
}
});
}
}
Here is the AnimationScreenActivity:
public class AnimationScreenActivity extends AppCompatActivity{
private static String TAG = AnimationScreenActivity.class.getName();
private static long MAX_SPLASH_TIME = 10000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animation_screen);
try {
VideoView videoHolder = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoHolder.setVideoURI(video);
videoHolder.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
jump();
}
});
videoHolder.start();
} catch (Exception ex) { jump(); }
}
private void jump() {
new Thread() {
@Override
public void run() {
synchronized (MainActivity.SPLASH_LOCK) {
// wait for notify or time-out
try {
MainActivity.SPLASH_LOCK.wait(MAX_SPLASH_TIME);
} catch (InterruptedException ignored) {}
}
finish();
}
}.start();
}
}
Here is the activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Here is the animation_screen_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/animation_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test.AnimationScreenActivity">
<VideoView
android:id="@+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
And finally the Manifest.xml where i set MainActivity as LAUNCHER:
<activity android:name=".MainActivity"
android:theme="@style/FullScreenTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AnimationScreenActivity"
android:theme="@style/FullScreenTheme"
android:screenOrientation="portrait"/>
So what i have until now is that once the user starts the app, the .mp4 starts and when the .mp4 finish THEN it waits for 10 seconds in the AnimationScreenActivity and THEN it loads the webpage.
Any help will be appreciated!
Upvotes: 1
Views: 2297
Reputation: 625
After a lot of help from @android developer (many thanks!) and stackoverflow posts, I have combined both activities MainActivity
, AnimationScreenActivity
in one activity (MainActivity).
Here is the code:
public class MainActivity extends AppCompatActivity {
private String myURL = "https://www.testpage.com";
VideoView videoView;
ViewSwitcher viewSwitcher;
private WebView webView;
private boolean hasFinishedLoadingPage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
final VideoView videoView = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoView.setVideoURI(video);
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (hasFinishedLoadingPage)
setViewToSwitchTo(viewSwitcher, webView);
// else webView.reload();
setViewToSwitchTo(viewSwitcher, webView);
}
});
videoView.start();
} catch (Exception ex) {
}
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
webView.setWebViewClient(new WebViewClient() {
boolean isRedirected;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (!isRedirected) {
setViewToSwitchTo(viewSwitcher, videoView);
}
isRedirected = true;
}
@Override
public void onPageFinished(WebView webView, String url) {
super.onPageFinished(webView, url);
hasFinishedLoadingPage = true;
}
});
/** Callback for web events */
webView.setWebChromeClient(new WebChromeClient() {
});
webView.loadUrl(myURL);
}
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
}
Upvotes: 1
Reputation: 115952
You can have a single Activity that has what you have on the 2 Activities, by having a ViewSwitcher (or ViewAnimator) to switch between the layouts. This will also remove the need for the SPLASH_LOCK object.
While loading, switch the ViewSwitcher (or ViewAnimator) to the layout of the video, and when you are done loading the page, switch it to the layout of the WebView.
I've made a simple code to make it easier to switch between view. If you wish, you can use it:
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @IdRes final int viewIdToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView().getId() == viewIdToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i).getId() == viewIdToSwitchTo) {
if (viewAnimator.getDisplayedChild() == i)
return;
viewAnimator.setDisplayedChild(i);
return;
}
}
Usage:
setViewToSwitchTo(viewSwitcher, R.id.webViewLayout);
or:
setViewToSwitchTo(viewSwitcher, webViewLayout);
You can even have an animation when switching between the views, using "inAnimation" and "outAnimation" attributes.
And, if the code gets too large, you can have fragments instead of views. One for the WebView, and another for the video.
About onPageFinished being called multiple times, you need to check which of them is the one that you consider as really being finished. Since each website is different, and can have multiple frames, you will have to add this logic. If you want, you can monitor onPageStarted, as shown here:
BTW, if you change the orientation in the manifest, do note that since you have a WebView, you will have to think what to do with orientation change, because it doesn't restore its state well.
EDIT:
Here's the layout file:
<ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/viewSwitcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<VideoView
android:id="@+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
</ViewSwitcher>
in the onCreate, use the code of both of your activities, and add this to go to the video :
setViewToSwitchTo(viewSwitcher, R.id.videoView1);
and this to go to the webView (when it has done loading, in your case) :
setViewToSwitchTo(viewSwitcher, R.id.webView);
Upvotes: 3
Reputation: 17613
My suggestion would be to avoid having 2 activities, I suspect that's one of your problems.
Have only one Activity with the VideoView
and the WebView
both inside a RelativeLayout so that VideoView is above the WebView.
When the WebView is ready, simply VideoView.setVisibity(View.GONE)
Upvotes: 0