2013年9月25日水曜日

Volleyを使ってみる(ベーシック認証編)

Volleyを使ってAPIとの連動をさせようとしたらベーシック認証が必要だったのでその際のメモになります(ΦωΦ)フフフ…

Volleyでベーシック認証を適用するやり方としては次の2つ?があるみたいです。
・newRequestQueueの第2引数でネットワークの設定を行う。(NetworkImageViewを利用する場合にはこちらだけ?)
・getHeadersをオーバーライドする方法。

今回は、getHeadersをオーバーライドする方法で行いたいと思います!(`・ω・´)シャキーン
処理は主に以前の「Volleyを使ってみる(StringRequest編) 」をそのまま利用して、
ベーシック認証の処理だけを追加している感じになっています。

Base64エンコードにはこちらのサイトのものをそのまま拝借させてもらいました。ありがとうございますъ(゚Д゚)グッジョブ!!
twitter APIに接続するためのjavaコード

ベーシック認証でエラーになっている場合には、次のようなエラーが表示されていると思います。
09-25 09:54:01.166: E/Volley(1556): [15] BasicNetwork.performRequest: Unexpected response code 401 for リクエストURL

■AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.volleyexample4"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />

    <!-- インターネットへのアクセスを許可 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.volleyexample4.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
■activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
</RelativeLayout>

■MainActivity.java
package com.example.volleyexample4;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.Toast;

public class MainActivity extends Activity {

 //ログ出力時のタグ名
 private static final String TAG_LOG = "Log";
 //Volleyでリクエスト時に設定するタグ名。キャンセル時に利用する。
 private static final Object TAG_REQUEST_QUEUE = new Object();
 //リクエスト先
 private static final String REQUEST_URL_RESEPONSE_STRING = "リクエスト先";
 //RequestQueueのインスタンス用
 private RequestQueue mRequestQueue;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  //RequestQueueのインスタンス用を取得
  mRequestQueue = Volley.newRequestQueue(getApplicationContext());
  
 }

 /*
  * onCreateの後に呼び出される。
  */
 @Override
 public void onStart(){
  super.onStart();
  //HTTPリクエストを行う
  requestString();
 }
 
 /*
  * アプリが見えなくなったときに呼び出される。
  * (他のアプリを立ち上げたりした時など)
  */
 @Override
 public void onStop(){
  super.onStop();
  mRequestQueue.cancelAll(TAG_REQUEST_QUEUE);
 }
 /*
  * 
  */
 private void requestString(){
  
  //リクエスト&レスポンス情報の設定
  //StringRequestの場合
  StringRequest request = new StringRequest(
   //送信方法 GET/POST
   Request.Method.GET, 
   //送信先
   REQUEST_URL_RESEPONSE_STRING,
   //レスポンス成功時のリスナー
   new Response.Listener<String>() {
    @Override 
    public void onResponse(String response) {
     
     //レスポンス受け取り時の処理
     if (response == null){
      //空の場合
      return;
     }
     //
     Toast.makeText(getApplicationContext(), response, Toast.LENGTH_LONG).show();
    }
   },
   //レスポンス失敗時のリスナー
   new Response.ErrorListener() {
    @Override 
    public void onErrorResponse(VolleyError error) {
     //エラー時の処理
     Toast.makeText(getApplicationContext(), "onErrorResponse", Toast.LENGTH_LONG).show();

    }
   }
  ){
  @Override
   public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();
    // Add BASIC AUTH HEADER
    Map<String, String> newHeaders = new HashMap<String, String>();
    newHeaders.putAll(headers);
    String password = createAuthorization("アカウントID", "アカウントパスワード");
    newHeaders.put("Authorization", "Basic "+password+"======");
    return newHeaders;
   }
  };

  //タグを設定する
  request.setTag(TAG_REQUEST_QUEUE);
  
  //リクエスト&レスポンス情報の設定を追加
  mRequestQueue.add(request);

  //リクエスト開始
  mRequestQueue.start();  
 }

 /**
  * BASIC認証用のヘッダ文字列を作成する。
  * @param in_username ユーザ名
  * @param in_password パスワード
  * @return BASIC認証用のヘッダ文字列
  */
 public static String createAuthorization( String in_username, String in_password ) {

  String string = in_username + ":" + in_password;

  byte[] tmp = getAsciiBytes( string );

  String encoded = base64Encode( tmp );

  return encoded;
 }

 /**
  * 文字列をASCIIのバイト配列に変換します。
  * @param text 対象の文字列
  * @return 変換後のバイト配列
  */
 private static byte[] getAsciiBytes( String text ) {

  byte[] ascii;
  try {
   ascii = text.getBytes( "ASCII" );
  } catch ( UnsupportedEncodingException e ) {
   throw new RuntimeException( e );
  }

  return ascii;
 }

 /**
  * バイト配列をBASE64エンコードします。
  * @param ascii 対象のバイト配列
  * @return エンコード後の文字列
  */
 private static String base64Encode( byte[] ascii ) {

  // ASCIIをビットパターンに変換します。
  StringBuffer bitPattern = new StringBuffer();
  for ( int i = 0; i < ascii.length; ++i ) {
   int i_tmp = ascii[i] & 0xff;
   String bin_tmp = Integer.toBinaryString( i_tmp );
   while ( bin_tmp.length() < 8 ) {
    bin_tmp = "0" + bin_tmp;
   }
   bitPattern.append( bin_tmp );
  }

  // ビットパターンのビット数が6の倍数にするため、末尾に0を追加します。
  while ( bitPattern.length() % 6 != 0 ) {
   bitPattern.append( "0" );
  }

  // 変換表
  final String[] table = {
    "A", "B", "C", "D", "E", "F", "G", "H",
    "I", "J", "K", "L", "M", "N", "O", "P",
    "Q", "R", "S", "T", "U", "V", "W", "X",
    "Y", "Z", "a", "b", "c", "d", "e", "f",
    "g", "h", "i", "j", "k", "l", "m", "n",
    "o", "p", "q", "r", "s", "t", "u", "v",
    "w", "x", "y", "z", "0", "1", "2", "3",
    "4", "5", "6", "7", "8", "9", "+", "/"
  };

  // 変換表を利用して、ビットパターンを4ビットずつ文字に変換します。
  StringBuffer encoded = new StringBuffer();
  for ( int i = 0; i < bitPattern.length(); i += 6 ) {
   String tmp = bitPattern.substring( i, i + 6 );
   int index = Integer.parseInt( tmp, 2 );
   encoded.append( table[index] );
  }

  // 変換後の文字数を4の倍数にするため、末尾に=を追加します。
  while ( encoded.length() % 4 != 0 ) {
   encoded.append( "=" );
  }

  return encoded.toString();
 }
}
以上です(`・ω・´)ゞビシッ!!

参考URL

0 件のコメント:

コメントを投稿