如何在Webview中保存用户名和密码

4

目前,我还在学习Android开发的过程中,所以如果我的问题不容易让您理解,请见谅。

我创建了一个Android应用程序,使用RecyclerView显示一组列表,当用户单击列表中的每个名称时,它将重定向到一组不同的网站,并且在WebView中显示。每个网站都有不同的登录页面,我无法控制这些网站。这些网站关闭了他们的cookies,那么在这种情况下是否可能保存用户的用户名和密码呢?

当我包含Facebook、Instagram和Twitter时,我的应用程序可以保存用户名和密码(也许是因为它们保存了cookies)。但是,如果我尝试添加特定网站(具有特殊情况),则用户名和密码不会保存。

由于setSavePassword方法已弃用,我找不到其他实现保存用户名和密码的方式。我已经多次阅读了SharedPreferences、JavaScript和Autofill等内容,但不知道如何正确地将它们实现到我的应用程序中。因为从我所读的大部分内容来看,它需要先有一个登录页面才能保存用户名和密码。

这是我的WebView代码:

public class WebViewActivity extends AppCompatActivity {

    private WebView webView;
    String url = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview);
        
        webView = findViewById(R.id.webView);
        
        WebSettings webSettings = webView.getSettings();
        
        websettings.setDomStorageEnabled(true);
        websettings.setJavaScriptEnabled(true);
        webView.getSettings().setAppCachePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/cache");
        webView.getSettings().setDatabasePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/databases");
        
        if (Build.VERSION.SDK_INT >= 21) {
            CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
        } else {
            CookieManager.getInstance().setAcceptCookie(true);
        }
        
        webView.loadUrl(url);
        
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }
        }
        ...
    }
    
    ...
}

谢谢。


你能在Chrome浏览器上做到这个吗? - nima
编写一个不保存您的用户名和密码的网站。 - nima
我看到了,删除它。 - nima
@nima,你找到实现预期结果的方法了吗? - Gedanggoreng
现在是睡觉的时间了。明天我会工作。 - nima
显示剩余6条评论
2个回答

2
public class WebViewActivity extends AppCompatActivity {

    private WebView webView;
    String url = "";

    class MyJavaScriptInterface {
        MyJavaScriptInterface() {
        }
        @SuppressWarnings("unused")
        @JavascriptInterface
        public void processContent(String user,String pass) {
            Log.e("Remember", "user:"+user+" pass:"+pass);
            if (!(user.length() >= 1 && pass.length() >= 1))
                return;

               
            SharedPreferences sharedPreferences = getContext().getSharedPreferences("UserInformation",MODE_PRIVATE);
            if (sharedPreferences.getBoolean("isClickYes", false)) {
                sharedPreferences.edit().putString("us",user).apply();
                sharedPreferences.edit().putString("pass",pass).apply();
            }

            if (!sharedPreferences.getBoolean("isClickYes", false)) {
                AlertDialog alertDialog = new AlertDialog.Builder(getContext())
                        .setTitle("save information")
                        .setMessage("Are You Want Save Password?")

                        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                sharedPreferences.edit().putString("us",user).apply();
                                sharedPreferences.edit().putString("pass",pass).apply();
                                sharedPreferences.edit().putBoolean("isClickYes",true).apply();
                            }
                        })

                        .setNegativeButton(android.R.string.no, null)
                        .setIcon(android.R.drawable.ic_popup_reminder)
                        .show();
            }

        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview);

        webView = findViewById(R.id.webView);

        WebSettings webSettings = webView.getSettings();

        websettings.setDomStorageEnabled(true);
        websettings.setJavaScriptEnabled(true);
        webView.addJavascriptInterface(new MyJavaScriptInterface(), "INTERFACE");
        webView.getSettings().setAppCachePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/cache");
        webView.getSettings().setDatabasePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/databases");

        if (Build.VERSION.SDK_INT >= 21) {
            CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
        } else {
            CookieManager.getInstance().setAcceptCookie(true);
        }

        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }



private void runOnUi(int page, WebView view ,SharedPreferences sharedPreferences) {
    int LOGIN      = 0;
    int LOGIN_PASS = 1;
    WebViewActivity.this.runOnUiThread(() -> {
        if (page == LOGIN_PASS) {
        view.loadUrl("javascript:(function(){l=document.getElementById(\"formLogin\"); l.setAttribute(\"onclick\",\"" +
                "INTERFACE.processContent(  document.getElementById('txtUserId').value , document.getElementById('txtPassword').value  );\"   );       " + "})()");

        if (sharedPreferences.getBoolean("isClickYes", false)) {
            String pass = sharedPreferences.getString("pass", "");
            view.loadUrl("javascript:(function(){l=document.getElementById('txtPassword');l.value='" + pass + "'; })()");
        }
        } else if (page == LOGIN) {
            String user = sharedPreferences.getString("us", "");
            view.loadUrl("javascript:(function(){l=document.getElementById('txtUserId2');l.value='" + user + "'; })()");
        }
    });
}



            @Nullable
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {




    if (request.getUrl().toString().equals("https/.../....png")) {
        SharedPreferences sharedPreferences = getContext().getSharedPreferences("UserInformation", MODE_PRIVATE);
        if (request.getRequestHeaders().toString().contains("Referer=https/...../loginpass"))
            runOnUi(1, view, sharedPreferences);
        else if (request.getRequestHeaders().toString().contains("Referer=https/...../login"))
            runOnUi(0, view, sharedPreferences);
    }



                return super.shouldInterceptRequest(view, request);
            }
        }
    
    }
    
    webView.loadUrl(url);
    ...
}

我能否将(url + "/login")替换为(""yourLoginUrl")? - Gedanggoreng
你可以把这些代码放在onFinish里面,而不是shouldInterceptRequest。但是onFinish有时会结束得比较晚,我认为这种方法更好。 - nima
请注意,shluldInerceptRequest方法的工作与此不同。当要加载url时,调用任何url(如图像、脚本等)时,将调用此方法。我使用.png的原因是该文件在HTML加载完成后加载。密码字段也会被加载,因此我可以获取其值。我使用此方法而不是onFinish方法,因为我认为onFinish不够准确! - nima
我刚刚给你发送了一封邮件,请求某事。 - Gedanggoreng
我尝试保存http://175.107.63.74/sm3p/login的信息,但失败了。有什么解决办法吗? - Attaullah
显示剩余28条评论

0

不要写那么1000行的代码,可以写成这样

webview.getSettings().setSavePassword(true);

webview.loadUrl("url");

3
此方法已在API级别18中被弃用。来源:https://developer.android.com/reference/android/webkit/WebSettings#setSavePassword(boolean) - Gedanggoreng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接