Android - when exiting a WebView, the audio still keeps playing - android

I have this code which works and the only problem with it is that if I leave the WebView and even close the app, and even press power on the phone, the audio from the podcasts keeps playing.
Would anyone know how to stop that?
Here is the code:
public class PodcastsActivity extends BaseActivity //implements ActionBar.OnNavigationListener
{
WebView webview = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
//setTheme(R.style.Theme_Sherlock_Light);
super.onCreate(savedInstanceState);
//setContentView(R.layout.podcasts);
webview = new WebView(this);
webview.getSettings().setAppCacheEnabled(false);
webview.getSettings().setJavaScriptEnabled(true);
webview.setInitialScale(1);
webview.getSettings().setPluginState(PluginState.ON);
webview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
//webSettings.setBuiltInZoomControls(true);
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setBuiltInZoomControls(true);
//webSettings.getMediaPlaybackRequiresUserGesture();
webSettings.setAllowContentAccess(true);
webSettings.setEnableSmoothTransition(true);
webSettings.setLoadsImagesAutomatically(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setSupportZoom(true);
webSettings.setUseWideViewPort(true);
setContentView(webview);
webview.loadUrl("http://www.stitcher.com/podcast/entrepreneuronfirecom/entrepreneur-on-fire-tim-ferriss-other-incredible-entrepreneurs");
}
// public void onBackPressed ( )
// {
// Class.forName("com.***.HTML5WebView").getMethod("onPause", (Class[]) null).
// invoke(html5WebView, (Object[]) null);
// }
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack())
{
webview.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onStop()
{
super.onStop();
// your code
webview.clearView();
}

You should call through to the WebView's onPause() and onResume() from your Activity's onPause() and onResume(), respectively.
Pauses any extra processing associated with this WebView and its
associated DOM, plugins, JavaScript etc. For example, if this WebView
is taken offscreen, this could be called to reduce unnecessary CPU or
network traffic. When this WebView is again "active", call onResume().
There's also pauseTimers(), which affects all of the WebViews within your application:
Pauses all layout, parsing, and JavaScript timers for all WebViews.
This is a global requests, not restricted to just this WebView. This
can be useful if the application has been paused.

Accepted answer didnt work for me - just using onPause in a fragment was not enough to stop music on Android 9. I had to also do:
override fun onDestroyView() {
webview?.destroy()
super.onDestroyView()
}

Same issue for the Jetpack Compose can be solved by capturing the WebView (https://google.github.io/accompanist/webview/) in "onCreated" and then use it to call "destroy()"
val webViewState = rememberWebViewState(webViewUrl.value)
val webView = remember { mutableStateOf<android.webkit.WebView?>(null) }
//..inside Composable..
WebView(state = webViewState,
captureBackPresses = true,
onCreated = { wv ->
webView.value = wv
}
)
//..on Back Press/Close Button..
webView.value?.destroy()

In my case WebView onPause() and onResume() is not working for me.
Solution:
onPause I load the below URL to stop the audio:
webView.loadUrl("javascript:document.location=document.location");

Related

How can we run a function when the website responds or changes its page in web view?

My problem is that if there is a button on a website, then it will appear on the some page when the user click it . i want to enable function when the information is displayed . Please help me.
private WebView webView;
private ProgressBar progressXml;
private RelativeLayout WaitPageXml; // waiting page for user
private RelativeLayout NoInternetPage;// page for no conection display for youser
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.phone_number);
webView = findViewById(R.id.WebViewXml);
progressXml = findViewById(R.id.progressXml);
WaitPageXml = findViewById(R.id.WaitPageXml);
webView = findViewById(R.id.WebViewXml);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setUseWideViewPort(true);
webView.setInitialScale(15);
WebSettings mWebSettings = webView.getSettings();
webView.getSettings().setUseWideViewPort(true);
WebSettings webSettings = webView.getSettings();
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setSupportMultipleWindows(true);
webView.getSettings().setSupportZoom(true);
mWebSettings.setAllowFileAccess(true);
mWebSettings.setAllowFileAccess(true);
mWebSettings.setAllowContentAccess(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(),
"android");
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap
favicon) {
if (isOnline()) {
progressXml.setVisibility(View.VISIBLE);
WaitPageXml.setVisibility(View.VISIBLE);
super.onPageStarted(view, url, favicon);
} else {
super.onPageStarted(view, url, favicon);
NoInternetPage.setVisibility(View.VISIBLE);
}
}
#Override
public void onPageFinished(WebView view, String url) {
progressXml.setVisibility(View.GONE);
WaitPageXml.setVisibility(View.GONE);
NoInternetPage.setVisibility(View.GONE);
});
webView.loadUrl("https://......");
#Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
public boolean isOnline() { //for test conection....
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
#SuppressLint("MissingPermission") NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
unfortunately ,the rosponse was not executed by the site
I'm having a bit of trouble telling exactly what you want from your question, but from how I interpret it, you need a button press in the web-page to trigger some sort of UI update (pop-up, field update, etc). There are a few different ways to do that, and I'm not entirely sure which is the best solution for what you're trying to accomplish.
However, given that you've posted this as an Android question and provided a source listing that includes your work for setting up the web view, I'm going to assume that you're looking for a way to hook up a button press from the HTML page to some Java callback. If that's the case, you're already part-way there. When you call webView.addJavascriptInterface(new MyJavaScriptInterface(), "android");, that injects an instance of MyJavaScriptInterface as a global JavaScript variable.
You don't have your implementation of MyJavaScriptInterface listed, so let's assume it's a class declared with the JavascriptInterface annotation, meant to be passed on to addJavascriptInterface. Annotation a class with JavascriptInterface exposes its public methods to JavaScript. Let's say you have your class declared as such:
#JavascriptInterface
class MyJavaScriptInterface {
public void doSomething() {
Log.d("MyJavaScriptInterface", "Got a callback from JavaScript");
}
}
Since you added an instance of this class with the name "android" when you set up your WebView, then you can now call our doSomething function in JavaScript with android.doSomething(). For example, let's say this is the HTML that loads when you call webView.loadUrl("https://......");:
<html>
<head>
<script>
function onButtonPressed() {
android.doSomething();
}
</script>
</head>
<body>
<button onclick="onButtonPressed();">Click me!</button>
</body>
</html>
In that case, clicking the button on the page will call all the way down into doSomething in the Java class. From there, you can do whatever you need to do to display your information. Note that doSomething doesn't need to be a void; it can also return data, if you need displaying of information to be handled by JavaScript but retrieved natively.
For some more help, you can check out the Android developer guide on this topic here.

How to prevent webview to reload webpage in Android

I got a webview which is implemented like that:
this.webView = (WebView) view.findViewById(R.id.typeform);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.setWebViewClient(new WebViewClientHelper(activity));
I don't want to reload the webpage if I click back button and then come to the fragment again, so I implemented that:
In the onCreateView:
if (webViewBundle == null) {
webView.loadUrl(Constants.TYPEFORM_URL);
} else {
webView.restoreState(webViewBundle);
}
In the onPause():
#Override
public void onPause() {
super.onPause();
webViewBundle = new Bundle();
webView.saveState(webViewBundle);
}
Not sure why it does not work. Any recommendation?
Thanks in advance.
If you are getting to onCreateView when you click the back button, it means you are creating a new view instance every time. You need to have one instance, and if you want to override the behavior when you come back to it, implement onResume.

Webview sometimes shows webpage not available

On all of my apps I am getting a "webpage not available" error. This has just been happening recently, even on apps that have not been updated in awhile. At first I thought it was my server or domain name. However, everything loads on a mobile browser or desktop browser. The strangest part is that I can click on the link for the website given by the error and it works. Also, this isn't every time I get into the app. It sometimes load without any problems at all.
This is my main activity:
public class MainActivity extends Activity {
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Allow third party cookies for Android Lollipop
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mWebView = (WebView) findViewById(R.id.activity_main_webview);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptThirdPartyCookies(mWebView,true);
}
mWebView = (WebView) findViewById(R.id.activity_main_webview);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setDatabaseEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.loadUrl("http://www.google.com");
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && this.mWebView.canGoBack()) {
this.mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
You instantiated WebView twice that could be the reason.
cookieManager.setAcceptThirdPartyCookies(mWebView,true);
You don't need this one below, you've done it already.
mWebView = (WebView)findViewById(R.id.activity_main_webview);

WebView back history without redirects

I implemented android webview and onKeyDown method for back key. (It implements webview.goBack();)
My problem is exactly similar to the question in this post below (no answers there)
How to control the Android WebView history/back stack?
PROBLEM - When I press back button, webview selects the previous URL, but if that URL was actually a redirect, it goes into this vicious cycle/loop. If you look at chrome or stock browser it correctly handles the back without going back to the redirects.
How can this be solved?
Example: go to gap.com. Then select "My Gap Credit Card". This opens a redirect link and then the final page. Now when I click back, it never goes to Gap.com home page.
Any suggestions...
Additional Information: I did implement the shouldOverrideUrlLoading. If I remove that method, it seems to work fine but with this method it does not...
I've just tested this on jellybean and it seems to work.
Essentially, whenever a new URL is loaded in the WebView keep a copy of the url.
On the next URL request, double check they we aren't already on this page, if they are, then go back in the webview history another step.
Essentially this is relying on the url passed into the override step being the redirected url, rather than the final redirected url.
public class MainActivity extends Activity {
private Button mRefreshButton;
private WebView mWebView;
private String mCurrentUrl;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.webview);
mRefreshButton = (Button) findViewById(R.id.refresh);
mRefreshButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mWebView.reload();
}
});
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(mCurrentUrl != null && url != null && url.equals(mCurrentUrl)) {
mWebView.goBack();
return true;
}
view.loadUrl(url);
mCurrentUrl = url;
return true;
}
});
mWebView.loadUrl("http://www.gap.com/");
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN) {
switch(keyCode) {
case KeyEvent.KEYCODE_BACK:
if(mWebView.canGoBack()){
mWebView.goBack();
return true;
}
break;
}
}
return super.onKeyDown(keyCode, event);
}
}
I hope this answer if anyone is still looking for it.I had been hunting to fix similar issues in my project and had tried multiple approaches like using
- WebView.HitTestResult
- Pushing the urls into the list
- onKeyDown and so on...
I think most of it would work if your app consists of just webview. But my project had a combination of native and webview and handles some native schema.
Essentially found that the key is how you override the method shouldOverrideUrlLoading. Since i wanted my app to handles some of the urls and the webview to handle some of the other ones especially the back handling.I used a flag for back presses something like ..
#Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mClient.setIsBackPressed(true);
//mClient is an instance of the MyWebviewClient
mWebView.goBack();
} else {
super.onBackPressed();
}
}
public class MyWebviewClient extends WebViewClient {
private Boolean isBackPressed = false;
public void setIsBackPressed(Boolean isBackPressed) {
this.isBackPressed = isBackPressed;
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (isBackPressed){
return false;
}
else {
// handle the url by implementing your logic
return true;
}
}
#Override
public void onPageFinished(WebView view, String url) {
isBackPressed = false;
super.onPageFinished(view, url);
}
}
In this way, whenever there is a redirect when you click back, then it return false and hence mocks the behaviour of the webview. At the same time, you make sure that the isBackPressed is set to false after the page finishes loading.
Hope this helps !!

html5 in a WebView, detect when video is started

In a WebView, I'm trying to load a html5 page where I embed a <video> but is there any way I can detect when the user selects the play button or the video starts playing?
Right now is when I play the video, default is it fires an Intentto open Android's default player, I don't want it to fire an Intent, I want to use a Dialog and play it there. If anybody can give an idea. Thanks.
#Override
public void onCreate(Bundle savedInstanceState) {
....
mywebviewer = (WebView) findViewById(R.id.mywebviewer);
WebSettings webSettings = mywebviewer.getSettings();
webSettings.setJavaScriptEnabled(true);
mywebviewer.loadUrl("https://www.youtube.com");
mywebviewer.setWebViewClient(new WebViewClient());
}
#Override
public void onBackPressed() {
if (mywebviewer.canGoBack()) {
mywebviewer.goBack();
} else {
super.onBackPressed();
}
}
I do it in this way:
boolean videoPlay=false;
webView.setWebChromeClient(new WebChromeClient() {
#Override
public Bitmap getDefaultVideoPoster() {
super.getDefaultVideoPoster();
videoPlay=true;
Log.d("vplayyyyyyyy",String.valueOf(videoPlay));
return null;
}
});
hope this help :)

Categories

Resources