HttpURLConnectionを使用してURLを含むファイルを取得する一般的なコードがいくつかあります。 Android 1.xと2.xでは問題なく動作しましたが、Android 4.1!
ウェブで検索しましたが、同様の情報はほとんど見つかりませんでした。誰かがこの問題の調査を手伝ってくれませんか?
private String mURLStr;
private HttpURLConnection mHttpConnection;
...
url = new URL(mURLStr);
...
mHttpConnection = (HttpURLConnection) url.openConnection();
mHttpConnection.setDoOutput(true);
mHttpConnection.setRequestMethod("GET");
...
InputStream is = mHttpConnection.getInputStream();
GetInputStreamメソッドは例外をスローします。
08-01 15:56:48.856: W/System.err(13613): Java.io.IOException: No authentication challenges found
08-01 15:56:48.856: W/System.err(13613): at libcore.net.http.HttpURLConnectionImpl.getAuthorizationCredentials(HttpURLConnectionImpl.Java:427)
08-01 15:56:48.866: W/System.err(13613): at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.Java:407)
08-01 15:56:48.866: W/System.err(13613): at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.Java:356)
08-01 15:56:48.866: W/System.err(13613): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.Java:292)
08-01 15:56:48.866: W/System.err(13613): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.Java:168)
...
現在、同じ問題に直面しています。 4.1 Jelly Beanでは、HttpURLConnectionでgetResponseCode()を呼び出すと、IOException "No authentication challenge found"が発生します。
Androidソースコードの変更点を確認するためにオンラインで検索したところ、次のものが見つかりました:4.0.4(動作中): https://bitbucket.org/seandroid/libcore /src/7ecbe081ec95/luni/src/main/Java/libcore/net/http/HttpURLConnectionImpl.Java 4.1.1(動作しない): https://bitbucket.org/seandroid/libcore/src /6b27266a2856/luni/src/main/Java/libcore/net/http/HttpURLConnectionImpl.Java
4.1 JBでわかるように、メソッドgetAuthorizationCredentials()はIOExceptionをスローします。応答コードが401または407の場合、HeaderParser.parseChallenges(..)を使用して応答で見つかったチャレンジヘッダーを解析します。返されたリストが空の場合、例外がスローされます。
現在、リストが空になる原因を調査中ですが、サーバーがチャレンジヘッダーでrealm = "..."ではなくrealm = ...を使用している可能性があるという疑いがあります。引用符の欠落がこの問題の原因である可能性があります。それが本当に事実であり、それを機能させることができるかどうか、さらに調査する必要があります。
あたり RFC2617 :
401(無許可)応答メッセージは、ユーザーエージェントの承認を要求するために、オリジンサーバーによって使用されます。この応答には、要求されたリソースに適用可能なチャレンジを少なくとも1つ含むWWW-Authenticateヘッダーフィールドを含める必要があります。
Androidでは、サーバーがWWW-Authenticateヘッダーを設定せずにJava.io.IOException: No authentication challenges found
または401 Unauthorized
ステータスコードを返すと、 HttpURLConnection getResponseCode() メソッドが407 Proxy Authentication Required
をスローします。
サーバーサイドAPIを所有している場合は、401または407を返すときに必要なWWW-Authenticateヘッダーを追加することで修正できます。私の場合は、PHPで次のように修正しました。
header('WWW-Authenticate: OAuth realm="users"');
header('HTTP/1.1 401 Unauthorized');
私は同じ問題を抱えています。この回避策を見つけましたが、Android 2.で機能しません。JellyBeanでは正常に機能します。getInputStream()ではなくgetErrorStream()を使用してください。
try
{
responseStream = new BufferedInputStream(connection.getInputStream());
}
catch(IOException e)
{
responseStream = new BufferedInputStream(connection.getErrorStream());
}
見出し
ジェリービーンの問題を修正しました。上記のシナリオには以下のコードを使用してください
DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(new AuthScope(null, -1), new UsernamePasswordCredentials(userName,userPass));
HttpGet request = new HttpGet();
request.addHeader("Accept", "application/xml");
request.setURI(new URI(service));
HttpResponse response = client.execute(request);
必要に応じて適切な応答が得られます。
1つの解決策があります
あなたのコードでこれを削除してください
ICS
またはJelly bean
で動作します
私がこれに使用したソリューション(私はAndroidのVolleyライブラリを使用しています)は SquareのOkHttpライブラリ を使用することでした。彼らの実装はこの問題を正しく処理し、期待どおりに401を返します。
正しく動作するためにCookieを必要とするWebサービスで同様の問題が発生しました。どうやらJelly Beanはデフォルトでは(以前のバージョンとは異なり)Cookieストアを自動的に作成しないので、サービスはセッションを見つけることができず、アクセスしようとするたびに401をスローしました。次のコード行をアプリケーションの初期化に追加すると、問題が解決しました。
// enable VM-wide cookie support for HttpUrlConnection
// see http://developer.Android.com/reference/Java/net/HttpURLConnection.html for details
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
サーバーがError 401 - Not Authorised
を返しているかどうかを確認します。 Androidコードはその応答を見て、認証の詳細を提供することを意図していたと信じています。私の場合、サーバーに間違ったトークンを提供していただけです。