Is there a way that we can connect an Android application to a central database server (e.g. MSSQLServer 2008)?
I have a MySQL database that is accessed by both website and Android. Connecting to the database from the website is fine, but how can it be done from the Android app?
here are some similar questions asked (an answered):
android MySQL connection
How to connect to a MySQL Database from an Android App?
Even though those are for MySQL, it should work for MSSQL by changing the engine or the driver's use to connect. Usually, the approach is to expose some limited level of modification through a web service. Still, nothing is stopping you from directly accessing the database, albeit depending on the case, could pose a security risk.
Main Reasons the web service approach is taking:
Performance
Security
Best Practice
Separation of concerns
An exception is if you want to enable direct access because you're building a sort of database client through mobile.
All you have to do is use the appropriate driver, i'd recommend using JTDS, and version 1.2.5 seems to have worked well with android.Detailed instruction on how to use with eclipse can be found here
A working code is available in github
/**
* This is a demo code to demonstrate db connection and operations and not
* meant for a live run.
*
*/
public class DBTestActivity extends Activity {
private Connection conn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dbtest);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.dbtest, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
(new DBConnection()).execute(null, null, null);
}
#Override
protected void onPause() {
super.onPause();
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
class DBConnection extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... arg0) {
try {
Log.e("MSSQL", "Attempting to connect");
Class.forName("net.sourceforge.jtds.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:jtds:sqlserver://yourserver.com/DBName",
"username", "password");
Log.e("MSSQL", "Connected");
} catch (Exception e) {
e.printStackTrace();
Log.e("MSSQL", e.toString());
}
return null;
}
}
class UserInfo {
String userID;
String userName;
String PhoneNo;
String age;
public UserInfo(String userID, String userName, String PhoneNo,
String age) {
this.userID = userID;
this.userName = userName;
this.PhoneNo = PhoneNo;
this.age = age;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPhoneNo() {
return PhoneNo;
}
public void setPhoneNo(String phoneNo) {
PhoneNo = phoneNo;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
class DBOperation {
public List<UserInfo> getAllUsers() throws SQLException {
Statement statement = getStatement(conn);
List<UserInfo> userlist = new ArrayList<UserInfo>();
ResultSet rs = statement.executeQuery("SELECT * FROM UserInfoTable");
rs.next();
int count = 0;
while (rs.next()) {
userlist.add(new UserInfo(rs.getString(1), rs.getString(2),
rs.getString(3), rs.getString(4)));
count++;
}
rs.close();
statement.close();
return userlist;
}
public void addUser(UserInfo info) {
Log.e("MSSQL", "in adduser");
Statement statement = getStatement(conn);
try {
ResultSet rs = statement.executeQuery("INSERT INTO UserInfoTable "
+ " VALUES ('1001', 'Bob', '333333', '33')");
rs.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private Statement getStatement(Connection connection) {
try {
return connection.createStatement();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
An other approach, musch simpler than Web Service, is to use a Virtual JDBC Driver that uses a three-tier architecture: your JDBC code is sent through HTTP to a remote Servlet that filters the JDBC code (configuration & security) before passing it to the SQL Server JDBC Driver. The result is sent you back through HTTP. There are some free software that use this technique. Just Google "Android JDBC Driver over HTTP".
Connecting your android application directly to an external database server is a bad idea, instead create a web application and access the database through that.
There are a number of strategies you can employ to accomplish what you want to do. Given that the SOAP support for Android is non-existent, you're going to most likely want to push the data out in either XML or JSON format through WCF, ASP.NET, Ruby On Rails, PHP or any number of web frameworks.
Without knowing what your web application is currently running, it's hard to say how to best make that data connection. You can use WCF Data Services if you want to get up and running as fast as possible, and MSDN has a decent article on getting started with it:
http://msdn.microsoft.com/en-us/library/cc668792.aspx
I suggest that you examine your existing solution and figure out how to best extend that to push data out to your Android app.
i've try to connect android via PHPto ms sql server, you can read here,am using httprequest and json. If you want to connect to Ms SQL Server 2005 or higher, you must download Microsoft Driver for PHP for SQL Server.
I've used php as web service to connect Ms SQL Server database, anyway you can used jdbc to connect from android direct to MS SQL Server database
If you need to do that probably you donìt have already a 3 tier architecture. If this is the case consider writing a mobile web application.
I did that to add mobile interface to a client server 2 tier legacy system.
I had a legacy Delphi client/server app, and i created by using Raudus a web app optimized for mobile devices. Of course this makes sense if you have Delphi skills, but for other languages/tecnhologies there are the coutnerparts.
Related
I'm new to android and not much aware about it. I though have been through tutorial but still didn't get any solution. How to connect Android Studio with postgressql? Step by step!
I wrote this code in my MainActitvity.java. Is this correct? Or should I write it else where?
static final String JDBC_DRIVER = "org.postgresql.Driver";
static final String DB_URL = "jdbc:postgresql://localhost:5432/user1";
// Database credentials
static final String USER = "root";
static final String PASS = "root";
public static void main(String[] args)
{
Connection conn = null;
Statement st = null;
try{
//STEP 2: Register JDBC driver
Class.forName("org.postgresql.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/","root","root");
//STEP 4: Execute a query
System.out.println("Creating statement...");
st = conn.createStatement();
String sql;
sql = "SELECT first, last FROM Employees";
ResultSet rs = st.executeQuery(sql);
//STEP 5: Extract data from result set
while(rs.next()){
//Retrieve by column name
String first = rs.getString("first");
String last = rs.getString("last");
//Display values
System.out.print(", First: " + first);
System.out.println(", Last: " + last);
}
//STEP 6: Clean-up environment
rs.close();
st.close();
conn.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}
finally
{
//finally block used to close resources
try{
if(st!=null)
st.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}
catch(SQLException se){
se.printStackTrace();
}//end finally try
}
}
use 10.0.2.2 instead of localhost, it works for me.
You cannot directly use java.sql.DriverManger, Connection, etc in Android. Android support SQLite DB, if you want to use DB in android you have to go with SQLite database. For Postgres you have to develop server side application and api services which you can the call from Android
Okay, this may be obsolete but still helpful for users (it was helpful for me)
I copied your example and worked with it because I also need to get postgres running on android. And it works!
conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/","root","root");
This will result in an error because you need to enter the database name without a slash at the and, like:
conn = DriverManager.getConnection("jdbc:postgresql://domain.com:5432/databaseName", "username", "password");
Network connections (like connection to database) must be done in an AsyncTask using doInBackground(). I did it inside an activity
public class dbactivity extends AppCompatActivity { //sry code formatting just broke
String message = null;
String conmsg = null;
private class pgsqlcon extends AsyncTask<Void, Void, Void>
{
public pgsqlcon()
{
super();
}
#Override
protected Void doInBackground(Void... voids) {
Connection conn = null;
Statement st = null;
try
{
//STEP 2: Register JDBC driver
Class.forName("org.postgresql.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
message = "Connecting to database...";
conn = DriverManager.getConnection("jdbc:postgresql://serverdomain.com:5432/databasename",
"dbusername", "password");
//and so on
If you need to make UI changes like setText, you must use runOnUiThread like so ():
//using quote because code formatting doesn't work anymore for me xD
private void setAsyncText(final TextView text,final String value){
runOnUiThread(new Runnable() {
#Override
public void run() {
if (value == null)
text.setText("null");
else
text.setText(value);
}
});
}
Oh yeah and last but not least, since I wrote this inside an Activiy, I have to trigger the trouble by calling my asynctask in OnCreate() of my Activity.
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dbactivity);
pgsqlcon pgcon = new pgsqlcon();
pgcon.execute();
}
}
I am not that experienced by myself so you can use this only for getting a connection at all to your postgresdb using JDBC only. Although I managed to get successful query results that way.
And again, sorry for the wrong code formatting. I did what they wanted (4 space rule etc.) and it didn't work. I hope you can read it anyway, good luck.
And if nothing of this does work, maybeeee you want to take a look at these little hints: https://jdbc.postgresql.org/documentation/head/prepare.html
(I assume you did that anyway since you have done a lot of almost correct code)
My app uses PostgreSQL as backend. Use the retrofit library for connecting to the backend. In my app backend is written in python which will make queries in the database. This will make the front-end codes more smooth and secure. And the more controls can be shifted to the back-end.
You can not connect the database with android studio directly,
you have to make connection with your application and database through api ,
and you can write your api in java, php etc.
?php
$db_connection = pg_connect("host=localhost dbname=record user=postgres password= ''");
//pg query
?>
This is your connect query api.
I need a working example for a custom API for Microsoft Azure App Service.
I could not get any useful or working information/examples for that, or they just show each time different approaches which are outdated?!?!
For now I have a working table controller which gets information from database and returns it back to my Android client. Now I need to define a custom API Controller to get a string back. In the examples they are all sending an object to the service in order to get an object back. I do not want to send anything to the API, just retrieve some information back from a GET Request.
Regards
// EDIT - Added / edited client / server code to Post a String.
You can use the following code to do a GET request on the auto generated API controller Visual Studio creates (ValuesController).
private void getStringFromAzure() throws MalformedURLException {
// Create the MobileService Client object and set your backend URL
String yourURL = "https://yourApp.azurewebsites.net/";
MobileServiceClient mClient = new MobileServiceClient(yourURL, this);
// Your query pointing to yourURL/api/values
ListenableFuture<JsonElement> query = mClient.invokeApi("values", null, GetMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
// Since you are on a async task, you need to show the result on the UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onFailure(Throwable throwable) {
Log.d(TAG, "onFailure: " + throwable.getMessage());
}
});
}
public void sendString(final String someString) throws MalformedURLException {
// Your query pointing to /api/values/{String}
ListenableFuture<JsonElement> query = mClient.invokeApi("values/" + someString, null, PostMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
}
#Override
public void onFailure(Throwable throwable) { }
});
}
The backend API: (ValuesController)
{
// Use the MobileAppController attribute for each ApiController you want to use
// from your mobile clients
[MobileAppController]
public class ValuesController : ApiController
{
// GET api/values
public string Get()
{
return "Hello World!";
}
// POST api/values/inputString
public string Post(string inputString)
{
return inputString;
}
}
}
You can also send parameters along in the following way:
List<Pair<String, String>> parameters = new ArrayList<>();
parameters.add(new Pair<>("name", "John"));
parameters.add(new Pair<>("password", "fourwordsalluppercase"));
ListenableFuture<JsonElement> query = client.invokeApi("yourAPI", PostMethod, parameters);
Or as json in the body:
JsonObject body = new JsonObject();
body.addProperty("currentPassword", currentPassword);
body.addProperty("password", password);
body.addProperty("confirmPassword", confirmPassword);
ListenableFuture<JsonElement> query = mClient.invokeApi("yourAPI", body, PostMethod, null);
Based on my understanding, I think there are two parts in your question which include as below. And I think you can separately refer to two sections to get the answers and write your own example.
How to define a custom API on Azure Mobile App to retrieve data from database? Please refer to the section Custom APIs to know how to do with Azure Mobile App backend.
How to call a custom API from Android App? Please refer to the section How to: Call a custom API to know how to do with Android SDK.
I have been trying to create a GAE to get and insert data into my Android Application. I used the Eclipse wizard to create both projects (app engine connected android project). I am using JDO and trying to create unique primary keys but it doesn't seem to be doing it for me and I think that it should although i'm probably wrong. The server keeps popping out messages that the primary key should not be 0. Im new to this and was testing it out. Here is the code I feel is relevant (please let me know if more is needed). As to my understanding, it should be getting its key when the server calls makepersistant().
#ApiMethod(name = "insertTrack")
public Track insertTrack(Track track) {
PersistenceManager mgr = getPersistenceManager();
try {
if (containsTrack(track)) {
throw new EntityExistsException("Object already exists");
}
mgr.makePersistent(track);
} finally {
mgr.close();
}
return track;
}
This is what my app is calling:
public class EndpointsTask extends AsyncTask<Context, Integer, Long> {
protected Long doInBackground(Context... contexts) {
Trackendpoint.Builder endpointBuilder = new Trackendpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) { }
});
Trackendpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
try {
Track track = new Track();
track.setName("1");
track.setDesc("First Track on Server");
Track result = endpoint.insertTrack(track).execute();
} catch (IOException e) {
e.printStackTrace();
}
return (long) 0;
}
}
And the JDO
public class Track {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private long trackID;
private String name;
private String desc;
Any help leading me in the right direction would be awesome. Thanks in advance!
Is there a way that we can connect an Android application to a central database server (e.g. MSSQLServer 2008)?
I have a MySQL database that is accessed by both website and Android. Connecting to the database from the website is fine, but how can it be done from the Android app?
here are some similar questions asked (an answered):
android MySQL connection
How to connect to a MySQL Database from an Android App?
Even though those are for MySQL, it should work for MSSQL by changing the engine or the driver's use to connect. Usually, the approach is to expose some limited level of modification through a web service. Still, nothing is stopping you from directly accessing the database, albeit depending on the case, could pose a security risk.
Main Reasons the web service approach is taking:
Performance
Security
Best Practice
Separation of concerns
An exception is if you want to enable direct access because you're building a sort of database client through mobile.
All you have to do is use the appropriate driver, i'd recommend using JTDS, and version 1.2.5 seems to have worked well with android.Detailed instruction on how to use with eclipse can be found here
A working code is available in github
/**
* This is a demo code to demonstrate db connection and operations and not
* meant for a live run.
*
*/
public class DBTestActivity extends Activity {
private Connection conn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dbtest);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.dbtest, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
(new DBConnection()).execute(null, null, null);
}
#Override
protected void onPause() {
super.onPause();
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
class DBConnection extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... arg0) {
try {
Log.e("MSSQL", "Attempting to connect");
Class.forName("net.sourceforge.jtds.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:jtds:sqlserver://yourserver.com/DBName",
"username", "password");
Log.e("MSSQL", "Connected");
} catch (Exception e) {
e.printStackTrace();
Log.e("MSSQL", e.toString());
}
return null;
}
}
class UserInfo {
String userID;
String userName;
String PhoneNo;
String age;
public UserInfo(String userID, String userName, String PhoneNo,
String age) {
this.userID = userID;
this.userName = userName;
this.PhoneNo = PhoneNo;
this.age = age;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPhoneNo() {
return PhoneNo;
}
public void setPhoneNo(String phoneNo) {
PhoneNo = phoneNo;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
class DBOperation {
public List<UserInfo> getAllUsers() throws SQLException {
Statement statement = getStatement(conn);
List<UserInfo> userlist = new ArrayList<UserInfo>();
ResultSet rs = statement.executeQuery("SELECT * FROM UserInfoTable");
rs.next();
int count = 0;
while (rs.next()) {
userlist.add(new UserInfo(rs.getString(1), rs.getString(2),
rs.getString(3), rs.getString(4)));
count++;
}
rs.close();
statement.close();
return userlist;
}
public void addUser(UserInfo info) {
Log.e("MSSQL", "in adduser");
Statement statement = getStatement(conn);
try {
ResultSet rs = statement.executeQuery("INSERT INTO UserInfoTable "
+ " VALUES ('1001', 'Bob', '333333', '33')");
rs.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private Statement getStatement(Connection connection) {
try {
return connection.createStatement();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
An other approach, musch simpler than Web Service, is to use a Virtual JDBC Driver that uses a three-tier architecture: your JDBC code is sent through HTTP to a remote Servlet that filters the JDBC code (configuration & security) before passing it to the SQL Server JDBC Driver. The result is sent you back through HTTP. There are some free software that use this technique. Just Google "Android JDBC Driver over HTTP".
Connecting your android application directly to an external database server is a bad idea, instead create a web application and access the database through that.
There are a number of strategies you can employ to accomplish what you want to do. Given that the SOAP support for Android is non-existent, you're going to most likely want to push the data out in either XML or JSON format through WCF, ASP.NET, Ruby On Rails, PHP or any number of web frameworks.
Without knowing what your web application is currently running, it's hard to say how to best make that data connection. You can use WCF Data Services if you want to get up and running as fast as possible, and MSDN has a decent article on getting started with it:
http://msdn.microsoft.com/en-us/library/cc668792.aspx
I suggest that you examine your existing solution and figure out how to best extend that to push data out to your Android app.
i've try to connect android via PHPto ms sql server, you can read here,am using httprequest and json. If you want to connect to Ms SQL Server 2005 or higher, you must download Microsoft Driver for PHP for SQL Server.
I've used php as web service to connect Ms SQL Server database, anyway you can used jdbc to connect from android direct to MS SQL Server database
If you need to do that probably you donìt have already a 3 tier architecture. If this is the case consider writing a mobile web application.
I did that to add mobile interface to a client server 2 tier legacy system.
I had a legacy Delphi client/server app, and i created by using Raudus a web app optimized for mobile devices. Of course this makes sense if you have Delphi skills, but for other languages/tecnhologies there are the coutnerparts.
I know this question is asked before also, but I want to know whether we can Connect to external database (e.g mySQL) from android device without using a webservice.
I have already build the app using webservice but now they have asked us to make it without using webservice.
Can anybody knows or give any reference about same ?
I have all the required data about the database location i.e. server name, db name etc.
Actually in my requirement I am downloading and xml using a webservice which will have all the details the connection string, database name, server name, username , password etc. but the connection is to be done on runtime.
Yes you can connect to remote database directly. I'm unsure about it's security though.
Try this:
Download MySQL JDBC
Add the .jar file in your Android project and add it as a library.
Create a class that extends AsyncTask and execute the method there.
public class connectToServer extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... args) {
try {
connect();
} catch (Exception e) {
Log.e("Error", e.toString());
}
return null;
}
#Override
protected void onPostExecute(String file_url)
{
}
}
public void connect(){
Log.e("Android", "SQL Connection start");
Connection conn = null;
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String ip = "[your host server]";
String dbName = "[your dbName]";
String user = "[your userName]";
String password = "[your password]";
String connString = "jdbc:mysql://" + ip + "/" + dbName +
"";
conn = DriverManager.getConnection(connString, user, password);
Log.e("Connection", "Open");
Statement statement = conn.createStatement();
ResultSet set = statement.executeQuery("Select * from [table]");
statement.setQueryTimeout(0);
while(set.next())
{
Log.e("Data:", set.getString("[column_name]"));
}
}catch(Exception e)
{
Log.e("Error connection", e.toString());
}
}//end method