如何从webview 中获取表单数据

1. 先分析html 表单

1
2
3
4
5
6
7
8
9
10
<form method="POST" id="login-form" class="adjacent" action="/accounts/login/?force_classic_login=&next=/oauth/authorize/%3Fclient_id%3Dcf2cd88a0b7745a4b4f8ac673190f659%26redirect_uri%3Dhttp%253A%252F%252Finstafollow.elasticbeanstalk.com%252Fredirect.php%253FclientKey%253Dcf2cd88%26response_type%3Dcode">
<input type="hidden" name="csrfmiddlewaretoken" value="fd942039c72570e71786a8a5a13566b5"/>
<p><label for="id_username">��ㄦ�峰��:</label> <input name="username" maxlength="30" autocapitalize="off" autocorrect="off" type="text" id="id_username" /></p>
<p><label for="id_password">瀵����:</label> <input autocapitalize="off" autocorrect="off" type="password" name="password" id="id_password" /></p>
<p class="form-actions">
<a href="/accounts/password/reset/">蹇�璁板�����锛�</a>
<input type="submit" class="button-green" value="��诲��" />
</p>
</form>

写js代码

1
2
3
4
5
6
String javascript = "javascript: document.getElementsByClassName(\"button-green\")[0].onclick = function() {\n" +
" var username = document.getElementById(\"id_username\").value;\n" +
" var password = document.getElementById(\"id_password\").value;\n" +
" bridge.saveData(username, password);\n" +
" };";

2. js调用的java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MyBridge {
private static String mUsername;
private static String mPassword;
Context mContext;
public MyBridge(Context context) {
mContext = context;
}
@JavascriptInterface
public void saveData(String username, String password) {
Toast.makeText(mContext, username + " " + password, Toast.LENGTH_SHORT).show();
mUsername = username;
mPassword = password;
}
public static String getUsername() {
return mUsername;
}
public static String getPassword() {
return mPassword;
}
}

3. 完整的webview布局及实现

布局

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class OAuthActivity extends Activity {
private static final String OAUTH_URI = "https://instagram.com/oauth/authorize/";
public static final String INTENT_KEY_USERNAME = "username";
public static final String INTENT_KEY_PASSWORD = "password";
public static final String INTENT_KEY_REGISTER_DATA = "registerData";
private RegisterData mRegisterData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_oauth);
init();
}
@SuppressLint("SetJavaScriptEnabled")
private void init() {
mRegisterData = (RegisterData) getIntent().getSerializableExtra(INTENT_KEY_REGISTER_DATA);
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new MyBridge(OAuthActivity.this), "bridge");
myWebView.setWebViewClient(new MyWebViewClient());
myWebView.loadUrl(getOAuthUrl());
}
private String getOAuthUrl() {
// https://instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
StringBuilder builder = new StringBuilder();
builder.append(OAUTH_URI);
builder.append("?client_id=" + mRegisterData.getClientId());
builder.append("&redirect_uri=" + Uri.encode(mRegisterData.getRedirectUri()));
builder.append("&response_type=" + mRegisterData.getReponseCode());
String url = builder.toString();
System.out.println("====== getOAuthUrl ====" + url);
return url;
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
System.out.println("====== shouldOverrideUrlLoading url ====" + url);
if (Uri.parse(url).getHost().equals(Uri.parse(mRegisterData.getRedirectUri()).getHost())) {
String error = Uri.parse(url).getQueryParameter("error");
handleReturnCode(error);
CookieSyncManager.createInstance(OAuthActivity.this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
return true;
} else {
return false;
}
}
@Override
public void onPageFinished(WebView view, String url) {
//System.out.println("====== onPageFinished url====" + url);
if (url.contains("login")) {
view.addJavascriptInterface(new MyBridge(OAuthActivity.this), "bridge");
String javascript = "javascript: document.getElementsByClassName(\"button-green\")[0].onclick = function() {\n" +
" var username = document.getElementById(\"id_username\").value;\n" +
" var password = document.getElementById(\"id_password\").value;\n" +
" bridge.saveData(username, password);\n" +
" };";
view.loadUrl(javascript);
}
super.onPageFinished(view, url);
}
}
private void handleReturnCode(String error) {
System.out.println("====== handleReturnCode error ====" + error);
Intent intent = new Intent();
if (error == null) {
intent.putExtra(INTENT_KEY_USERNAME, MyBridge.getUsername());
intent.putExtra(INTENT_KEY_PASSWORD, MyBridge.getPassword());
setResult(RESULT_OK, intent);
} else {
setResult(RESULT_CANCELED, intent);
}
finish();
}
}

4. 调用OAuth 的Activtiy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class MainActivity extends ActionBarActivity {
private static final String CLIENT_ID = "cf2cd88a0b7745a4b4f8ac673190f659";
private static final String REDIRECT_URI = "http://instafollow.elasticbeanstalk.com/redirect.php?clientKey=cf2cd88";
private static final String RESPONSE_TYPE = "code";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickLogin(View v) {
Intent intent = new Intent(this, OAuthActivity.class);
RegisterData registerData = new RegisterData();
registerData.setClientId(CLIENT_ID);
registerData.setRedirectUri(REDIRECT_URI);
registerData.setReponseCode(RESPONSE_TYPE);
intent.putExtra(OAuthActivity.INTENT_KEY_REGISTER_DATA,registerData);
startActivityForResult(intent, 200);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != 200) return;
if (resultCode == RESULT_OK) {
Toast.makeText(this, "success " + data.getStringExtra(OAuthActivity.INTENT_KEY_USERNAME)
+ data.getStringExtra(OAuthActivity.INTENT_KEY_PASSWORD), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "fail ", Toast.LENGTH_SHORT).show();
}
}
}