2013-03-09 77 views
4

我寫了一個簡單的Java程序(JDK 1.7),列出了所有我的服務總線的主題,並打印出每個主題的名稱到stdout:連接Azure的服務總線與Android

  try { 

     String namespace = "myservicebus"; // from azure portal 
     String issuer = "owner"; // from azure portal 
     String key = "asdjklasdjklasdjklasdjklasdjk"; // from azure portal 

     Configuration config = ServiceBusConfiguration.configureWithWrapAuthentication(
       namespace, 
       issuer, 
       key, 
       ".servicebus.windows.net", 
       "-sb.accesscontrol.windows.net/WRAPv0.9"); 

     ServiceBusContract service = ServiceBusService.create(config); 
     ListTopicsResult result = service.listTopics(); 
     List<TopicInfo> infoList = result.getItems(); 
     for(TopicInfo info : infoList){ 
      System.out.println(info.getPath()); 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

現在,我試圖在一個簡單的Android項目(Android 4.2)中運行這個例子,但它不會工作。 運行時總是會引發以下錯誤:

java.lang.RuntimeException: Service or property not registered: com.microsoft.windowsazure.services.serviceBus.ServiceBusContract 

有沒有人成功地建立了從Android設備(或仿真器),以蔚藍的服務總線的連接?

Microsoft Azure-Java-SDK不支持android項目嗎?

在此先感謝

+0

呃......你可能想在上面的代碼示例中隱藏你的應用程序密鑰! – 2013-03-11 07:02:09

+0

您是否在Linux/Mac/Windows機器上嘗試過相同的示例代碼?你確定這是一個Android兼容性問題嗎? – 2013-03-11 17:38:33

+0

應用程序密鑰被遮擋;-) – stef 2013-03-11 19:56:08

回答

2

此錯誤是由於生成的APK不包括(刪除)的ServiceLoader信息(在META-INF /服務)的事實。您可以測試自己從生成的jar中刪除它,並看到出現相同的錯誤。在文檔中說它現在被支持,但我發現使用它的問題。

http://developer.android.com/reference/java/util/ServiceLoader.html

您可以使用Ant

Keep 'META-INF/services'-files in apk

10小時的調試後,手動刪除類,包括META-INF /服務等包含人工apk中的數據,我發現, Azure SDK使用一些不受Android支持的類(javax.ws。*)以及任何對我有用的工具。

所以我建議在Android環境中使用REST API,找到下面我用來sebd消息的主題代碼。

private static String generateSasToken(URI uri) { 
    String targetUri; 
    try { 
     targetUri = URLEncoder 
     .encode(uri.toString().toLowerCase(), "UTF-8") 
     .toLowerCase(); 

     long expiresOnDate = System.currentTimeMillis(); 
     int expiresInMins = 20; // 1 hour 
     expiresOnDate += expiresInMins * 60 * 1000; 
     long expires = expiresOnDate/1000; 
     String toSign = targetUri + "\n" + expires; 

     // Get an hmac_sha1 key from the raw key bytes 
     byte[] keyBytes = sasKey.getBytes("UTF-8"); 
     SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256"); 

     // Get an hmac_sha1 Mac instance and initialize with the signing key 
     Mac mac = Mac.getInstance("HmacSHA256"); 
     mac.init(signingKey); 
     // Compute the hmac on input data bytes 
     byte[] rawHmac = mac.doFinal(toSign.getBytes("UTF-8")); 

     // using Apache commons codec for base64 
//  String signature = URLEncoder.encode(
//  Base64.encodeBase64String(rawHmac), "UTF-8"); 
     String rawHmacStr = new String(Base64.encodeBase64(rawHmac, false),"UTF-8"); 
     String signature = URLEncoder.encode(rawHmacStr, "UTF-8"); 

     // construct authorization string 
     String token = "SharedAccessSignature sr=" + targetUri + "&sig=" 
     + signature + "&se=" + expires + "&skn=" + sasKeyName; 
     return token; 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

public static void Send(String topic, String subscription, String msgToSend) throws Exception { 

     String url = uri+topic+"/messages"; 

     HttpClient client = new DefaultHttpClient(); 
     HttpPost post = new HttpPost(url); 

     // Add header 
     String token = generateSasToken(new URI(uri)); 
     post.setHeader("Authorization", token); 
     post.setHeader("Content-Type", "text/plain"); 
     post.setHeader(subscription, subscription); 
     StringEntity input = new StringEntity(msgToSend); 
     post.setEntity(input); 

     System.out.println("Llamando al post"); 
     HttpResponse response = client.execute(post); 
     System.out.println("Response Code : " 
       + response.getStatusLine().getStatusCode()); 
     if (response.getStatusLine().getStatusCode() != 201) 
      throw new Exception(response.getStatusLine().getReasonPhrase()); 

} 

有關REST API Azure信息的更多信息。