GCM推送消息编码

时间:2012-11-05 09:59:26

标签: android encoding push

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

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

在接收方,我的代码是:

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

当消息是英文,latin charset,一切正常。但是,当我尝试其他语言或字符ç时,它们会作为问号到达或从字符串中删除。

注意:它以utf-8编码

5 个答案:

答案 0 :(得分:9)

Java服务器

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

Android应用

String message = URLDecoder.decode(intent.getStringExtra("message"), "UTF-8");

答案 1 :(得分: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使用UTF-8作为平台默认字符集做什么比如“blah”.getBytes()。这是不好的做法,但是当它是别人的图书馆时你能做什么呢?

答案 2 :(得分:2)

我遇到了与gcm-server库类似的问题。我的解决方法是使用自定义发件人覆盖post方法,并在getBytes()调用中使用UTF8作为编码。 它适用于Google App Engine。

自定义发件人类的代码:

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);
            }
        }
    }

}

答案 3 :(得分:2)

这些是一些很好的解决方案,但是他们没有帮助我,因为我使用主题消息来发送通知。根据{{​​3}}

  

HTTP标头必须包含以下标头:   授权: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邮政编码低于( 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) {
        // ...
    }

答案 4 :(得分:0)

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