2010-01-26 45 views
5

我收到以下錯誤:Facebook連接的Android - 使用stream.publish @ http://api.facebook.com/restserver.php

<error_code>104</error_code> 
<error_msg>Incorrect signature</error_msg> 

我應該被設置的contentType類型?我應該設置爲:

String contentType = "application/x-www-form-urlencoded"; 

String contentType = "multipart/form-data; boundary=" + kStringBoundary; 

這是我正在寫流:

HttpURLConnection conn = null; 
OutputStream out = null; 
InputStream in = null; 
try { 
    conn = (HttpURLConnection) _loadingURL.openConnection(); 
    conn.setDoOutput(true); 
    conn.setDoInput(true); 
    if (method != null) { 
     conn.setRequestMethod(method); 
     if ("POST".equals(method)) { 
      //"application/x-www-form-urlencoded"; 
      String contentType = "multipart/form-data; boundary=" + kStringBoundary; 
      //String contentType = "application/x-www-form-urlencoded"; 
      conn.setRequestProperty("Content-Type", contentType); 
     } 

     // Cookies are used in FBPermissionDialog and FBFeedDialog to 
     // retrieve logged user 
     conn.connect(); 
     out = conn.getOutputStream(); 
     if ("POST".equals(method)) { 
      String body = generatePostBody(postParams); 
      if (body != null) { 
       out.write(body.getBytes("UTF-8")); 
      } 
     } 
     in = conn.getInputStream(); 

下面是我使用發佈該流的方法:

private void publishFeed(String themessage) { 
    //Intent intent = new Intent(this, FBFeedActivity.class); 
    // intent.putExtra("userMessagePrompt", themessage); 
    // intent.putExtra("attachment", 
    Map<String, String> getParams = new HashMap<String, String>(); 
    // getParams.put("display", "touch"); 
    // getParams.put("callback", "fbconnect://success"); 
    // getParams.put("cancel", "fbconnect://cancel"); 

    Map<String, String> postParams = new HashMap<String, String>(); 

    postParams.put("api_key", _session.getApiKey()); 
    postParams.put("method", "stream.publish"); 
    postParams.put("session_key", _session.getSessionKey()); 
    postParams.put("user_message", "TESTING 123"); 
    // postParams.put("preview", "1"); 
    postParams.put("attachment", "{\"name\":\"Facebook Connect for Android\",\"href\":\"http://code.google.com/p/fbconnect-android/\",\"caption\":\"Caption\",\"description\":\"Description\",\"media\":[{\"type\":\"image\",\"src\":\"http://img40.yfrog.com/img40/5914/iphoneconnectbtn.jpg\",\"href\":\"http://developers.facebook.com/connect.php?tab=iphone/\"}],\"properties\":{\"another link\":{\"text\":\"Facebook home page\",\"href\":\"http://www.facebook.com\"}}}"); 
    // postParams.put("user_message_prompt", "22222"); 


    try { 
     loadURL("http://api.facebook.com/restserver.php", "POST", getParams, postParams); 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } 
} 

這裏是generatePostBody():

private String generatePostBody(Map<String, String> params) { 
    StringBuilder body = new StringBuilder(); 
    StringBuilder endLine = new StringBuilder("\r\n--").append(kStringBoundary).append("\r\n"); 

    body.append("--").append(kStringBoundary).append("\r\n"); 

    for (Entry<String, String> entry : params.entrySet()) { 
     body.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append("\"\r\n\r\n"); 
     String value = entry.getValue(); 
     if ("user_message_prompt".equals(entry.getKey())) { 
      body.append(value); 
     } 
     else { 
      body.append(CcUtil.encode(value)); 
     } 

     body.append(endLine); 
    } 

    return body.toString(); 
} 

謝謝。

+0

如何實現'loadURL()'方法? PS。請重新編輯您的帖子,我們無法在此閱讀一些代碼.... – 2010-03-14 23:28:01

回答

0

這是從的Facebook開發維基:http://wiki.developers.facebook.com/index.php/API

Note: If you manually form your HTTP POST requests to Facebook, you must include the request data in the POST body. In addition, you should include a Content-Type: header of application/x-www-form-urlencoded.

使用的multipart/form-data的上傳(在Facebook上API例如Photos.upload)文件僅

另外的情況下,基於這個API參考,http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application,這是你做錯了什麼。

1)請勿使用HashMap來存儲Facebook參數。參數必須是sorted。而是使用SortedMap接口並使用TreeMap來存儲Facebook參數。

2)始終包括在地圖sig參數之前將呼叫發送到Facebook。您收到「104錯誤簽名」,因爲Facebook在您的請求中找不到sig參數。

參考文獻(http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application)顯示瞭如何創建Facebook使用的MD5簽名。

以下是如何快速爲Facebook創建sig值。

String hashString = ""; 
     Map<String, String> sortedMap = null; 
     if (parameters instanceof TreeMap) { 
      sortedMap = (TreeMap<String, String>) parameters; 
     } else { 
      sortedMap = new TreeMap<String, String>(parameters); 
     } 

     try { 
      Iterator<String> iter = sortedMap.keySet().iterator(); 
      StringBuilder sb = new StringBuilder(); 
      synchronized (iter) { 
       while (iter.hasNext()) { 
        String key = iter.next(); 
        sb.append(key); 
        sb.append("="); 
        String value = sortedMap.get(key); 
        sb.append(value == null ? "" : value); 
       } 
      } 
      sb.append(secret); 

      MessageDigest digest = MessageDigest.getInstance("MD5"); 
      byte[] digested = digest.digest(sb.toString().getBytes()); 

      BigInteger bigInt = new BigInteger(1, digested); 
      hashString = bigInt.toString(16); 
      while (hashString.length() < 32) { 
       hashString = "0" + hashString; 
      } 
     } catch (NoSuchAlgorithmException nsae) { 
      // TODO: handle exception 
      logger.error(e.getLocalizedMessage(), e); 
     } 

     return hashString;