7

我正在尝试使用以下代码发送推送通知:

    Message message = new Message.Builder().addData("appName", appData.name)
.addData("message", pushData.message).build();

在接收方,我的代码是:

String message = intent.getStringExtra("message");

当消息是英文、拉丁字符集时,一切正常。但是,当我尝试其他语言或字符 ç 时,它们会以问号形式出现或从字符串中删除。

注意:它是用 utf-8 编码的

4

5 回答 5

9

Java 服务器

Message messagePush = new Message.Builder().addData("message", URLEncoder.encode("your message éèçà", "UTF-8")))

安卓应用

String message = URLDecoder.decode(intent.getStringExtra("message"), "UTF-8");
于 2013-04-03T14:15:47.923 回答
2

我遇到了同样的问题。在 Android 客户端上收到时损坏的非 ASCII 字符。我个人认为这是 Google GCM 服务器库实现中的一个问题。

在 Android GCM 库中,我看到了方法:

com.google.android.gcm.server.Sender.sendNoRetry(Message, List<String>) 

该方法执行以下操作

HttpURLConnection conn = post(GCM_SEND_ENDPOINT, "application/json", requestBody) 

他们应该至少指定“application/json; charset=utf-8 ”或他们使用的任何编码,或者更好的是强制它为 UTF-8。这不是一个大问题吗?

更深入地挖掘我找到了方法:

com.google.android.gcm.server.Sender.post(String, String, String) 

这样做:

byte[] bytes = body.getBytes()

为什么他们使用平台默认字符集?特别是因为它不太可能与设备的默认字符集对齐。

解决问题

将以下属性作为参数传递给 JVM “ -Dfile.encoding=UTF-8 ” 这将指示 Java 在执行“blah”.getBytes() 之类的操作时使用 UTF-8 作为平台默认字符集。这是不好的做法,但是当它是别人的图书馆时,你能做什么?

于 2013-10-18T18:42:18.367 回答
2

我对 gcm-server 库有类似的问题。我的解决方法是使用自定义发件人来覆盖该方法并在调用post中使用 UTF8 作为编码。getBytes()它适用于谷歌应用引擎。

自定义发送者类的代码:

import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.logging.Level;

import com.google.android.gcm.server.Sender;

/**
 * Workaround to avoid issue #13 of gcm-server
 * @see https://code.google.com/p/gcm/issues/detail?id=13&q=encoding
 * 
 * @author rbarriuso /at/ tribalyte.com
 *
 */
public class Utf8Sender extends Sender {

    private final String key;

    public Utf8Sender(String key) {
        super(key);
        this.key = key;
    }

    @Override
    protected HttpURLConnection post(String url, String contentType, String body) throws IOException {
        if (url == null || body == null) {
            throw new IllegalArgumentException("arguments cannot be null");
        }
        if (!url.startsWith("https://")) {
            logger.warning("URL does not use https: " + url);
        }
        logger.fine("Utf8Sender Sending POST to " + url);
        logger.finest("POST body: " + body);
        byte[] bytes = body.getBytes(UTF8);
        HttpURLConnection conn = getConnection(url);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setFixedLengthStreamingMode(bytes.length);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", contentType);
        conn.setRequestProperty("Authorization", "key=" + key);
        OutputStream out = conn.getOutputStream();
        try {
            out.write(bytes);
        } finally {
            close(out);
        }
        return conn;
    }

    private static void close(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                // ignore error
                logger.log(Level.FINEST, "IOException closing stream", e);
            }
        }
    }

}
于 2014-03-27T12:36:14.990 回答
1

这些是一些很好的解决方案,但是它们对我没有帮助,因为我正在使用主题消息发送通知。按照这个

HTTP 标头必须包含以下标头: Authorization: key=YOUR_API_KEY Content-Type: application/json for JSON; application/x-www-form-urlencoded;charset=UTF-8 用于纯文本。如果省略 Content-Type,则假定格式为纯文本。

但是,因为我正在使用云端点并且我的应用程序(已经在野外)期待 json,所以以纯文本格式格式化请求是不可行的。解决方案是忽略上面的文档,并在我的后端中,将 http 请求标头格式化为:

 connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");

就像魔术一样,突然间所有特殊字符(读作:日语)都进入了我的应用程序,而没有进行前端更改。我完整的http post代码如下( where payload = Cloud endpoint model object, converted to json<String> via Gson):

 try {
        URL url = new URL("https://gcm-http.googleapis.com/gcm/send");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
        connection.setRequestProperty("Authorization", "key=" + API_KEY);
        connection.setRequestMethod("POST");

        byte[] bytes=payload.getBytes("UTF-8");
        OutputStream out = connection.getOutputStream();
        try {
            out.write(bytes);
        } finally {
            out.close();
        }

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            // OK
            log.warning("OK");
        } else {
            // Server returned HTTP error code.
            log.warning("some error "+connection.getResponseCode());
        }
    } catch (MalformedURLException e) {
        // ...
    }
于 2015-08-18T06:50:39.863 回答
0

中断调试器并查看您认为要发送的消息的字节

于 2012-11-07T08:43:13.957 回答