2015-10-13 193 views
0

我是Java編程的新手,在過去的幾天裏,我一直在嘗試使用基本的英語到希臘語的語音翻譯應用程序,純粹是爲了幫助我學習一些(更高級的)概念。這是picture of the interface使用Retrofit 2.0從網絡中提取信息API

到目前爲止,我已經獲得了兩種語言的語音識別功能,並且我決定使用MyMemory's API作爲翻譯的REST API。我正在使用Retrofit 2.0.0-beta2將HTTP API變成Java界面。

此刻,我只是試圖從MyMemory中提取單詞/短語的翻譯,並將其放置在我的應用程序中的文本字段中。

目前,我已經在我的項目三類:

  1. TranslateAPI(接口)
  2. TranslatedData
  3. MainActivity

TranslateAPI

public interface TranslateAPI { 
    @GET("get") 
    void getTranslation(@Query("q") String request, Callback<TranslatedData> cb); 
} 

TranslatedData

public class TranslatedData { 
    String translatedText; 

    public String getTranslatedText(){ 
     return translatedText; 
    } 
} 

MainActivity(相關代碼)

 public void translate(String toTranslate){ 
     String request = "=" + toTranslate + "&langpair=" + langPair; 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl("http://api.mymemory.translated.net/") 
       .build(); 
     TranslateAPI service = retrofit.create(TranslateAPI.class); 
     service.getTranslation(request, new Callback<TranslatedData>() { 
      @Override 
      public void onResponse(Response<TranslatedData> response, Retrofit retrofit) { 
       System.out.println("Success"); 
       //handle success 
      } 

      @Override 
      public void onFailure(Throwable t) { 
       System.out.println("Failure"); 
       //handle failure 
      } 
     });   
    } 

有幾個問題在這裏出現。首先,應用程序因translate()方法而崩潰,我無法理解爲什麼(我在android中的調試技巧仍然不存在)。任何人都可以請幫我弄清楚爲什麼?

其次,我如何解析服務器的響應?

我的代碼是否有任何其他缺陷,可以防止應用程序工作/崩潰?

我很抱歉,如果我的問題很差或直截了當,我仍然是Android的新手,我發現大多數關於改裝模糊和混亂的教程,因爲一半的指南是在Retrofit 1.x中編寫的,另一半是2.0。

+1

插入你的手機我進入你的電腦。如果您使用的是Android Studio,則在將應用程序部署到您的設備時,它應該會自動打開到控制檯(logcat界面)。如果你沒有,你可以使用adb logcat手動捕獲你的設備上的信息。這是一個開始的好地方。某些可能導致您的應用崩潰的原因(我不是100%確定的),是主線程中的網絡使用或未聲明您的應用需要網絡訪問權限。 –

+0

你好泰勒,感謝早日回覆。我要求清單文件上的網絡訪問權限。我非常抱歉,這個問題與translate()方法有關,因爲如果我註釋掉該方法,那麼該應用程序運行良好,沒有任何問題。我覺得我離解決方案只有一步之遙,但我不確定問題出在哪裏。 –

回答

2

Retrofit提供註釋來構建正確的調用,順便說一下,在這種特殊情況下,你需要建立這種URI的:

http://api.mymemory.translated.net/get?q=hola&langpair=ES|EN

langpair該參數值包含的字符:|需要逃脫(我花了一些時間),這可能是墜機的原因。

您可以輕鬆地修復它設置參數作爲在改造2 API聲明的簽名編碼:

@GET("/get") 
Call<TranslatedData> getTranslation(
    @Query("q") String textToTranslate, 
    @Query(value = "langpair", encoded = true) 
String languagePair); 

則該參數值編碼:

mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage)) 
    .enqueue(new Callback<TranslatedData>() { 

而且你有一些錯誤您的響應實體,包含translatedText屬性的對象是名爲responseData的JsonObject,您需要設置適當的實體:

class TranslatedData { 
    ResponseData responseData; 
} 

class ResponseData { 
    String translatedText; 
} 

我發佈你TranslateApi.java的整個文件,我已經測試和工程;)

package com.example.alex.finalproject; 

import java.net.URLEncoder; 
import retrofit.Call; 
import retrofit.Callback; 
import retrofit.GsonConverterFactory; 
import retrofit.Response; 
import retrofit.Retrofit; 
import retrofit.http.GET; 
import retrofit.http.Query; 

class TranslatedData { 
    ResponseData responseData; 
} 

class ResponseData { 
    String translatedText; 
} 

public class TranslateAPI { 
    private static final String ENDPOINT = "http://api.mymemory.translated.net"; 
    public final static String SPANISH = "ES"; 
    public final static String ENGLISH = "EN"; 


    private final TranslateService mService; 

    public interface TranslateService { 
     @GET("/get") 
     Call<TranslatedData> getTranslation(
      @Query("q") String textToTranslate, 
      @Query(value = "langpair", encoded = true) 
     String languagePair); 
    } 

    public TranslateAPI() { 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(ENDPOINT) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     mService = retrofit.create(TranslateService.class); 
    } 

    public void translate(final String textToTranslate, final String fromLanguage, final String toLanguage) { 
     mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage)) 
      .enqueue(new Callback<TranslatedData>() { 

       @Override 
       public void onResponse(Response<TranslatedData> response, Retrofit retrofit) { 
        String output = 
         String.format("Translation of: %s, %s->%s = %s", textToTranslate, 
          fromLanguage, toLanguage, response.body().responseData.translatedText); 

        System.out.println("Result: " + output); 
       } 

       @Override public void onFailure(Throwable t) { 
        System.out.println("[DEBUG]" + " RestApi onFailure - " + ""); 
       } 
      }); 
    } 
} 

可以撥打這樣的翻譯方法:

translateAPI.translate("hola", TranslateAPI.SPANISH, TranslateAPI.ENGLISH); 

我的控制檯結果:

I/System.out(31427): Result: Translation of: hola, ES->EN = hello 
+1

我不能感謝你足夠的隊友。非常感謝你的時間,你真的幫助我。 :)現在它工作得很好。 –

3

在Android Studio的底部,您有Android監視器,您可以在其中找到帶有錯誤和更多信息的堆棧軌跡,錯誤將以紅色突出顯示。

Android Monitor

爲了解析從改造2.0你需要指定一個轉換器服務器的響應。例如:如果您想首先使用Gson作爲您的Entity轉換器,您必須將該依賴項添加到您的build.gradle文件中。

compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' 

然後,你必須指定到你的改造適配器:

Retrofit marvelApiAdapter = new Retrofit.Builder() 
    .baseUrl(END_POINT) 
    .addConverterFactory(GsonConverterFactory.create(new Gson())) 
    .client(client) 
    .build(); 

如果沒有,你會得到一個崩潰。也許最好的建議是,你現在應該使用Retrofit 1.9,這是穩定的,第二個版本在寫作時是beta版。另一方面,in this link你會發現如何從1.9版本遷移到2.0版本的一個很好的指南,以防你遵循1.9教程,這可能是:)

+0

感謝您的回覆Saulmm。我已經包含了Gson對象,謝謝指出。我是否也需要創建一個OkHttpClient並在我的項目中調用.client()方法?此時,即使創建Gson對象並調用.addConverterFactory(。。。)方法,該應用程序仍然崩潰。 –

+0

Alexandros,我剛剛創建了一個非常簡單的工作示例,說明Retrofit 2如何工作 - > https://github.com/saulmm/Retrofit-2-basic-sample 將其導入到android studio中,查看它是如何工作的,然後你可以替換端點,回調類型和實體類。 :) – saulmm

+1

你是個英雄。非常感謝你! :)我會給它另一次嘗試,並讓我知道如果我設法使它工作。 –