#

Android google翻译踩坑之旅

  最近由于工作需求,需要为游戏Android平台接入Google翻译的SDK,由于关于翻译的文章非常少,访问官方文档又需要翻墙,更可气的是找到的博客写了一大堆结果是错的,官网给的库跟链接也不对,导致耽搁了挺长一段时间。今天我就分享下我的踩坑之旅,希望这篇博客能帮助到也需要接Google翻译的人。

  废话不多说,首先使用Google翻译是需要翻墙的,请自备VPN。关于怎么注册申请翻译API请看这篇博客需要注意的一点是Android平台需要申请参数APIKey,在申请时是需要选择Android apps 并需要填入应用包名 和应用签名的SHA1字符串的,假如你申请时没有填入这两项,那你申请的可能不是Android的翻译API。

  参数申请完毕后还需要下载一个jar包 guava.jar ,点这进入下载页。本来我是看了这篇博客进行接入的 http://blog.csdn.net/nicolelili1/article/details/76973097 ,由于公司项目是eclipse工程,我把依赖里的jar包全部下载,放到工程里大概10M左右,并且方法数超出65535限制,使用dex分包方案后测试发现翻译失败,Log打印错误日志如下:

{"code": 403,"errors": [{"domain": "global","message": "Requests from this Android client application <empty> are blocked.","reason": "forbidden"}],"message": "Requests from this Android client application <empty> are blocked.","status": "PERMISSION_DENIED"
}

在 stackoverflow 上看到一个一模一样的问题,看了半天发现说的不是翻译。。。然后接着换了关键词去搜,发现这里有一个回答有点靠谱,一个老外发的帖子说自己用OKHttp接入谷歌翻译出错,虽然错误内容不一样,但有个回复引起了我的注意:

大概意思是说在调用 Google翻译URL进行翻译时需要在请求头加上"X-Android-Package" 包名和"X-Android-Cert"应用签名SHA1然后给了获取SHA1的示例代码:


/*** Gets the SHA1 signature, hex encoded for inclusion with Google Cloud Platform API requests** @param packageName Identifies the APK whose signature should be extracted.* @return a lowercase, hex-encoded*/
public static String getSignature(@NonNull PackageManager pm, @NonNull String packageName) {try {PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);if (packageInfo == null|| packageInfo.signatures == null|| packageInfo.signatures.length == 0|| packageInfo.signatures[0] == null) {return null;}return signatureDigest(packageInfo.signatures[0]);} catch (PackageManager.NameNotFoundException e) {return null;}
}private static String signatureDigest(Signature sig) {byte[] signature = sig.toByteArray();try {MessageDigest md = MessageDigest.getInstance("SHA1");byte[] digest = md.digest(signature);return BaseEncoding.base16().lowerCase().encode(digest);} catch (NoSuchAlgorithmException e) {return null;}
}

以及如何使用HttpulrConnection进行正确的请求:

java.net.URL url = new URL(REQUEST_URL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
try {connection.setDoInput(true);connection.setDoOutput(true);connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");connection.setRequestProperty("Accept", "application/json");// add package name to request headerString packageName = mActivity.getPackageName();connection.setRequestProperty("X-Android-Package", packageName);// add SHA certificate to request headerString sig = getSignature(mActivity.getPackageManager(), packageName);connection.setRequestProperty("X-Android-Cert", sig);connection.setRequestMethod("POST");// ADD YOUR REQUEST BODY HERE// ....................
} catch (Exception e) {e.printStackTrace();
} finally {connection.disconnect();
}

在此基础上我写了Demo进行测试,不过网络框架我是用的OkHttp,在有VPN的情况下是可以翻译成功的,没有VPN可能会报链接超时的错误。由于需要分dex,我把代码打成了jar包: 源码下载 jar包下载

其实就是使用链接访问google翻译API,Google翻译链接地址是这个: https://www.googleapis.com/language/translate/v2 其中需要传入几个参数:

  • key:apiKey
  • target:目标语言(en zh等语言代号)
  • q:要翻译的内容(该参数是可以传递多个的,如:…url?q=内容&q=测试)

以及要在请求头加上 X-Android-Package 和 X-Android-Cert 信息,只要参数传递无误,并且有翻墙软件开启,得到的翻译结果格式如下:

{"data": {"translations": [{"translatedText": "test","detectedSourceLanguage": "zh-CN"}]}
}

translatedText 就是翻译结果,detectedSourceLanguage是
考虑到有的朋友不能访问github下载代码,在此处贴入具体代码:

public class OkHttpFactory {private static OkHttpClient okHttpClient;public static OkHttpClient getOkHttpClient(){if(okHttpClient == null){synchronized (OkHttpFactory.class){if(okHttpClient == null){okHttpClient = new OkHttpClient.Builder().connectTimeout(20, TimeUnit.SECONDS).build();}}}return okHttpClient;}
}
public interface TranslationCallback {void onTranslationSuccess(String resultJson);void onTranslationFailed(String errMsg);
}
public class Translation {private String apiKey = "";private static String REQUEST_URL = "https://www.googleapis.com/language/translate/v2";private static String PACKAGE_KEY = "X-Android-Package";private static String SHA1_KEY = "X-Android-Cert";public Translation(String apiKey){this.apiKey = apiKey;}public void translate(Context context,String content,String targetLanguage, TranslationCallback callback){JSONArray array = new JSONArray();array.put(content);translate(context,array,targetLanguage,callback);}public void translate(Context context, JSONArray contents, String targetLanguage, final TranslationCallback callback){OkHttpClient okHttpClient = OkHttpFactory.getOkHttpClient();String sig = getSignature(context.getPackageManager(),context.getPackageName());FormBody.Builder builder = new FormBody.Builder().add("key", apiKey).add("target", targetLanguage);for (int i = 0; i < contents.length(); i++) {String text;try {text = contents.getString(i);builder.add("q",text);} catch (JSONException e) {e.printStackTrace();}}FormBody formBody = builder.build();Request request = new Request.Builder().url(REQUEST_URL).header(PACKAGE_KEY,context.getPackageName()).header(SHA1_KEY,sig).post(formBody).build();Call call = okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {callback.onTranslationFailed(e == null?"null":e.getMessage());}@Overridepublic void onResponse(Call call, Response response) throws IOException {callback.onTranslationSuccess(response.body().string());}});}/*** Gets the SHA1 signature, hex encoded for inclusion with Google Cloud Platform API requests** @param packageName Identifies the APK whose signature should be extracted.* @return a lowercase, hex-encoded*/private static String getSignature(PackageManager pm, String packageName) {try {PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);if (packageInfo == null|| packageInfo.signatures == null|| packageInfo.signatures.length == 0|| packageInfo.signatures[0] == null) {return null;}return signatureDigest(packageInfo.signatures[0]);} catch (PackageManager.NameNotFoundException e) {return null;}}private static String signatureDigest(Signature sig) {byte[] signature = sig.toByteArray();try {MessageDigest md = MessageDigest.getInstance("SHA1");byte[] digest = md.digest(signature);return BaseEncoding.base16().lowerCase().encode(digest);} catch (NoSuchAlgorithmException e) {return null;}}
}

Android google翻译踩坑之旅相关推荐

  1. Android Studio安装踩坑

    title: Android Studio安装踩坑 date: 2018-09-07 19:31:32 updated: tags: [Android,Android Studio,坑] descri ...

  2. 微信开发踩坑之旅 之 开发准备及服务器配置

    在工作和兴趣的机缘巧合之下,我开始接触微信开发.在这里简单记述自己的微信开发踩坑之旅. 首先,由于本人标准的理工科生,记述的语言有所不足,我尽量说明准确和详细点. 本文记述主线 ·申请公众号 ·公众号 ...

  3. python 同花顺thstrader_Python 踩坑之旅进程篇其三pgid是个什么鬼 (子进程\子孙进程无法kill 退出的解法)...

    代码示例支持 平台: Centos 6.3 Python: 2.7.14 1.1 踩坑案例 pid, ppid是大家比较常见的术语, 代表进程号,父进程号. 但pgid是个什么鬼? 了解pgid之前, ...

  4. Vue踩坑之旅(一)—— 数组、对象的监听

    作为一个接触 vue 才一个多月的小白,马上就接手基于 vue 的大型商城项目,其间真是跌跌撞撞踩了好多坑(o(╥﹏╥)o).在此写下自己的踩坑之旅,希望给跟我一样还在自学 vue 的同学一些帮助,另 ...

  5. VR制作中必须踩的坑365之037(oculus2、UE4、UE5、VR记录一年的踩坑之旅)Maya / ZBrush / Substance Painter倒来倒去

    VR制作中必须踩的坑365之037(oculus2.UE4.UE5.VR记录一年的踩坑之旅)Full 3D GAME ASSET workflow ( Maya / ZBrush / Substanc ...

  6. 重装win10系统+Ubuntu16.04的踩坑之旅(联想拯救者r720)

    重装win10系统+Ubuntu16.04的踩坑之旅(联想拯救者r720) 碎碎念:原本双系统用得很开心的,在手贱删了Ubuntu系统的某些隐藏文件之后导致Ubuntu系统不能正常使用,在某种程度强迫 ...

  7. VR制作中必须踩的坑365之044(oculus2、UE4、UE5、VR记录一年的踩坑之旅)拳击VR小游戏红绿灯

    VR制作中必须踩的坑365之043(oculus2.UE4.UE5.VR记录一年的踩坑之旅)拳击VR制作起来,拳击动画人物 How to create box minigame in VR (UE4 ...

  8. android 字体文件压缩,Android 字体使用踩坑指南

    Android 字体使用踩坑指南 最近项目改版,根据ui的设计,需要使用到三字体.在使用过程中遇到一些坑,于是有了这个避坑指南! 字体压缩 第一个坑!字体库的体积太大. 字体压缩的前提是要使用的内容是 ...

  9. VR制作中必须踩的坑365之045(oculus2、UE4、UE5、VR记录一年的踩坑之旅)iclone8来来来告诉你剁手坑

    VR制作中必须踩的坑365之045(oculus2.UE4.UE5.VR记录一年的踩坑之旅) iClone 8 Work in Progress - Part One: Dramatically Si ...

最新文章

  1. (建议收藏)万字长文,帮你一招搞定产品经理面试-详解产品经理面试大全
  2. 『Python』__getattr__()特殊方法
  3. linux显示磁盘使用情况命令,Linux查看磁盘使用情况命令(示例代码)
  4. PHP设置脚本最大执行时间的三种方法
  5. PHP 数字缩短(最多1倍)与还原
  6. WEB前端、后端的说明
  7. 虎牙直播源解析【可选清晰度】
  8. Annotation-specified bean name conflicts with existing
  9. 中国标准时间、标准时间、时间戳时间格式转换
  10. linux下列出绝对路径的最快捷的方法lls
  11. mac环境 java找不到或无法加载主类
  12. BasicVSR_pp video2frame
  13. 分布式算法-Paxos
  14. 计算机四级 信息安全工程师 题库 前言
  15. 计算机协会发言稿范文,计算机协会社长就职演讲稿范文
  16. 树莓派配置红外遥控及关联python程序
  17. 汇编语言(王爽第三版)笔记
  18. 天下布魔服务器维护,2017年4月20日服务器停机维护公告
  19. JS简单实现:根据奖品权重计算中奖概率实现抽奖的方法
  20. 使用金蝶kis财务的具体步骤

热门文章

  1. Quartus II 修改工程名称和顶层实体名称
  2. VS studio 项目名称更改
  3. 解决Windows Server 2008 R2无法保存网络发现状态更改问题
  4. HTML的常见标签及用法
  5. 抖音seo源码账号矩阵程序开发搭建?抖音seo搜索技术研发搭建部署
  6. 经由蓝牙适配器连接蓝牙耳机失败解决方法。
  7. 小程序:微信小程序支付流程
  8. 电脑任务栏同时显示网速与CPU和内存的占用。
  9. 计算机一级常用计算公式,(完整版)计算机一级word操作知识点
  10. labview怎么设置中文_小米手机怎么弄抖音中文数字时钟罗盘屏保 设置动态壁纸教程...