forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Android (http://forum.boolean.name/forumdisplay.php?f=150)
-   -   Как контролировать WebView? (http://forum.boolean.name/showthread.php?t=16036)

barsunduk 15.12.2011 00:14

Как контролировать WebView?
 
вопрос: Как прочитать текст страницы загруженной в WebView?

на Activity нет никаких элементов управления, кроме WebView. я свободно прыгаю по сайту/сайтам, которые открываются не в стандартном браузере, а в том же WebView (при этом работают скрипты со страниц, например проводится многостраничная регистрация на сайте). мне бы хотелось знать, что отображается на страницах, чтобы отловить какое-то кодовое слово, признак, по которому я решу, что сеанс завершен и закрою Activity, сохранив, полученные данные в глобальных переменных.

как я могу реализовать контроль, в каком методе разместить, какие функции использовать чтобы узнать содержимое загруженной страницы?

сам победить пока не смог, инглишсцуковерибед. есть подозрение, что нужно использовать методы WebViewClient.

PHP код:

package ru.jru.sru;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class 
RegActivity extends Activity {

    private class 
wvClient extends WebViewClient {
        @
Override
        
public boolean shouldOverrideUrlLoading(WebView viewString url) {
            
view.loadUrl(url);
            return 
true;
        }
    }
    
    public 
WebView wvReg;
    
    @
Override
    
public void onConfigurationChanged(Configuration newConfig) {
        
super.onConfigurationChanged(newConfig);
    }
    
    public 
void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        
setContentView(R.layout.regform);
        
wvReg = (WebView)findViewById(R.id.wvReg);
        
wvReg.setWebViewClient(new wvClient());
        
wvReg.getSettings().setJavaScriptEnabled(true);
        
wvReg.loadUrl("http://www.mysite.ru/registration.php?request=newuser");
    }
    
    public 
boolean onKeyDown(int keyCodeKeyEvent event
    {
        if ((
keyCode == KeyEvent.KEYCODE_BACK) && wvReg.canGoBack()) 
        {
            
wvReg.goBack();
            return 
true;
        }
        return 
super.onKeyDown(keyCodeevent);
    }





хотелось бы использовать именно WebView, а не всяческие post-запросы, так как нужно оставить возможность развития и изменения серверной части (регистрационные данные и внешний вид страниц будет со временем меняться).

cyberblut 15.12.2011 00:50

Ответ: Как контролировать WebView?
 
Ох :) Ступил ты на тёмную сторону силы.
Как же я ненавижу гугл с его долбоандроидом за то, что приходится иногда вытворять, чтобы это дерьмо работало. Наверное разработчики этой шняги трахаются с собаками периодически.


А теперь по теме:

1. В своей активити создаёшь вложенный класс и обзываешь например WebViewInjector
2. Создаёшь в нём метод, пускай
PHP код:

String processBody(String body); 

3. Вешаешь свой инъектор на веб вьюху:
PHP код:

webView.addJavascriptInterface(new WebViewInjector(), "WebInjector"); 

4. Создаёшь WebViewClient и ассайнишь своей веб вьюхе
5. В методе клиента onPageFinished вызываешь следующий код:
PHP код:

webView.loadUrl("javascript:window.WebInjector.processBody(document.getElementsByTagName('body')[0].innerHTML);"); 

ИТОГО: в методе processBody на входе окажется всё содержимое тега <body> (ну или любого по твоему усмотрению)

barsunduk 15.12.2011 17:26

Ответ: Как контролировать WebView?
 
Цитата:

Сообщение от cyberblut (Сообщение 213988)
Ох :) Ступил ты на тёмную сторону силы. Как же я ненавижу гугл с его долбоандроидом за то, что приходится иногда вытворять, чтобы это дерьмо работало. Наверное разработчики этой шняги трахаются с собаками периодически.

сначала прочитал часть фразы "Ступил ты..." и хотел было обидеться, но не смог, потому что действительно ступил, ступая на темную сторону. ибо собак я не люблю, а в сексе придерживаюсь традиционных взглядов, что разработчиками андроида явно не приветствуется.

хочу сказать большое спасибо за решение проблемы, ибо в этом вопросе, похоже ни здравый смысл, ни преподобный гугл на путь истинный наставить меня не смогли бы.

маленький подарок любителям копипаста:
PHP код:

package ru.jru.sru;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class 
RegActivity extends Activity {

    private class 
WebViewInjector {
        public 
String processBody(String body) {
            
// если на странице есть NOT FOUND, то закрываем недобраузер
            
int p body.toLowerCase().indexOf("not found");
            
int l body.length();
            if ((
>= 0)&&(l)) {
                
finish();
            }
            return 
body;
        }
    }

    private class 
wvClient extends WebViewClient {
        @
Override
        
public boolean shouldOverrideUrlLoading(WebView viewString url) {
            
// открываем внешние ссылки в том же недобраузере
            
view.loadUrl(url);
            return 
true;
        }
        @
Override
        
public void onPageFinished (WebView viewString url) {
            
// просматриваем содержимое страницы (в нашем случае секция body)
            
super.onPageFinished(viewurl);
            
wvReg.loadUrl("javascript:window.WebInjector.processBody(document.getElementsByTagName('body')[0].innerHTML);");
        }
    }

    public 
WebView wvReg// наш недобраузер
    
    
public void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        
setContentView(R.layout.regform);
        
wvReg = (WebView)findViewById(R.id.wvReg);
        
wvReg.getSettings().setJavaScriptEnabled(true);
        
wvReg.addJavascriptInterface(new WebViewInjector(), "WebInjector");
        
wvReg.setWebViewClient(new wvClient());
        
wvReg.loadUrl("http://www.mysite.ru");
    }
    
    
// возврат на предыдущую страницу по нажатию аппаратной кнопки back
    
public boolean onKeyDown(int keyCodeKeyEvent event
    {
        if ((
keyCode == KeyEvent.KEYCODE_BACK) && wvReg.canGoBack()) 
        {
            
wvReg.goBack();
            return 
true;
        }
        return 
super.onKeyDown(keyCodeevent);
    }




moka 16.12.2011 17:17

Ответ: Как контролировать WebView?
 
Можно поинтересоваться, я конечно в этой сфере много не знаю, но вы правы - метод извратный, т.к. изначально вообще черезжоперный.
Почему бы не использовать сокеты, и установить соединение с веб хостом, который выдаст соответствующий код страницы? А потом уже можно этот код кормить в WebView - если такая возможность есть.. ?

barsunduk 16.12.2011 19:40

Ответ: Как контролировать WebView?
 
Цитата:

Сообщение от MoKa (Сообщение 214160)
Почему бы не использовать сокеты, и установить соединение с веб хостом, который выдаст соответствующий код страницы? А потом уже можно этот код кормить в WebView - если такая возможность есть.. ?

если бы меня устраивал такой вариант, я бы воспользовался одним из стандартных способов, кстати вполне хорошо описанных в этом блоге. но практически в каждом из случаев вышло бы куда больше писанины и использовалось бы большее количество методов и классов. хотя... может быть вы и правы, можно еще немного подумать над оптимизацией, пожалуй...

cyberblut 16.12.2011 19:58

Ответ: Как контролировать WebView?
 
Через URLConnection можно всё прекрасно забирать. Но и там свои косяки/нюансы есть.
1. Надо открывать тред, тк начиная с 3.0 все сетевые операции нельзя проводить на основном треде (читай синхронно)
2. Если лезть по SSL придётся в 90% случаев лепить свой менеджер сертификатов и разрешать идти на неправильно подписанные хосты
3. WebView довольно часто не может правильно прохавать (особенно объёмный) HTML полученный при loadData(). При чём если пути к CSS/JS относительные, надо не забыть отдать корневой URL
4. Так как могут быть косяки с памятью из-за объёмов страницы, придётся всё писать в темповый файл, потом оттуда отдавать веб вьюхе

barsunduk 19.12.2011 22:20

Ответ: Как контролировать WebView?
 
Цитата:

Сообщение от cyberblut (Сообщение 214175)
При чём если пути к CSS/JS относительные, надо не забыть отдать корневой URL

а как и кому отдать этот самый URL?
для отображения локальных страниц (динамически создаваемых в строковых переменных или загружаемых из нижеуказанной папки приложения) я использую разметку css, но файлы графики webview естественно не видит.
причем графика (и некоторые страницы в html) сохраняются тут: "/data/data/ru.jru.sru/files/"
этого потребовал класс openFileInput (ничем другим пользоваться у меня пока не получается)

разметка примерно такая:
PHP код:

<style type="text/css">
    .
msg_container {width95%; background-color#000000; background-color: #ffdd88;}
    
.msg_top_left {height10pxbackground-imageurl(ctl.png); background-repeatno-repeatbackground-color#ffd76b;}
    
.msg_top_right {height10pxbackground-imageurl(ctr.png); background-repeatno-repeatbackground-positionright;}
    .
msg_bottom_left {height10pxbackground-imageurl(cbl.png); background-repeatno-repeatbackground-color#ffd76b;}
    
.msg_bottom_right {height10pxbackground-imageurl(cbr.png); background-repeatno-repeatbackground-positionright;}
    .
msg_body {padding0px 10px 0px 10px;}        
</
style

, где *.png - уголки пузыря.
может мне просто url(*) поменять как-то? (с учетом положения файлов "/data/data/ru.jru.sru/files/")

з.ы.: пробовал так:
PHP код:

webview.loadDataWithBaseURL("/data/data/ru.jru.sru/files/"htmlCode"text/html""utf-8"""); 

предварительно накидав в папку все файлы. не помогло

cyberblut 20.12.2011 00:26

Ответ: Как контролировать WebView?
 
Цитата:

Сообщение от barsunduk (Сообщение 214620)
з.ы.: пробовал так:
PHP код:

webview.loadDataWithBaseURL("/data/data/ru.jru.sru/files/"htmlCode"text/html""utf-8"""); 

предварительно накидав в папку все файлы. не помогло

Попробуй так:

PHP код:

webview.loadDataWithBaseURL("file:///data/data/ru.jru.sru/files/"htmlCode"text/html""utf-8"""); 

Я обычно читаю/пишу через File() + InputStream()/OutputStream().

barsunduk 20.12.2011 20:06

Ответ: Как контролировать WebView?
 
спасибо, работает. я этот вариант пробовал, но оказалось, что проблема в css-разметке (даже в png - прозрачные участки накладывались на одноцветный фон :) и казалось, что картинки не отображаются)

наглость, конечно, но еще вопрос можно?
как WebView пролистать в конец страницы? я такой вариант пробовал:

view.scrollTo(0, view.getContentHeight() - view.getHeight());

и такой:

view.pageDown(true);

и даже такой х_Х:
PHP код:

private class wvLogClient extends WebViewClient {
        @
Override
        
public void onPageFinished (WebView viewString url) {
            
super.onPageFinished(viewurl);
            
view.scrollTo(0view.getContentHeight() - view.getHeight());
        }
    } 

разницы, конечно-же никакой.

не листает зараза, остается на месте ..(
вернее пролистывается в конец и тут же возвращается в начало. зачем?

cyberblut 20.12.2011 21:22

Ответ: Как контролировать WebView?
 
Цитата:

Сообщение от barsunduk (Сообщение 214720)
наглость, конечно, но еще вопрос можно?
как WebView пролистать в конец страницы?

Ну так для того и форум.

Никогда не скроллил, но как вариант:
PHP код:

webView.loadUrl("javascript:window.scrollTo(0, document.body.scrollHeight);"); 


barsunduk 20.12.2011 22:00

Ответ: Как контролировать WebView?
 
отлично шевелится! а я почти 5 часов убил на поиски ответа в гугле и самостоятельные потуги что-то исправить, а скриптом так и не попробовал (веб-разработкой никогда не занимался, вот и не работает мозг в эту сторону).

barsunduk 22.01.2012 00:38

Ответ: Как контролировать WebView?
 
Цитата:

Сообщение от cyberblut (Сообщение 214640)
Я обычно читаю/пишу через File() + InputStream()/OutputStream().

не подскажете, а могу ли я таким способом создать папку для локализации (например "values-ru") и сохранить в нее файл "strings.xml"? хочу переводы с сервера подгружать, чтобы можно было их исправлять и добавлять новые языки уже в процессе использования. уверен, что есть такая возможность, но вот какой путь указывать при создании потока - не "/data/data/package_name/values-ru" случайно?

cyberblut 22.01.2012 02:31

Ответ: Как контролировать WebView?
 
Цитата:

Сообщение от barsunduk (Сообщение 217451)
не подскажете, а могу ли я таким способом создать папку для локализации (например "values-ru") и сохранить в нее файл "strings.xml"? хочу переводы с сервера подгружать, чтобы можно было их исправлять и добавлять новые языки уже в процессе использования. уверен, что есть такая возможность, но вот какой путь указывать при создании потока - не "/data/data/package_name/values-ru" случайно?

Вот уж не знаю. Не было такой задачи у меня пока. По крайней мере под iOS решал через кастомный класс с выборкой из базовых фалов локализации и/или SQLite. Может под андроидом и предусмотрен какой-нить стандартный механизм, но я не уверен.

barsunduk 22.01.2012 13:17

Ответ: Как контролировать WebView?
 
да, что-то я не то опять ляпнул. если рассуждать чисто логически - id для строковых ресурсов, как я понял, генерируются в классе R при компиляции приложения, так что не должно быть возможности их замены уже в процессе исполнения. тяжело быть чайником ..( ну, буду грузить переменные вручную. тем более есть удобный механизм для хранения настроек Shared Preferences.


Часовой пояс GMT +4, время: 19:39.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot