I've developed a simple browser to research information on the net that has an edit text and a web view.
You can write the keywords in the edit text and press a button to reaserch your keywords on Google and see the results in the web view.
Now I wanna make possible to start the research using the space botton on the keyboard.
Is it possible? How can I do?
This is my code:
public class MainActivity extends AppCompatActivity {
WebView web;
EditText adress;
String url = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
web = (WebView) findViewById(R.id.wv);
adress = (EditText) findViewById(R.id.et1);
web.setWebViewClient(new WebViewClient());
web.getSettings().getBuiltInZoomControls();
}
public void Research(View v) {
url += adress.getText().toString();
Toast.makeText(this, "Loading...", Toast.LENGTH_SHORT).show();
web.loadUrl("https://www.google.it/search?q=" + url);
url = "";
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.p:
startActivity(new Intent(MainActivity.this, MainActivityBookmarks.class));
break;
case R.id.r:
web.reload();
Toast.makeText(this, "Loading...", Toast.LENGTH_SHORT).show();
break;
case R.id.b:
if (web.canGoBack()) {
web.goBack();
} else {
Toast.makeText(this, "You can't go more back!", Toast.LENGTH_SHORT).show();
}
break;
case R.id.f:
if (web.canGoForward()) {
web.goForward();
} else {
Toast.makeText(this, "You can't go more foward!", Toast.LENGTH_SHORT).show();
}
break;
}
return false;
}}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (userPressedKey) {
if (keyCode == KeyEvent.KEYCODE_SPACE) {
adress.setText("");
return true;
}
}
super.onKeyDown(keyCode, event);
}
I have one activity in which there is a webview. when the webview goes to a few pages and I click the back button on the device runs fine, but if I click the back button in the actionbar then return it wrong.
can I make function back button in action bar like back button in the device?
this is my code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tes_backbutton);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
view = (WebView)findViewById(R.id.wv_tes);
progressBar = (ProgressBar)findViewById(R.id.prgbarhome);
view.setWebViewClient(new WebViewClient());
view.loadUrl(URL);
view.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//Required functionality here
return super.onJsAlert(view, url, message, result);
}
});
view.setWebViewClient(new WebViewClient() {
ProgressDialog progressDialog;
//Show loader on url load
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (progressDialog == null) {
// in standard case YourActivity.this
progressDialog = new ProgressDialog(tes_backbutton.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
}
public void onPageFinished(WebView view, String url) {
try {
progressDialog.dismiss();
progressDialog = null;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Intent myIntent = new Intent(tes_backbutton.this, main_noconnect.class);
tes_backbutton.this.startActivity(myIntent);
}
});
view.canGoBack();
view.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == MotionEvent.ACTION_UP
&& view.canGoBack()) {
view.goBack();
return true;
}
return false;
}
});
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
You need to override onOptionsItemSelected method if you want to take any action after back arrow is clicked from action bar like below
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
onBackPressed(); //finishes the activity
return true;
}
return super.onOptionsItemSelected(menuItem);
}
The 'back' button in the action bar should act differently than the device's back button. You don't want them both to do the same thing. The button in the action bar should serve as an 'up' button rather than a 'back' button. Please read more about Providing Up Navigation.
I hope this helps you.
you can use onBackPressed(); method
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
if(mWebView.canGoBack() == true){
mWebView.goBack();
}else{
onBackPressed(); //finishes the activity
}
return true;
}
return super.onOptionsItemSelected(menuItem);
}
you can use webview.cangoback() method for navigating between different web pages in webview
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
if(view.cangoback()){
view.goback();
}
else{
finish();
}
break;
}
return super.onOptionsItemSelected(menuItem);
}
I am having an issue with the back button in my android app. I am trying to have it go back through the previous pages and if unable then to exit. I pick through the code on the developer website and nothing is working. I would appreciate any help.
Below is my activity page:
WebView webView;
#SuppressLint("SetJavaScriptEnabled")
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient(new myWebView());
webView.loadUrl("http://google.com");
webView.setInitialScale(1);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setUseWideViewPort(true);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.diabetes_meal_planner, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case R.id.action_settings:
//exits app
finish();
break;
default:
break;
}
return true;
}
private class myWebView extends WebViewClient
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if(url.startsWith("mailto:"))
{
String[] email = url.split(":");
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{email[1]});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Send_Us_Your_Email");
Log.v("NOTICE", "Sending Email to" + email[1] + "with subject" + "Send Us Your Feedback");
startActivity(emailIntent);
}
view.loadUrl(url);
return true;
}
}
Dont do this onKeyDown. Override Activity.onBackPressed to do this..
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView!=null && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
Try this at the end, works in my webview app
UPDATE: Solved! Problem was related to my Viewpager not WebView.
I'm trying to add a "Go Back" function to my WebView which is inside a Fragment. But I can't figure out how to:
public final class TestFragment extends Fragment {
static WebView mWeb;
private View mContentView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
mContentView = inflater.inflate(R.layout.webview, null);
mWeb = (WebView)mContentView.findViewById(R.id.webview);
WebSettings settings = mWeb.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(false);
mWeb.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mWeb.getSettings().setBuiltInZoomControls(false);
mWeb.loadUrl("myurl...");
mWeb.setOnKeyListener(new OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
mWeb.goBack();
return true;
}
return false;
}
});
}
}
I also tried something like:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
mWeb.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
Another solution but same problem:
#Override
public void onBackPressed()
{
if(webView.canGoBack())
webView.goBack();
else
super.onBackPressed();
}
Any ideas how to get this working?
Perhaps its android restriction. Try to do this using handler.
public final class TestFragment extends Fragment {
static WebView mWeb;
private View mContentView;
private Handler handler = new Handler(){
#Override
public void handleMessage(Message message) {
switch (message.what) {
case 1:{
webViewGoBack();
}break;
}
}
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
mContentView = inflater.inflate(R.layout.webview, null);
mWeb = (WebView)mContentView.findViewById(R.id.webview);
WebSettings settings = mWeb.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(false);
mWeb.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mWeb.getSettings().setBuiltInZoomControls(false);
mWeb.loadUrl("myurl...");
mWeb.setOnKeyListener(new OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == MotionEvent.ACTION_UP
&& mWeb.canGoBack()) {
handler.sendEmptyMessage(1);
return true;
}
return false;
}
});
}
private void webViewGoBack(){
mWeb.goBack();
}
}
You can check this code :
webView.canGoBack();
webView.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == MotionEvent.ACTION_UP
&& webView.canGoBack()) {
webView.goBack();
return true;
}
return false;
}
});
Actually you can not do directly inside the fragment. The onBackPressed can be overridden in the FragmentActivity. What you can do is:
Override the onBackPressed inside the activity.
When the onBackPressed is called, check if the instance of the current fragment is the instance showing the webview.
If it is, ask the fragment if the webview can go back.
if it is not, call the super or whatever you need
Edit:
#Override
public void onBackPressed() {
Fragment webview = getSupportFragmentManager().findFragmentByTag("webview");
if (webview instanceof MyWebViewFragment) {
boolean goback = ((MyWebViewFragment)webview).canGoBack();
if (!goback)
super.onBackPressed();
}
}
I've created a simple interface:
public interface IOnBackPressed {
boolean onBackPressed();
}
in the Activity:
public class MyActivity extends Activity {
#Override public void onBackPressed() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
if (!(fragment instanceof IOnBackPressed) || !((IOnBackPressed) fragment).onBackPressed()) {
super.onBackPressed();
}
}
}
in the Fragment:
public class MyFragment extends Fragment implements IOnBackPressed {
#Override
public boolean onBackPressed() {
if (webview.canGoBack()) {
webview.goBack();
// backpress is not considered in the Activity
return true;
} else {
// activity will act normal
return false;
}
}
}
In WebViewActivity.java, I added 1 method:
#Override
public void onBackPressed() {
WebViewFragment fragment = (WebViewFragment)
getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
if (fragment.canGoBack()) {
fragment.goBack();
} else {
super.onBackPressed();
}
}
In WebViewFragment.java, I added 2 methods:
public boolean canGoBack() {
return mWebView.canGoBack();
}
public void goBack() {
mWebView.goBack();
}
#RomanBlack's answer gave me the right idea, but since we use kotlin I had to adapt the answer a little bit.
webView.setOnKeyListener { _, _, keyEvent ->
if (keyEvent.keyCode == KeyEvent.KEYCODE_BACK && !webView.canGoBack()) {
false
} else if (keyEvent.keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == MotionEvent.ACTION_UP) {
webView.goBack()
true
} else true
}
if you want to do it with returns you have to add something like:
return#setOnKeyListener true
There is a simple way with BackPressedDispatcher
Fragment:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if(webView.canGoBack()){
webView.goBack()
} else {
isEnabled = false
requireActivity().onBackPressed()
}
}
}
requireActivity().onBackPressedDispatcher.addCallback(this,callback)
}
Activity :
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentByTag("WebViewFragment")
if (WebViewFragment::class.java.isInstance(fragment)) {
if (onBackPressedDispatcher.hasEnabledCallbacks()) {
onBackPressedDispatcher.onBackPressed()
return
}
super.onBackPressed()
}
}
Maybe these codes can be improved, but it works very well for me. For more information visit here.
my solution was in fragment I added to public methods
public static boolean canGoBack(){
return mWebView.canGoBack();
}
public static void goBack(){
mWebView.goBack();
}
then from activity I call
#Override
public void onBackPressed() {
if(webFragment.canGoBack()){
webFragment.goBack();
}else{
super.onBackPressed();
}
}
note The mwebview is static
you can do this by :
in the Activity put :
// Set WebView
public void setWebView(WebView web) {
this.web = web;
}
in the web fragment after ActivityCreated() put:
((Your_Activity) getActivity()).setWebView(webView);
Don't forget to set webView from the onCreateView() like these:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
webView = (WebView) inflater.inflate(R.layout.your_web_fragment, container,
false);
return web;
}
#OmidAmnivia answer is correct your app the solution to the crash is
#Override
public void onBackPressed() {
if(webFragment.isInitialized && webFragment.canGoBack()){
webFragment.goBack();
}else{
super.onBackPressed();
}
}
You have to check whether your class has been initialised or not.
This is how I did in my app. I consume back press event till web view can go back. Once web view cant go back I show hint to user that if he keep on pressing back then app will exit.
It will give user a chance to stay in your app when webview cant go back. I felt it more user friendly:
//time passed between two back presses.
private val TIME_INTERVAL = 200
// variable to keep track of last back press
private var mBackPressed: Long = 0
webView!!.requestFocus()
webView.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.action == MotionEvent.ACTION_UP
) {
if(webView.canGoBack()) {
//go back in previous page
webView.goBack()
return#OnKeyListener true
}
else
{
if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis())
{ // dont consume back press and pass to super
return#OnKeyListener false
}
else {
// show hint for double back press
Toast.makeText(context, " Double Tap back button to exit the demo", Toast.LENGTH_SHORT).show();
mBackPressed = System.currentTimeMillis();
return#OnKeyListener true
}
}
}
return#OnKeyListener false
})
First of all get back pressed in fragment
mContentView.setFocusableInTouchMode(true);
mContentView.requestFocus();
mContentView.setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack())
{
mWebView.goBack();
return true;
}
return false;
}
} );
hope it will works.
This worked in my case
public class FantasyFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
WebView webview;
SwipeRefreshLayout swipeLayout;
String currentUrl="https://www.stackoverflow.com/";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_stadium, container, false);
swipeLayout = (SwipeRefreshLayout) root.findViewById(R.id.swipescreen);
swipeLayout.setOnRefreshListener(this);
return root;
}
#Override
public void onStart() {
super.onStart();
LoadWeb();
}
public void LoadWeb() {
webview = (WebView) getActivity().findViewById(R.id.webview786);
swipeLayout.setRefreshing(true);
webview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
webview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webview.getSettings().setAppCacheEnabled(true);
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webSettings.setUseWideViewPort(true);
webSettings.setSavePassword(true);
webSettings.setSaveFormData(true);
webSettings.setEnableSmoothTransition(true);
webview.loadUrl(currentUrl);
webview.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Snackbar.make(view, "Connection Error", Snackbar.LENGTH_LONG)
.setAction("Retry", new View.OnClickListener() {
#Override
public void onClick(View v) {
LoadWeb();
}
}).show();
}
#Override
public void onPageFinished(WebView view, String url) {
swipeLayout.setRefreshing(false);
currentUrl = url;
super.onPageFinished(view, url);
}
});
webview.canGoBack();
webview.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == MotionEvent.ACTION_UP
&& webview.canGoBack()) {
webview.goBack();
return true;
}
return false;
}
});
}
#Override
public void onRefresh() {
LoadWeb();
}
}
The simplest answer is jut to setOnKeyListeneron into webView itself:
webView.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey( View v, int keyCode, KeyEvent event ) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if( keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()){
webView.goBack();
return true;
}
}
return false;
}
});
My android application contains a webview. But i have a problem, because when i check some checkboxes inside the website and navigate to another website via a link on the site itself, and then go back to the checkbox site, the checkboxes are unchecked again. something that doesn't happen inside the default android webbrowser. How can i fix this??? Please help and thanks in advance. I am using this code:
public class finnActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
Button TilbakeButton;
WebView FinnWeb;
private String currentURL;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FinnWeb = (WebView)findViewById(R.id.FinnWeb);
FinnWeb.setWebViewClient(new MyWebViewClient());
FinnWeb.getSettings().setBuiltInZoomControls(true);
FinnWeb.getSettings().setJavaScriptEnabled(true);
FinnWeb.loadUrl("http://m.finn.no");
FinnWeb.requestFocus(View.FOCUS_DOWN);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
if (FinnWeb.canGoBack()) {
FinnWeb.goBack();
}
else {
System.exit(0);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onCreateOptionsMenu(Menu meny) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menubuttons, meny);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.LoggInn:
setContentView(R.layout.main);
FinnWeb = (WebView) findViewById(R.id.FinnWeb);
FinnWeb.setWebViewClient(new MyWebViewClient());
FinnWeb.getSettings().setJavaScriptEnabled(true);
FinnWeb.loadUrl("http://m.finn.no/#loginForm.html");
FinnWeb.requestFocus(View.FOCUS_DOWN);
break;
case R.id.OmUtvikler:
setContentView(R.layout.omutvikler);
TilbakeButton = (Button)findViewById(R.id.TilbakeButton);
TilbakeButton.setOnClickListener(this);
break;
case R.id.RegistrerDeg:
setContentView(R.layout.main);
FinnWeb = (WebView) findViewById(R.id.FinnWeb);
FinnWeb.setWebViewClient(new MyWebViewClient());
FinnWeb.getSettings().setJavaScriptEnabled(true);
FinnWeb.loadUrl("http://m.finn.no/#auth/registrer.html");
FinnWeb.requestFocus(View.FOCUS_DOWN);
break;
case R.id.Tilbake:
if (FinnWeb.canGoBack()) {
FinnWeb.goBack();
}
else{
}
break;
case R.id.Frem:
if (FinnWeb.canGoForward()) {
FinnWeb.goForward();
}
else{
}
break;
case R.id.ExitWithSaving:
FinnWeb.saveState(null);
System.exit(0);
break;
case R.id.Exit:
System.exit(0);
break;
case R.id.LastAnnose:
FinnWeb.restoreState(null);
break;
}
return true;
}
public void onClick(View src) {
switch(src.getId()) {
case R.id.TilbakeButton:
setContentView(R.layout.main);
FinnWeb = (WebView) findViewById(R.id.FinnWeb);
FinnWeb.setWebViewClient(new MyWebViewClient());
FinnWeb.getSettings().setJavaScriptEnabled(true);
FinnWeb.getSettings().setBuiltInZoomControls(true);
FinnWeb.requestFocus(View.FOCUS_DOWN);
break;
}
}
public boolean shouldOverrideUrlLoading(WebView view, String url)
{ view.loadUrl(url);
//save off url in instance variable
return true;
}
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}