2013-12-20 48 views
1

我使用Google Cloud Messaging发送通知。我的应用程序将令牌(显然来自Google)发送到我的服务器数据库......问题是save token request同时发送两次到服务器(确切的说,就像一个克隆)! 所以,通过服务器我无法解决这个问题(因为时间是一样的,我不能告诉insert if not exist)...通过应用我不知道我是否有问题。Google云消息传递:数据库中的重复令牌

我认为问题出自Google,但我不知道。

这是我的注册代码:

 GCMRegistrar.checkDevice(this); 
     GCMRegistrar.checkManifest(this); 
     registerReceiver(mHandleMessageReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION)); 
     regId = GCMRegistrar.getRegistrationId(this); 
     if (regId.equals("")) { 
      new registra_background().execute(); 
     } else { 
      if (!GCMRegistrar.isRegisteredOnServer(this)) { 
       mRegisterTask = new AsyncTask<Void, Void, Void>() { 
        @Override 
        protected Void doInBackground(Void... params) { 
         ServerUtilities.register(context, regId); 
         return null; 
        } 
        @Override 
        protected void onPostExecute(Void result) { 
         mRegisterTask = null; 
        } 
       }; 
       mRegisterTask.execute(null, null, null); 
      } 
     } 

这就是所谓的类

private class registra_background extends AsyncTask<Void, Integer, Void> { 
    int progress_status; 
    @Override 
    protected void onPreExecute(){ 
     super.onPreExecute(); 
    } 
    @Override 
    protected Void doInBackground(Void... params){ 
     try{ 
      if (gcm == null) { 
       gcm = GoogleCloudMessaging.getInstance(context); 
      } 
      regId = gcm.register(SENDER_ID); 
      Log.e("TOKEN",regId); 
     }catch(Exception ex){ 
      System.out.println("Errore dati"); 
     } 
     return null; 
    } 
    @Override 
    protected void onProgressUpdate(Integer... values){ 
    } 
    @Override 
    protected void onPostExecute(Void result){ 
     mRegisterTask = new AsyncTask<Void, Void, Void>() { 
      @Override 
      protected Void doInBackground(Void... params) { 
       ServerUtilities.register(context, regId); 
       return null; 
      } 
      @Override 
      protected void onPostExecute(Void result) { 
       mRegisterTask = null; 
      } 
     }; 
     mRegisterTask.execute(null, null, null); 
    } 
} 

,这是服务器级

public final class ServerUtilities { 
private static final int MAX_ATTEMPTS = 5; 
private static final int BACKOFF_MILLI_SECONDS = 2000; 
private static final Random random = new Random(); 
static public void register(final Context context, final String regId) { 
    Database db; 
    db = new Database(context); 
    try { 
     db.open(); 
    } catch (SQLException sqle) { 
     throw sqle; 
    } 
    Cursor variabili=db.variabili(); 
    int x=1; 
    String pvPref="",pvPrefProv="",pvPrefCitta="",pvPrefIndirizzo=""; 
    while(variabili.moveToNext()){ 
     if(x==1){ 
      pvPref=variabili.getString(variabili.getColumnIndex("valore")); 
     }else if(x==2){ 
      pvPrefProv=variabili.getString(variabili.getColumnIndex("valore")); 
     }else if(x==3){ 
      pvPrefCitta=variabili.getString(variabili.getColumnIndex("valore")); 
     }else if(x==4){ 
      pvPrefIndirizzo=variabili.getString(variabili.getColumnIndex("valore")); 
     } 
     x++; 
    } 
    String serverUrl = SERVER_URL; 
    Map<String, String> params = new HashMap<String, String>(); 
    params.put("regId", regId); 
    params.put("token_push", regId); 
    params.put("pvPref", pvPref); 
    params.put("device",android.os.Build.MODEL); 
    params.put("pvPrefProv", pvPrefProv); 
    params.put("pvPrefCitta", pvPrefCitta); 
    params.put("pvPrefIndirizzo", pvPrefIndirizzo); 
    params.put("app_version", "2.0"); 
    params.put("os", Build.VERSION.RELEASE); 
    long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000); 
    for (int i = 1; i <= MAX_ATTEMPTS; i++) { 
     try { 
      post(serverUrl, params); 
      SystemClock.sleep(500); 
      GCMRegistrar.setRegisteredOnServer(context, true); 
      return; 
     } catch (IOException e) { 
      if (i == MAX_ATTEMPTS) { 
       break; 
      } 
      try { 
       Thread.sleep(backoff); 
      } catch (InterruptedException e1) { 
       Thread.currentThread().interrupt(); 
       return; 
      } 
      backoff *= 2; 
     } 
    } 
} 
public static void unregister(final Context context, final String regId) { 
    String serverUrl = SERVER_URL + "/unregister"; 
    Map<String, String> params = new HashMap<String, String>(); 
    params.put("regId", regId); 
    try { 
     post(serverUrl, params); 
     GCMRegistrar.setRegisteredOnServer(context, false); 
    } catch (IOException e) { 
    } 
} 
private static void post(String endpoint, Map<String, String> params) throws IOException { 
    URL url; 
    try { 
     url = new URL(endpoint); 
    } catch (MalformedURLException e) { 
     throw new IllegalArgumentException("invalid url: " + endpoint); 
    } 
    StringBuilder bodyBuilder = new StringBuilder(); 
    Iterator<Entry<String, String>> iterator = params.entrySet().iterator(); 
    while (iterator.hasNext()) { 
     Entry<String, String> param = iterator.next(); 
     bodyBuilder.append(param.getKey()).append('=').append(param.getValue()); 
     if (iterator.hasNext()) { 
      bodyBuilder.append('&'); 
     } 
    } 
    String body = bodyBuilder.toString(); 
    byte[] bytes = body.getBytes(); 
    HttpURLConnection conn = null; 
    try { 
     conn = (HttpURLConnection) url.openConnection(); 
     conn.setDoOutput(true); 
     conn.setUseCaches(false); 
     conn.setFixedLengthStreamingMode(bytes.length); 
     conn.setRequestMethod("POST"); 
     conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); 
     OutputStream out = conn.getOutputStream(); 
     out.write(bytes); 
     out.close(); 
     int status = conn.getResponseCode(); 
     if (status != 200) { 
      throw new IOException("Errore " + status); 
     } 
    } finally { 
     if (conn != null) { 
      conn.disconnect(); 
     } 
    } 
} 
} 

回答

1

您的代码混合新的登记方法(GoogleCloudMessaging.register)与旧的弃用GCMRegistrar类。两个异步任务的嵌套使用非常混乱。

如果您在服务器上收到两个具有相同注册ID的请求,那么您的客户端代码是唯一负责的代码。与其试图调试这个太复杂的代码,我建议你使用当前的Google GCM Demo作为参考。当你正在检查

if(regId==""){ 
     //here simply put 
GCMRegistrar.register(this, SENDER_ID); 

}else{ 
ServerUtilities.register(context, regId); 
    } 

休息,你应该小心在服务器端的程序只

在Apidemo提供更多信息检查GCMDemo

+0

我不在为什么在onClick上有这样的事情: gcm.send(SENDER_ID +“@ gcm.googleapis.com”,id,data); wuth @是什么? –

+0

@DFerra该演示使用GCM的新功能 - 设备进行云消息传递 - 这是通过GCM服务器(需要使用GCM XMPP协议)从应用程序向您的服务器发送消息的一种方式。如果您只将消息从服​​务器发送到您的应用程序,则不需要它。当您希望通过GCM从您的应用向其发送消息时,SENDER_ID @ gcm.googleapis.com'是识别您的服务器的方式。 – Eran

0

上面的代码将达到注册服务只有一次

快乐圣诞