読者です 読者をやめる 読者になる 読者になる

DRY

Web関連の技術の事、食事/お酒の事、旅行の事など

Android SDKを用いてFacebookの友達をListViewに表示するコード

Android

何か調べていてあんまりこの手のエントリーが無いのはなんででしょう?気のせいかな?

内容的には単純にAndroidアプリ上でSDKを用いてFacebookのauthorizeを呼び、友達リストとその画像をListViewに表示するソースです。

■参考サイト
Facebookオフィシャルサイト
IBMさんのこのサイト

ぶっちゃけ画像を取ってくるところとか自信ありません。。。
急にコレだけ単なるhttp(s)アクセスになっていて、SDK関係ないし。
これみんなどうしてるんだろう???

ちょっと本当の友達が表示されてしまうので、完成キャプチャーは貼れませんが。
一応画像とnameは取れています。

                                                    • -

クラス名を「FriendActivity」としました。
AndroidManifest.xmlに追加



res/layout/friend.xml





実際のFriendActivity.javaはこんな感じです


import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;

import java.util.List;
import java.util.ArrayList;

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

import android.content.Intent;
import android.content.Context;

import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.LayoutInflater;

import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ImageView;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;

import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;


public class FriendActivity extends Activity
{
private FriendListAdapter m_list_view;
private List m_item_list;

private Facebook m_facebook;
private AsyncFacebookRunner m_facebook_runner;

private static class Friend
{
String id;
String name;
String img_url;

Friend (String _id, String _name)
{
this.id = _id;
this.name = _name;
this.img_url = "https://graph.facebook.com/" + id + "/picture";
}
}
private static class ViewHolder
{
ImageView image;
TextView name;
}

@Override
protected void onCreate(Bundle bundle)
{
super.onCreate (bundle);

requestWindowFeature (Window.FEATURE_INDETERMINATE_PROGRESS);

setContentView (R.layout.friend);
setProgressBarIndeterminateVisibility (true);
setProgressBarIndeterminate (true);

m_item_list = new ArrayList ();
connect_facebook ();

setProgressBarIndeterminate (false);
setProgressBarIndeterminateVisibility (false);
}

@Override
public void onActivityResult (int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
m_facebook.authorizeCallback (requestCode, resultCode, data);
}

private void connect_facebook ()
{
m_facebook = new Facebook ("Facebookから取得したID");
m_facebook.authorize (this, new LoginListener ());
}

public class LoginListener implements DialogListener
{
@Override
public void onComplete (Bundle values)
{
m_facebook_runner = new AsyncFacebookRunner (m_facebook);
m_facebook_runner.request ("me/friends", new FriendsRequestListener ());
}

@Override
public void onFacebookError (FacebookError e)
{
Log.e ("Facebook", "authorize : Facebook Error:" + e.getMessage ());
}

@Override
public void onError (DialogError e)
{
Log.e ("Facebook", "authorize : Error:" + e.getMessage ());
}

@Override
public void onCancel () {}
}

public class FriendsRequestListener implements com.facebook.android.AsyncFacebookRunner.RequestListener
{
@Override
public void onComplete(String response, final Object state)
{
try
{
Log.d ("Facebook", "Friends-Request : response.length(): " + response.length ());
Log.d ("Facebook", "Friends-Request : Response: " + response);

final JSONObject json = new JSONObject (response);
JSONArray d = json.getJSONArray ("data");
int l = (d != null ? d.length () : 0);
Log.d ("Facebook-Friends-Request", "d.length (): " + l);

//for (int i = 0; i < l; i++)
for (int i = 0; i < 10; i++)
{
JSONObject o = d.getJSONObject (i);

String id = o.getString ("id");
String name = o.getString ("name");

m_item_list.add (new Friend (id, name));
}

FriendActivity.this.runOnUiThread (new Runnable () {
public void run ()
{
ListView lv = new ListView (FriendActivity.this);
setContentView (lv);
m_list_view = new FriendListAdapter (FriendActivity.this);
lv.setAdapter (m_list_view);
m_list_view.notifyDataSetChanged ();
}
});
}
catch (JSONException e)
{
Log.d ("Facebook", "Friends-Request : JSON Error in response");
}
}

@Override
public void onFacebookError (FacebookError e, final Object state)
{
Log.e ("Facebook", "Friends-Request : Facebook Error:" + e.getMessage ());
}

@Override
public void onFileNotFoundException (FileNotFoundException e, final Object state)
{
Log.e ("Facebook", "Friends-Request : Resource not found:" + e.getMessage ());
}

@Override
public void onIOException (IOException e, final Object state)
{
Log.e ("Facebook", "Friends-Request : Network Error:" + e.getMessage ());
}

@Override
public void onMalformedURLException (MalformedURLException e, final Object state)
{
Log.e ("Facebook", "Friends-Request : Invalid URL:" + e.getMessage ());
}
}

private class FriendListAdapter extends BaseAdapter
{
private LayoutInflater m_layoutInflater;

public FriendListAdapter (Context context)
{
m_layoutInflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount () { return m_item_list.size (); }
@Override
public Object getItem (int position) { return m_item_list.get (position); }
@Override
public long getItemId (int position) { return position; }
@Override
public View getView (int position, View convertView, ViewGroup parent)
{
ViewHolder holder;

if (convertView == null)
{
convertView = m_layoutInflater.inflate (R.layout.friend, null);
holder = new ViewHolder ();

holder.image = (ImageView) convertView.findViewById (R.id.image);
holder.name = (TextView) convertView.findViewById (R.id.name);

convertView.setTag (holder);
}
else
{
holder = (ViewHolder)convertView.getTag ();
}

Friend data = (Friend)getItem (position);

GetImageAsyncTask task = new GetImageAsyncTask (getApplicationContext (), holder.image);
task.execute (data.img_url);

holder.name.setText (data.name);
return convertView;
}
}
}

外部クラスはGetImageAsyncTaskぐらいですが、一般的なAsyncのクラスです。

GetImageAsyncTask.java


import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.MalformedURLException;

import android.util.Log;

import android.os.AsyncTask;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;


public class GetImageAsyncTask extends AsyncTask
{
private Context m_context;
private ImageView m_image_view;

public GetImageAsyncTask (Context context, ImageView image)
{
this.m_context = context;
this.m_image_view = image;
}

@Override
protected void onPreExecute ()
{
/*
// バックグラウンドの処理前にUIスレッドでダイアログ表示
m_progress = new ProgressDialog (this.m_context);

//m_progress.setMessage (getResources().getText(R.string.data_loading));
m_progress.setIndeterminate (true);
m_progress.show ();
*/
}

@Override
protected Bitmap doInBackground (String... params)
{
synchronized (m_context)
{
try
{
//キャッシュより画像データを取得
Bitmap image = ImageCache.get (params[0]);
if (image == null)
{
//キャッシュにデータが存在しない場合はwebより画像データを取得
URL image_url = new URL (params[0]);
InputStream is;
is = image_url.openStream ();
image = BitmapFactory.decodeStream (is);

//取得した画像データをキャッシュに保持
ImageCache.set (params[0], image);
}

return image;
}
catch (MalformedURLException e)
{
Log.d ("GetImageAsyncTask", "Failed AsyncImageGetTask MalformedURLException = " + e.getMessage ());
return null;
}
catch (IOException e)
{
Log.d ("GetImageAsyncTask", "Failed AsyncImageGetTask IOException = " + e.getMessage ());
return null;
}
}
}

@Override
protected void onPostExecute (Bitmap result)
{
// 処理中ダイアログをクローズ
//m_progress.dismiss();

m_image_view.setImageBitmap (result);
}
}

ImageCache.java


import android.graphics.Bitmap;
import java.util.HashMap;

public class ImageCache
{
private static HashMap cache = new HashMap ();

public static Bitmap get (String key)
{
if (cache.containsKey (key))
return cache.get (key);

return null;
}

public static void set (String key, Bitmap image)
{
cache.put (key, image);
}

public static void clear ()
{
cache = null;
cache = new HashMap ();
}
}