How to Pause Flash Content in an Android Webview When My Activity Isn't Visible

How do I pause Flash content in an Android WebView when my activity isn't visible?

I don't see where you see that BrowserActivity or anything is calling pauseTimers(). I do see where onPause() for BrowserActivity eventually routes to onPause() of WebView. However, onPause() of WebView has the @hide annotation and so is not part of the SDK. Off the cuff, it would seem like onPause() is what you want, given the comment:

Call this to pause any extra
processing associated with this view
and its associated
DOM/plugins/javascript/etc. For
example, if the view is taken
offscreen, this could be called to
reduce unnecessary CPU and/or network
traffic. When the view is again
"active", call onResume().

Note the reference to "plugins", which is not mentioned in the pauseTimers() documentation.

I'd try using reflection to see if onPause() (and later onResume(), when you want stuff to start up again) does what you need. If it does, please post an issue to b.android.com about this, asking them to add these methods (or equivalents) to the SDK. Your requirement seems like it will be a common one, and a solution that goes past the SDK is not a good solution.

Cannot pause HTML5 / Flash sound on Android in-app WebView when application going to background

Reply from Google:
https://code.google.com/p/chromium/issues/detail?id=532359#c5

Hm, if you only want to change the Android app, you're probably out of
luck with what you can do there.

If you can change the page, you may look into page visibility API to
pause/resume playback (Tim may know if it's enabled for WebView or
not).

But ultimately, since it's WebView, your app can communicate with the
page and cause it to play/pause playback in the app's activity
onPause/onResume.

android WebView stop running

Try looking at this to see if it is the same issue and resolution.

How do I pause Flash content in an Android WebView when my activity isn't visible?

Android activity with WebView crashes when starting new activity

Fatal signal 11 is because webview is still drawing after you destroyed it. Simply put the webView.destroy() in the onStop. I believe your app will work fine

Problem to load flv video in webview

You don't state clearly what your Android version, however I can confirm that the flash plugin does load and the movie player does intilaize with the swirly shape graphic. I can engage it into fullscreen mode. I am also able to play online video but not from the application's assets folder, however I do have a workaround.

The following permissinos are required in your manifest.xml:

<uses-permission android:name="android.permission.INTERNET"></uses-permission> <!-- where required -->
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

Interestingly I discovered I was only able to run the SWF player from the assets folder when the html was statically loaded i.e when I created an html file and loaded that directly from the assets folder using loadUrl(). There seems to be something blocking access to the application directory when html data is loaded using the loadDataBaseUrl method.

To succesfully get video to play from the local device a static html file and the video must be co-located on the sdcard. My only conclusion is that the assets folder is off limits to the embedded plugin for security reasons.

if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Log.d(TAG, "No SDCARD");
} else {
webView.loadUrl("file://"+Environment.getExternalStorageDirectory()+"/FLVplayer/index.html");
}

And here is the html file

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body style="margin:0; pading:0; background-color: black;">
<embed
style="width:100%; height:100%"
src="./FLVPlayer.swf?fullscreen=true&video=./expression_sad.flv"
autoplay="true"
quality="high"
bgcolor="#000000"
name="VideoPlayer"
align="middle"
allowScriptAccess="*"
allowFullScreen="true"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
</embed>
</body>
</html>

This is a 100% working solution but you would have to write your html file to the sdcard before calling loadUrl to dynaamically replace the video file name. In addition you should copy the video from your assets folder into the same path on the sdcard (as you can see from my exaple I created a folder called FLVplayer.

Test performed on Samsung Galaxy Tab running Froyo(2.2)

UPDATE

I am including a complete activity that has been tested and working. This expects a copy of the Flash player, the FLV file and the index.html file to be placed in a folder called "FLVplayer" on the root of your sdcard which you can copy across using the file explorer. You can edit the various utility functions to modify the behaviour to copy the files from your assetes folder

package com.FLVplayer;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.webkit.WebView;
import android.widget.FrameLayout;

public class FLVplayerActivity extends Activity {

private static final String TAG="FLVplayer";
private static WebView webView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

webView = (WebView)findViewById(R.id.webview);

//WebView webview = new WebView(this);
//setContentView(webview);

webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setPluginsEnabled(true);

if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Log.d(TAG, "No SDCARD");
} else {

//prepare the directory
File flvDirectory = new File(Environment.getExternalStorageDirectory(),"FLVplayer");

if(!flvDirectory.exists())
try {
flvDirectory.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}

//specify the html file name to use
File flvHtml = new File(flvDirectory,"index.html");

//copy what you need
copySwfAsset(flvDirectory, "FLVPlayer.swf");
copyFlvAsset(flvDirectory, "20051210-w50s.flv");

//render the html
createVideoHtml(flvHtml, "20051210-w50s.flv");

//load the content into the webview
webView.loadUrl(Uri.fromFile(flvHtml).toString());

//sit back, watch FLV and eat popcorn
}
}

private void createVideoHtml(File htmlFile, String htmlFileName)
{
//TODO render your own html file to sdcard
}

private void copySwfAsset(File flvDirectory, String flashFileName)
{
//TODO copy your own SWF video player file from assets
}

private void copyFlvAsset(File flvDirectory, String videoFileName)
{
//TODO copy your oown FLV file from asset folder
}

@Override
protected void onPause(){
super.onPause();

callHiddenWebViewMethod("onPause");

webView.pauseTimers();
if(isFinishing()){
webView.loadUrl("about:blank");
setContentView(new FrameLayout(this));
}
}

@Override
protected void onResume(){
super.onResume();

callHiddenWebViewMethod("onResume");

webView.resumeTimers();
}

private void callHiddenWebViewMethod(String name){
// credits: http://stackoverflow.com/questions/3431351/how-do-i-pause-flash- content-in-an-android-webview-when-my-activity-isnt-visible
if( webView != null ){
try {
Method method = WebView.class.getMethod(name);
method.invoke(webView);
} catch (NoSuchMethodException e) {
//Lo.g("No such method: " + name + e);
} catch (IllegalAccessException e) {
//Lo.g("Illegal Access: " + name + e);
} catch (InvocationTargetException e) {
//Lo.g("Invocation Target Exception: " + name + e);
}
}
}

}

ADENDUM

I believe there may be a way to bypass the security issues by intercepting the URL of the various files and returning the data directly from the assets folder using WebViewClient.shouldInterceptRequest() but that requires API 11 so not suitable as a generic solution.



Related Topics



Leave a reply



Submit