QA@IT

Android Exception Microsoft Translator

3720 PV

お世話になっています。
Androidアプリに翻訳機能を付けるべく、Microsoft TrancelatorというAPIで以下の様に実装してみました。

全コード

package com.hogehoge;

import com.memetix.mst.language.Language;
import com.memetix.mst.translate.Translate;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class hogeHogeActivity extends Activity implements OnInitListener  {

    @Override
    protected void onCreate(Bundle savedInstanceState)  {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.hogehoge);

        // =================
        // Microsoft Translator
        // =================

        // Set the Client ID / Client Secret once per JVM. It is set statically and applies to all services
        Translate.setClientId("MY_CLIENT_ID_HERE");
        Translate.setClientSecret("MY_CLIENT_SECRET_HERE");

        // From English -> Japanese
        String word = "hello";
        try {
            translatedText = Translate.execute(word, Language.ENGLISH, Language.JAPANESE);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        TextView translatedText = (TextView) findViewById(R.id.translatedText);
        translatedText.setText(String.valueOf(translatedText));
        });
    }

    @Override
    public void onInit(int status) {
        // TODO Auto-generated method stub

    }
}

公式のサンプルでは以下のようになっています。

公式サンプルのコード

import com.memetix.mst.language.Language;
import com.memetix.mst.translate.Translate;

public class Main {
  public static void main(String[] args) throws Exception {
    // Set your Windows Azure Marketplace client info - See http://msdn.microsoft.com/en-us/library/hh454950.aspx
    Translate.setClientId(/* Enter your Windows Azure Client Id here */);
    Translate.setClientSecret(/* Enter your Windows Azure Client Secret here */);

    String translatedText = Translate.execute("Bonjour le monde", Language.FRENCH, Language.ENGLISH);

    System.out.println(translatedText);
  }

しかし、

protected void onCreate(Bundle savedInstanceState)  {

protected void onCreate(Bundle savedInstanceState) throws Exception {

の様に例外を投げるようにすると「Exception Exception is not compatible with throws clause in Activity.onCreate(Bundle)」というエラーがでるので、try〜catchでくくりました。
するとエラーは出なくなり、コンパイルも通り、アプリを起動することができるのですが、表示したいtextViewの部分にはnullが入ってしまいます。
なにがいけないのかなと思いLogCatを確認してみると、関係しそうなログは以下のものがありました。

LogCatの出力の一部

W/System.err(23371): java.lang.Exception: [microsoft-translator-api] Error retrieving translation : null
W/System.err(23371):    at com.memetix.mst.MicrosoftTranslatorAPI.retrieveString(MicrosoftTranslatorAPI.java:202)
W/System.err(23371):    at com.memetix.mst.translate.Translate.execute(Translate.java:61)
W/System.err(23371):    at com.hogehoge.hogeHogeActivity.onCreate(hogeHogeActivity.java:37)

37行目、つまり

translatedText = Translate.execute(word, Language.ENGLISH, Language.JAPANESE);

で例外が発生しているようです。
しかし、この解決方法がわからず困っています。
おわかりになる方、いらっしゃればご教授願います。どうぞよろしくお願いします。

  • 37行目のtranslatedText はStringはつけなくていいんですか?
    また、permissionにINTERNETはくわえましたか?
    ちょっと気になったんで・・・
    -
  • diehardneverさんご指摘ありがとうございます。プログラムを見やすいようにいらないところを消していたらStringも消えてしまっていました。ありがとうございます。
    AndroidManifest.xmlに
    ```
    <uses-permission android:name="android.permission.INTERNET"/>
    ```
    は加えています。
    -
  • 勿論、String translatedText; は onCreateメソッドの外で宣言してますよね?まさかメソッド内でString translatedText = null とかしてないですよね? -
  • あ!関係ないですね。コンパイル通ったんですね。失礼しました(。。)/
    -
  • diehardneverさんありがとうございます。コンパイルは通ったのであとは「パフォーマンス低下検出機能を無効」にしなくてもできるようにするだけです!中間テストが開けたらやろうと思います。 -

回答

Translate.setClientId("MY_CLIENT_ID_HERE");
Translate.setClientSecret("MY_CLIENT_SECRET_HERE");

この部分はきちんと自分のIDやSECRETにしていますよね?

Android3.0以降ではメインスレッドでネットワーク操作を行うとエラーとなります。
とりあえず確認のために回避するにはアプリケーション開始前に

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build()); 

とすればよいのですが、これはあくまで一時的な回避策です。
正しくは AsyncTaskやAsyncTaskLoaderを使ってUIスレッドとは別のスレッドで実行する必要があります。

編集 履歴 (1)
  • flied_onionさん
    いつもご回答ありがとうございます。教えていただいたコードをonCreateメソッドに記述すると正しく動作しました。
    仕様変更で情報が古くなっていたのですね。AsyncTaskLoaderを用いて実装してみます。
    -
  • 実装してみたらまたご報告させてください。よろしくお願いします。 -
  • とても遅くなりましたが、解決しました。ありがとうございました! -
ウォッチ

この質問への回答やコメントをメールでお知らせします。