2017-04-04 112 views
1

因此,我一直在爲此打開/關閉幾天,感覺好像我已經用盡了任何相關搜索條件。首先讓我說說我已經做了一個很多的研究到這無濟於事;我得出的結論是,它要麼是非常不正常的(不太可能),要麼是我忽略了的一些微小細節。讓我也直接說蝙蝠,是的,我知道直接從應用程序連接到數據庫是不理想的,我應該使用Web服務器,但爲了我的意圖和目的,這個解決方案不是一個問題。在Android Studio中,與Azure的JDBC連接失敗

我知道這篇文章超長,但我非常感謝大家的時間。如果沒有別的,至少它可能會幫助最近開始使用JDBC並已經開始遇到問題的其他人。 「我所嘗試過的」部分概述了絕大多數嘗試的事情,您可以在網上找到。

我想要做的事:

使用JDBC驅動程序,連接到通過Android Studio中我的Azure的託管SQLServer數據庫。

我遇到的錯誤:

W/System.err: com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host vet-to-go.database.windows.net, port 1433 has failed. Error: "Connection timed out: no further information. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.". 

我已經試過/驗證(短名單):

- 連接代碼發生的活動類中,但是它在一個AsyncTask。

-uses-許可的android:NAME = 「android.permission.INTERNET對」

-Azure防火牆配置爲允許我的IP連接。

-Windows防火牆有規則的地方,允許傳入&傳出流量在端口1433上

- 從SQLServer的配置管理器,我已經啓用命名管道& TCP/IP。在「IP地址」選項卡上,我已啓用全部並將TCP端口設置爲1433.已嘗試使用&關閉TCP動態端口。

- 已嘗試使用SQL Server Browser運行&已停止(另一篇文章中提到這麼做)。

- 曾嘗試使用jre7 & jre8 JDBC驅動程序。

-sourceCompatibility & targetCompatibility在相應的1_7或1_8版本中設置。

-compile文件(「庫/ sqljdbc41.jar」)或42 jre8]

- 更拼命,並確保他們沒有問題,我也沒打開Windows防火牆後連接完全關閉,並且允許任何IP經由天青防火牆(爲0.0.0.0開始/結束IP - 255.255.255.255)連接

-I 可以平&遠程登錄到(mydbname).database.windows。網絡1433(都DNS &實際IP)

考慮到上述所有,我只能假設錯誤落在我的代碼內的某處,但我絕對不知道在哪裏。爲了在棺材中釘上一顆釘子,應該提到我能夠成功查詢DB &在我的項目中返回一個值,但是只在一個靜態的非活動類中。當添加到實際活動類時,複製代碼幾乎完全沒有結果。

這裏的工作代碼:

import java.sql.*; 

public class DatabaseHelper { 

public static void main(String[] args) throws Exception { 
    String custID = "1"; 
    String connectionString = "jdbc:sqlserver://vet-to-go.database.windows.net:1433;database=Vet To Go DB;[email protected];password=myPass;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"; 
    String queryString = "SELECT FirstName, LastName FROM Tbl_Customer WHERE CustomerID = " + custID; 

    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 
    Connection myConnection = DriverManager.getConnection(connectionString); 
    Statement myStatement = myConnection.createStatement(); 
    ResultSet myResultSet = myStatement.executeQuery(queryString); 

    myResultSet.next(); 
    String firstName = myResultSet.getString("FirstName"); 
    String lastName = myResultSet.getString("LastName"); 

    System.out.println(firstName); 
    System.out.println(lastName); 

    myStatement.close(); 
    myConnection.close(); 
} 

} 

我知道一些代碼看起來奇怪,因爲我希望將它合併到另一個類是隻。這是我最近在這樣的嘗試(正如我所說,我已經在它一段時間,所以我已經嘗試了一些不同的組合)

import android.content.Context; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.TextView; 

import java.sql.*; 

public class LandingPage extends AppCompatActivity { 

TextView txtFirst, txtLast; 
String firstName, lastName, customerID; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_landing_page); 
    txtFirst = (TextView)findViewById(R.id.txtFirstName); 
    txtLast = (TextView)findViewById(R.id.txtLastName); 

    customerID = getIntent().getStringExtra("custID"); 

    new myAsyncTask(LandingPage.this).execute(); 

    txtFirst.setText(firstName); 
    txtLast.setText(lastName); 
} 

public class myAsyncTask extends AsyncTask<Void, Void, String> { 
    String connectionString = "jdbc:sqlserver://vet-to-go.database.windows.net:1433;database=Vet To Go DB;[email protected];password=myPass;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"; 
    String queryString = "SELECT FirstName, LastName FROM Tbl_Customer WHERE CustomerID = " + customerID; 
    Context context; 


    public myAsyncTask(Context context) { 
     System.out.println("Async instantiated."); 
     this.context = context; 
    } 
    protected void onPreExecute() { 
     System.out.println("Pre-executing Async task."); 
    } 

    protected String doInBackground(Void... params) { 
     try { 
      System.out.println("Attempting to connect to DB..."); 
      Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 
      Connection con = DriverManager.getConnection(connectionString); 
      Statement st = con.createStatement(); 
      ResultSet rs = st.executeQuery(queryString); 

      while (rs.next()) { 
       System.out.println("Sorting through ResultSet..."); 
       firstName = rs.getString("FirstName"); 
       lastName = rs.getString("LastName"); 
      } 

     } catch (SQLException ex) { 
      ex.printStackTrace(); 
     } catch (ClassNotFoundException ex) { 
      ex.printStackTrace(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
     return "Complete"; 
    } 

    protected void onPostExecute(String result) { 
     if (result.equals("Complete")) { 
      System.out.println("Async task complete."); 
     } 
    } 
} 
} 

運行上面的代碼後,我得到了「連接到主機vet-to-go.database.windows.net,端口1433的TCP/IP連接失敗。「錯誤在這行:

Connection con = DriverManager.getConnection(connectionString); 

我不認爲這是相關的,但爲了以防萬一它是,這裏的一切,是目前在MainActivity

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    etID = (EditText)findViewById(R.id.etCustID); 
    btnSubmit = (Button)findViewById(R.id.btnSubmit); 

    btnSubmit.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      customerID = etID.getText().toString(); 
      myIntent = new Intent(MainActivity.this, LandingPage.class); 
      myIntent.putExtra("custID", customerID); 

      startActivity(myIntent); 
     } 
    }); 
} 

過Android Studio 2.3

內部編號AI-162.3764568,始建於2017年2月24日

JRE:1.8.0_112-釋放-B06 AMD64

JVM:OpenJDK的64位服務器VM通過JetBrains的SRO

搖籃3.3版

目標API 22:Android的5.1

敏SDK 21節

構建工具v 25.0.0

回答

0

首先,直接連接Azure並不是一個好主意Android上的SQL數據庫。通常,推薦的方式是通過調用一些在Azure上創建爲Web App或Mobile App的REST API來訪問數據庫。

其次,與你的類似的問題,許多現有的SO線程,解決方法解決方案是使用jTDS驅動程序,而不是Android上的MS SQL Server驅動程序sqljdbc連接,因爲sqljdbc司機似乎不完全支持在Android上。作爲參考資料,請參閱下面已解決的這些主題。

  1. https://social.msdn.microsoft.com/forums/sqlserver/en-US/4799819a-27fd-4292-a3d8-f114207c20b2/using-the-jdbc-driver-with-android
  2. Sql Database connect Using the JDBC Driver with android
  3. how to connect sql server using JTDS driver in Android

希望它能幫助。

+0

是的,我在帖子中提到,我知道直接連接並不是最佳實踐,但對於這種特定情況,這並不重要。我也已經構建了一個C#桌面應用程序,並使用直接連接,所以我想保持一致。我遇到了一些使用jTDS的建議,但認爲我只是在做一些錯誤的事情,所以我想堅持使用官方的MS。但是,如果事實證明,我確實沒有什麼可以做的不同,我很可能不得不走這條路。謝謝! – Nick