在 Android 中使用 JCIFS

Using JCIFS in Android

情况如下: 我想在代码中验证我的 Android 设备,通过将用户名和密码发送到特定 URL,此 URL 将具有内部和外部访问权限。 通过阅读 JCIFS Library 的主要工作是使用 NTML 连接到 windows,试图让它在 android 中工作,我插入了这段代码:

        new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {

            try {
                String user = "username";
                String pass = "password";
                String sharedFolder = "shared";
                String url = "smb://url/url//" + sharedFolder + "/test.txt";
                NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(
                        null, user, pass);
                SmbFile sfile = new SmbFile(url, auth);
                sfile.canRead();
            } catch (Exception e) {
                e.printStackTrace();
            }




            return null;
        }
    }.execute();

此示例代码我仅用于从 Windows 获得授权进入我的 Android 应用程序,我只想 return 授权,而不是复制文件或比较文件。 我在阅读 UrlConnection and UrlStreamHandler 后失败了,并且尝试了 Whosebug 中的几乎所有问题,但我没有找到答案。

同样,当我应用此代码时,出现的消息是

02-21 04:50:02.329 3032-3046/ils.com.ntmlproject W/System.err: jcifs.smb.SmbException: Failed to connect to server
02-21 04:50:02.329 3032-3046/ils.com.ntmlproject W/System.err: java.net.UnknownHostException: jorphp01
02-21 04:50:02.329 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.UniAddress.getAllByName(UniAddress.java:315)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.getFirstAddress(SmbFile.java:864)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.connect(SmbFile.java:954)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.connect0(SmbFile.java:880)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.queryPath(SmbFile.java:1338)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.exists(SmbFile.java:1420)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.canRead(SmbFile.java:1462)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at ils.com.ntmlproject.MainActivity.doInBackground(MainActivity.java:51)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at ils.com.ntmlproject.MainActivity.doInBackground(MainActivity.java:39)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at android.os.AsyncTask.call(AsyncTask.java:287)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:230)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.lang.Thread.run(Thread.java:841)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.connect0(SmbFile.java:882)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.queryPath(SmbFile.java:1338)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.exists(SmbFile.java:1420)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at jcifs.smb.SmbFile.canRead(SmbFile.java:1462)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at ils.com.ntmlproject.MainActivity.doInBackground(MainActivity.java:51)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at ils.com.ntmlproject.MainActivity.doInBackground(MainActivity.java:39)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at android.os.AsyncTask.call(AsyncTask.java:287)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:230)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-21 04:50:02.339 3032-3046/ils.com.ntmlproject W/System.err:     at java.lang.Thread.run(Thread.java:841)

不知道是不是http协议的问题?或者在代码中? 我需要在这里调整什么以及我错过了什么?

主机名:jorphp01 无法从执行代码的设备中解析。以下是可能的解决方案:

  1. 尝试将设备连接到同一网络并确保它通过可以解析此主机名的同一 DNS 服务器。
  2. 如果服务器可达,但DNS解析失败,请修改配置的DNS服务器。可以借助 https://play.google.com/store/apps/details?id=uk.co.mytechie.setDNS&hl=en
  3. 等应用
  4. 尝试在设备上的客户端应用程序中配置 IP 地址而不是主机名。
  5. 修改 /etc/hosts 文件(在有根设备上)以将主机名解析为首选 IP 地址。参考:https://www.howtogeek.com/140576/how-to-edit-the-hosts-file-on-android-and-block-web-sites/

我发现错误是什么情况以及我的情况的解决方案。 首先感谢@Pavan Kumar 回答问题并给了我一些提示。

  1. 无法通过 Android 访问我尝试访问的服务器,因此我使用了服务器的 IP 地址而不是其名称。
  2. 我在网络连接中应用了 OkHTTP,使用 jcifs 库通过这种方法连接到我的服务器,在我的情况下效果很好:

    final TextView textView = (TextView) findViewById(R.id.tvResponse);
    
    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
    
            HttpUrl.Builder urlBuilder = HttpUrl.parse("http://10.10.6.4/erpapi/").newBuilder();
            String url = urlBuilder.build().toString();
            // issue the Get request
            String getResponse = "";
            try {
                getResponse = doGetRequest(url);
                System.out.println(getResponse);
            } catch (IOException e) {
                e.printStackTrace();
                getResponse = e.getMessage();
            }
    
            return getResponse;
        }
    
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            textView.setText(s.toString().toLowerCase());
        }
    }.execute();
    

函数是:

static String doGetRequest(String url) throws IOException {
        okHttpClient = new OkHttpClient.Builder()
                .authenticator(new NTMLAuthenticator("username", "password"))
                .build();
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response = okHttpClient.newCall(request).execute();
        return response.body().string();}

source of this code,并使用了 jcifs 库进行身份验证。

在此之后我可以轻松登录到服务器并发送经过身份验证的信息。

此外,还有一些有用的资源可供查看:

httpclient

android-ntlm

ntlm-authentication-in-android

android-smb-cifs