0

Androidのサーバーからzipファイルをダウンロードしたいのですが、そのために以下のコードを使用しています。また、URL接続のリクエストでユーザー名とパスワードを渡すために、承認が必要です。しかし、私は常に401-Response code(UNAUTHORIZED)を取得しています。

コード:-

protected String doInBackground(final String... params) {
            int count;
            try {
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    /*Authenticator.setDefault(new Authenticator(){
                        protected PasswordAuthentication getPasswordAuthentication() {
                            return new PasswordAuthentication(Constants.USERNAME,Constants.PASSWORD.toCharArray());
                        }});*/

                    Log.i(TAG, "URL == " + params[0]);
                    final URL url = new URL(params[0]);
                    final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    final String auth = new String(Constants.USERNAME + ":" + Constants.PASSWORD);
                    connection.setRequestProperty("Authorization", "Basic " + Base64.encodeToString(auth.getBytes(), Base64.URL_SAFE));
                    //connection.addRequestProperty("Authorization", "Basic " + Base64.encodeToString(auth.getBytes(), Base64.DEFAULT));
                    connection.setUseCaches(false);
                    connection.setConnectTimeout(5000);
                    connection.setDoOutput(true);
                    connection.connect();
                    Log.i(TAG, "Response == " + connection.getResponseMessage());
                    Log.i(TAG, "Response Code == " + connection.getResponseCode());

                    // download the file
                    final InputStream input = new BufferedInputStream(connection.getInputStream());
                    // Path to the just created empty db

                    // this will be useful so that you can show a tipical 0-100% progress bar
                    lenghtOfFile = connection.getContentLength();
                    lengthOfFileInMB = lenghtOfFile / 1048576;
                    Log.i(TAG, "File Size in MB = " + lengthOfFileInMB);

                    outFileName = Environment.getExternalStorageDirectory() + File.separator + ZIP_NAME;
                    final File file = new File(outFileName);
                    if (!file.exists()) {
                        file.createNewFile();
                    }

                    // Output stream
                    final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
                    final byte data[] = new byte[lenghtOfFile];
                    long total = 0;

                    while ((count = input.read(data)) != -1) {
                        total += count;
                        publishProgress("" + total);
                        bufferedOutputStream.write(data, 0, count);
                    }
                    bufferedOutputStream.flush();
                    bufferedOutputStream.close();
                    input.close();
                } else {
                    Toast.makeText(DashboardActivity.this, "MEDIA IS NOT MOUNTED.", Toast.LENGTH_LONG).show();
                }
            } catch (final MalformedURLException e) {
                flag = false;
                Log.e(TAG, e.getMessage(), e);
            } catch (final FileNotFoundException e) {
                flag = false;
                Log.e(TAG, e.getMessage(), e);
            } catch (final IOException e) {
                flag = false;
                Log.e(TAG, e.getMessage(), e);
            } catch (final Exception e) {
                Log.e(TAG, e.getMessage(), e);
            }

            return null;
        }

同じサーバーにWebサービスがあり、JSON / XML応答を取得するために、DefaultHttpClientを使用しました。これは完全に正常に機能しており、応答コードもOKになっています。URLConnectionの時点でなぜ許可されていないのかわかりません。

これがそのコードです。

String line = null;
        try {
            final URL urlObj = new URL(url);
            final HttpHost host = new HttpHost(urlObj.getHost(), urlObj.getPort(), urlObj.getProtocol());
            final HttpParams httpParameters = new BasicHttpParams();
            // Set the timeout in milliseconds until a connection is established.
            HttpConnectionParams.setConnectionTimeout(httpParameters, Constants.CONNECTION_TIME_OUT);
            // Set the default socket timeout (SO_TIMEOUT) 
            // in milliseconds which is the timeout for waiting for data.
            HttpConnectionParams.setSoTimeout(httpParameters, Constants.CONNECTION_TIME_OUT);

            final DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
            final AuthScope scope = new AuthScope(urlObj.getHost(), urlObj.getPort());
            final UsernamePasswordCredentials creds = new UsernamePasswordCredentials(Constants.USERNAME, Constants.PASSWORD);
            final CredentialsProvider credentialProvider = new BasicCredentialsProvider();
            credentialProvider.setCredentials(scope, creds);
            final HttpContext credContext = new BasicHttpContext();
            credContext.setAttribute(ClientContext.CREDS_PROVIDER, credentialProvider);

            final HttpGet job = new HttpGet(url);
            job.addHeader("USER-AGENT", userAgentString);
            final HttpResponse httpResponse = httpClient.execute(host,job,credContext);

            final HttpEntity httpEntity = httpResponse.getEntity();

            try {
                line = EntityUtils.toString(httpEntity);
            } catch (final ParseException e) {
                line = "Error";
                Log.e("Parse Error", e.getMessage().toString());
            } catch (final IOException e) {
                line = "Error";
                Log.e("IOException Error", e.getMessage().toString());
            }
            final StatusLine status = httpResponse.getStatusLine();
            Log.d("Authentication Status = ", status.toString());
        } catch (final ClientProtocolException e1) {
            line = "Error";
            Log.e("ClientPrtocol Error", e1.getMessage().toString());
        } catch (final ConnectTimeoutException e1) {
            line = "ConnectionTimeOut";
            Log.e("Connection Error", e1.getMessage().toString());
        } catch (final IOException e1) {
            Log.e("IO Error", e1.getMessage().toString());
            line = "Error";
        }

また、認証のためにURLConnectionに次のコードを追加しようとしましたが、それも機能しませんでした。

Authenticator.setDefault(new Authenticator() {
  protected PasswordAuthentication getPasswordAuthentication() {
     return new PasswordAuthentication(loginNameString, passwordString.toCharArray());
  }
});

質問:-

1)サーバー側またはAndroid側で問題がありますか?

2)私が持っているdefaulthttpclientコードを使用してファイルをダウンロードできますか?はいの場合、ダウンロード方法の手がかりがあります。ファイル全体ではなく、その方法でしかコンテンツを取得できないと思うからです。

4

2 に答える 2

1

HttpClientを使用する方が簡単な方法のようですが、これはAndroidでも利用できます。

あなたのコードは私には問題ないように見えるので、認証の部分はスキップします。あなたのコメントに基づいて、以下のコードのダウンロード部分は機能するはずです。これは、私自身のプロジェクトからの典型的な読み取りとコピーと書き込みのIOオペコードです。

   HttpGet httpget = new HttpGet(url);
    //
    // Authorization configuration code here ...
    // 
    HttpResponse response = httpClient.execute(httpget);
    HttpEntity entity = response.getEntity();

    //
    // The content is all cached in memory for demonstration only, 
    // you can also write to file system using FileOutputStream.
    //
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    if (entity != null) {
        InputStream inputStream = entity.getContent();

        byte[] buf = new byte[1024];
        int read = 0;

        try {
            while ((read = is.read(buf)) >= 0) {
                baos.write(buf, 0, read);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {is.close();} catch (Exception ex) {}
            try {baos.close();} catch (Exception ex) {}
        }
    }

    byte[] content = baos.toByteArray();
于 2013-01-25T05:02:42.550 に答える
0

追加する必要があると思います。connection.setDoInput(true)そうしないと、入力ストリームを取得できないと確信しています(同じ接続で両方doInputdoOutputtrueを使用できます)。これでは正確な問題に答えられない場合がありますが、ダウンロードできなくなります。

編集:setDoInput(true)がないとダウンロードが妨げられる可能性があり、コードにそれが表示されません

于 2013-01-23T03:41:41.770 に答える