Mixi Voiceに対応してみました

Facebookに別れを告げたから、というわけではありませんが、MixiがAndroid向けにSDKを公開していたのでやっつけ仕事でSmartTrainingで対応してみました。
細かい話はMixi Developerを見てください。必要な手続き、サンプル、SDKダウンロード等すべてが揃ってるので敢えてここでやり方を各必要もなかろうと思います。
んで、このAPIを使ってみての所感というか。

・異常系の処理
例えば、投稿時に通信が利用できないケースでは、Mixiライブラリ側がcatchしてエラーメッセージ出してAPP側にthrowしてくれません。throwしてくれないのは、ちゃんとonFatal()あたりでコールバックしてくれるのでいいんですが、エラーメッセージがアプリ側とテーマが異なったり、メッセージ内容を変更したいといったことに対応できません。ライブラリなんだからUIの領域に踏み込んでほしくないなぁ。

・onActivityResult()実装の必要性
Facebook SDKも同じですが、Mixiへのアクセス(具体的には認証処理)時に結果を受け取るためにonActivityResult()を実装する必要があります。つまり、Activityから要求を送信することが前提となっています。例えば、Serviceが直接Mixiにアクセスしたい場合もあるわけですが、そういうケースへの配慮がありません。
そんなときは、Mixi送信用のActivityを作って画面表示とともに送信→送信完了もしくは何か異常が起きたら画面終了します。Activityは背景を透明にしておくと見た目上Activityが起動されたことがわからないのでいいカモ。

・Mixi Developerに登録できるアプリアイコン
サイズ76x76というAndroid標準ではあまり聞いたことのないサイズ。48x48とか72x72あたりにしてほしいな。まぁ、そんなことはいいんだけど、GIFかJPEGしか登録できない。いや、PNGでしょ。イマドキさ。。。

・アカウントの登録
昔からなんだけど、Mixiはキャリアメールを持っていないとアカウントが作れない。当然、Developer登録もできない。なんでよ?Android向けのSDK提供してるならGmailくらい認めてよ。それでサポートやってんだからさ。

いっぱい文句言ってごめんなさい。
というわけでやっつけ仕事のソースです。

まずは、Mixi投稿だけをするカラのActivity。こいつをService側からStartActivity()してやればいい。いや、カラじゃないか。


public class SendMixiVoiceActivity extends Activity implements CallbackListener {

private static final int CODE_MIXI_VOICE = 0;
public static final String KEY_MESSAGE = "key_message";
private MixiVoiceManager mvm;
private String message;
private Context context;
/**
* 画面生成時処理
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 引数取得
Bundle extras = getIntent().getExtras();
message = extras.getString(KEY_MESSAGE);
// 初期化
context = this;
mvm = new MixiVoiceManager(context){
@Override
public void onFinishSend() {
finish();
}
};

if ( !mvm.isAuthorized() )
{
// セッションなし:認証開始
mvm.authorize(
this,
new String[] {"w_voice"},
CODE_MIXI_VOICE,
this);
}
else
{
mvm.send(message);
}
}
@Override
public void onComplete(Bundle values) {
mvm.send(message);
}
@Override
public void onCancel() {
finish();
}
@Override
public void onFatal(ErrorInfo e) {
finish();
}
@Override
public void onError(ErrorInfo e) {
finish();
}

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

// 呼ばれる保証のないonDestroy()で後始末処理しても意味ないんじゃない?onPause()でやったらいいんジャマイカ。
@Override
public void onDestroy() {
mvm.close(this);
super.onDestroy();
}
}


次はMixi投稿を管理する自作のMixiVoiceManager(Activity側に処理いれてしまえば別にこんなの作んなくてもいい。)

public abstract class MixiVoiceManager {

private MixiContainer mContainer;
private Context context;

public abstract void onFinishSend();

/**
* コンストラクタ
* @param context
*/
public MixiVoiceManager(Context context)
{
this.context = context;

Config config = new Config();
config.clientId = "Mixi Developer Centerに登録したID";
config.selector = Config.GRAPH_API;

mContainer = MixiContainerFactory.getContainer(config);
if ( mContainer == null )
onFinishSend();

if ( !mContainer.init((ContextWrapper)context))
onFinishSend();
}

/**
* 認証処理
* @param activity
* @param permissions
* @param activityCode
* @param listener
*/
public void authorize(Activity activity, String[] permissions, int activityCode, CallbackListener listener)
{
mContainer.authorize(activity, permissions, activityCode, listener);
}

/**
* Voice投稿
* @param voice
*/
public void send(String voice)
{
Map params = new HashMap();
params.put("status", voice);
mContainer.send("/voice/statuses/update", HttpMethod.POST, params, new CallbackListener(){

@Override
public void onComplete(Bundle values) {
Toast.makeText(context, R.string.message_success_send_mixi_voice, Toast.LENGTH_LONG).show();
onFinishSend();
}

@Override
public void onCancel() {
onFinishSend();
}

@Override
public void onFatal(ErrorInfo e) {
Toast.makeText(context, R.string.message_fail_send_mixi_voice, Toast.LENGTH_LONG).show();
onFinishSend();
}

@Override
public void onError(ErrorInfo e) {
Toast.makeText(context, R.string.message_fail_send_mixi_voice, Toast.LENGTH_LONG).show();
onFinishSend();
}});
}

/**
* 認証状態チェック
* @return
*/
public boolean isAuthorized()
{
return mContainer.isAuthorized();
}

public void authorizeCallback(int requestCode, int resultCode, Intent data)
{
mContainer.authorizeCallback(requestCode, resultCode, data);
}

public void close(Context context)
{
mContainer.close((ContextWrapper) context);
}
}


そんな感じ。

コメント

このブログの人気の投稿

Joinノードを使う(その1)

Execノードを使う

Joinノードを使う(その4)