1

I am coding an app which uses a webview to display HTML files. When the user clicks search this code is ran:

public void search() {   
    container = (LinearLayout)findViewById(R.id.layoutId);

    nextButton = new Button(this);   
    nextButton.setText("Next");   
    nextButton.setOnClickListener(new OnClickListener(){   
        @Override  
        public void onClick(View v){   
            mWebView.findNext(true);   
        }   
    });   
    container.addView(nextButton); 

    closeButton = new Button(this);   
    closeButton.setText("Close");   
    closeButton.setOnClickListener(new OnClickListener(){   
        @Override  
        public void onClick(View v){   
            container.removeAllViews();   

        }   
    });   
    container.addView(closeButton);   

    findBox = new EditText(this);   
    findBox.setMinEms(30);   
    findBox.setSingleLine(true);   
    findBox.setHint("Search");   

    findBox.setOnKeyListener(new OnKeyListener(){   
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event){   
            if((event.getAction() == KeyEvent.ACTION_DOWN) && ((keyCode == KeyEvent.KEYCODE_ENTER))){   
                mWebView.findAll(findBox.getText().toString());   

                try{   
                    Method m = WebView.class.getMethod("setFindIsUp", Boolean.TYPE);   
                    m.invoke(mWebView, true);   
                }catch(Exception ignored){}   
            }   
            return false;   
        }   
    });

}

The code I'm using runs fine generally, with some bugs in Android 4.0. I would like a solution as presented in the Android Browser, where the top bar becomes the search area.

When I have tried to implement this I have failed. Is there a way to properly implement this into a webview for an Android application? I would like a more elegant and functional design than what I currently use.

Thank you to all replies

Edit

For users in the future, this bug is only present in the following Android version:

Platform Version        API Level   VERSION_CODE
Android 4.0.3, 4.0.4    15          ICE_CREAM_SANDWICH_MR1
user1363871
  • 580
  • 3
  • 11
  • 29
  • I have tried to search the Android source code to see how this is being done, I cannot find what happens next. The only other references I could find to findOnPage() are in UI.java and browser.xml. Neither of these led anywhere else for me to understand how to implement this. – user1363871 Aug 16 '13 at 15:21

2 Answers2

2

Other posts (such as this and this discuss this issue. Deriving my answer from these sources, something like this should do the trick:

try{   
    Method m = WebView.class.getMethod("findAllAsync", new Class<?>[]{String.class});
    m.invoke(mWebView, findBox.getText().toString());  
} catch(Throwable notIgnored){
    mWebView.findAll();
    try {
        m = WebView.class.getMethod("setFindIsUp", Boolean.TYPE);   
        m.invoke(mWebView, true); 
    } catch (Throwable ignored){}
} 
Community
  • 1
  • 1
Phil
  • 35,852
  • 23
  • 123
  • 164
  • Thank you for the solution, I solved this problem a couple days ago for myself but this code segment will surely help others who suffer from the problem. – user1363871 Aug 23 '13 at 18:45
  • @user1363871 no problem! Feel free to give out the bounty if you think this is helpful:) – Phil Aug 24 '13 at 04:33
  • I changed my answer to yours, it is the correct implementation since showFindDialog is depreciated. I am curious though, if you are still around do you know what a nice looking implementation of this would be - one that shows the searchbar in the actionbar and not buttons placed in the webview? I have been searching but haven't found anything quite like that which I seek. – user1363871 Apr 28 '14 at 03:18
  • @user1363871 This sounds like a separate question - so you may want to post it elsewhere. However, I would imagine a simple example including the use of the `SearchView`(http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget), and overriding the search query methods to use the *findAllAsync* method described above. I have not done this myself, but have created several apps that use the Android `SearchView` in the Action Bar. – Phil Apr 28 '14 at 13:22
0

I discovered the answer is bumping up my minimum SDK version and adding a bit of code. Now I can remove the long bit of search code above.

Edit

Here is the code that I found to work the best, note: this does not highlight in SDK version 15, as noted above. To my knowledge there is no workaround for this.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle your other action bar items...
    int itemId = item.getItemId();
    if (itemId == R.id.Search) {
            search();
    } else if (itemID == R.id.yourstuff){
              blah blah blah
               }
            }

And my search() method:

@SuppressLint("NewApi")
public void search() {

        if (Build.VERSION.SDK_INT >= 11) {
            if (wv != null) {
                wv.showFindDialog(null, true);
            }
        else {
            searchOldMethod();
        }
    } else {
        Toast.makeText(atcSectionWeb.this,
                "Please purchase premium to use this feature.",
                Toast.LENGTH_SHORT).show();
    }
}

The searcholdmethod is the search from the original question.

user1363871
  • 580
  • 3
  • 11
  • 29