如何在Android中的ImageView中显示验证码。

时间:2014-01-13 09:27:23

标签: java android imageview captcha

我在Google Play上有一个PNR查询应用。它工作得非常好。但最近Indian Railwys在他们的PNR查询部分添加了验证码,因此我无法将适当的数据传递给服务器以获得适当的响应。如何在我的应用程序中以imageview的形式添加此验证码,并要求用户输入验证码详细信息,以便我可以发送正确的数据并获得适当的响应。

Indian Railways PNR Inquiry Link

enter image description here

2 个答案:

答案 0 :(得分:4)

如果你检查html代码,它的实际上非常糟糕的验证码。 验证码的背景是:http://www.indianrail.gov.in/1.jpg 这些数字在输入标签中是实际的:

<input name="lccp_cap_val" value="14167" id="txtCaptcha" type="hidden">

他们正在做的是,通过javascript,使用隐藏输入标签中的数字 并用“验证码”背景将它们放在那个跨度上。

所以基本上你的流程是:

  • 阅读他们的HTML

  • 从输入字段获取“验证码”(lol,有趣的验证码)

  • 当用户将数据放入您的PNR字段并按下获取状态

  • 发布表单字段,将PNR置于适当的值,将验证码放入适当的值

  • 解析回复

噢,是的,还有一件事。你可以在隐藏输入和“验证码”中加入任何值 输入,只要它们是相同的。他们没有通过会话或 任何东西。

EDIT(提交表单的代码示例): 为了简化发布表单,我推荐Apache的HttpClient组件: http://hc.apache.org/downloads.cgi 让我们说你下载了HttpClient 4.3.1。包括客户端,核心和哑剧 项目中的库(复制到libs文件夹,右键单击项目, 属性,Java构建路径,库,添加Jars - &gt;加上那些。)。

代码示例如下:

private static final String FORM_TARGET = "http://www.indianrail.gov.in/cgi_bin/inet_pnstat_cgi.cgi";
    private static final String INPUT_PNR = "lccp_pnrno1";
    private static final String INPUT_CAPTCHA = "lccp_capinp_val";
    private static final String INPUT_CAPTCHA_HIDDEN = "lccp_cap_val";

    private void getHtml(String userPnr) {
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addTextBody(INPUT_PNR, userPnr); // users PNR code
        builder.addTextBody(INPUT_CAPTCHA, "123456");
        builder.addTextBody("submit", "Get Status");
        builder.addTextBody(INPUT_CAPTCHA_HIDDEN, "123456"); // values don't
                                                                // matter as
                                                                // long as they
                                                                // are the same

        HttpEntity entity = builder.build();

        HttpPost httpPost = new HttpPost(FORM_TARGET);
        httpPost.setEntity(entity);

        HttpClient client = new DefaultHttpClient();

        HttpResponse response = null;
        String htmlString = "";
        try {
            response = client.execute(httpPost);
            htmlString = convertStreamToString(response.getEntity().getContent());
                    // now you can parse this string to get data you require.
        } catch (Exception letsIgnoreItForNow) {
        }
    }

    private static String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException ignoredOnceMore) {
        } finally {
            try {
                is.close();
            } catch (IOException manyIgnoredExceptions) {
            }
        }

        return sb.toString();
    }

此外,请注意,我没有将其包装在异步调用中,因此您必须这样做。

答案 1 :(得分:1)

来自网络的图像可以通过高效的图像加载api(如Picasso / volley)显示在android中,或者只是通过异步任务进行图像查看。

考虑到以上所有内容作为基本构建逻辑,如果用户重置或刷新验证码,您应该需要该验证码的图像URL,它应该通过请求新请求实现的网络调用重新加载新映像,您必须获得REST api进入印度铁路并检查其中可用的任何图像(可能是base64格式)

如果REST API不可用,您可以考虑使用此代码构建自己的服务器

RESTful API to check the PNR Status

pnrapi

更新:您不需要执行此复杂的黑客攻击,只需实施 Drago的答案即可!