2015-10-13 38 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

你是个英雄。非常感谢你! :)我会给它另一次尝试,并让我知道如果我设法使它工作。 –