2

I have created a Public Class for my Database connection as am running various Database query's throughout the application

Every time i call the Class con always returns Null But if i use it outside of the Class, and directly in the Activity then it connects and runs. I have no idea why and would greatly appreciate any pointers in the right direction please.

Here are my ConnectionManager class:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;


public class ConnectionManager {
    static String serverName ="192.168.1.5";
    static String serverPort ="1433";
    static String databaseName ="DBNAME";
    static String db = String.format("jdbc:jtds:sqlserver://%s:%s/%s", serverName, serverPort, databaseName);
    static String un = "sa";
    static String pass = "";
    static Connection con;


    public static Connection getConnection() {
        try {
            try {
                Class.forName("net.sourceforge.jtds.jdbc.Driver");
                con = DriverManager.getConnection(db, un, pass);
            } catch (SQLException ex) {
                // log an exception. fro example:
                System.out.println("Failed to create the database connection.");
            }
        } catch (ClassNotFoundException ex) {
            // log an exception. for example:
            System.out.println("Driver not found.");
        }
        return con;
    }
}

And from within my Activity i am calling it as follow:

  try {

            con = ConnectionManager.getConnection();
            if (con == null) {
                z = "Check Your Internet Access!";
                Toast.makeText(StockEnquiry.this, z, Toast.LENGTH_LONG).show();
            } else {
                stmt = con.createStatement();
                String query = "select * from Details where ID= '1111'  ";
                rs = stmt.executeQuery(query);
                if (rs.next()) {
                    String sCode = rs.getString("Short_Code");
                    String sDesc = rs.getString("Short_Desc");
                    Toast.makeText(StockEnquiry.this, (sCode + " " + sDesc), Toast.LENGTH_LONG).show();
                    con.close();
                } else {
                    Toast.makeText(StockEnquiry.this,"Invalid Code!", Toast.LENGTH_LONG).show();
                }

                Toast.makeText(StockEnquiry.this, "Message1", Toast.LENGTH_LONG).show();
            }
        } catch (Exception ex) {
            isSuccess = false;
            z = ex.getMessage();
            Toast.makeText(StockEnquiry.this, "Appears to have failed in catch", Toast.LENGTH_LONG).show();
        }
    }
}
Michael
  • 41,989
  • 11
  • 82
  • 128
Dave Hamilton
  • 675
  • 1
  • 12
  • 23
  • 1
    Android apps generally do not use JDBC, and there is limited support for it. JDBC is not set up for transient Internet connections, and it requires you to bake the passphrase into the app (causing security problems). On the whole, Android apps talk to a Web service or other form of middleware instead of talking to a database directly. – CommonsWare Dec 13 '19 at 13:07
  • @CommonsWare This doesn't add any value to the question. Fact is, he *is* using JDBC and it should work. – Michael Dec 13 '19 at 13:11
  • 1
    @Michael: "This doesn't add any value to the question" -- it serves as a warning for others who encounter the question. We have more than enough reliability and security problems in Android; we do not need to be adding more. – CommonsWare Dec 13 '19 at 13:14
  • The Passphrase wont be an issue as it will be stored in sharedpref encrypted. I have hardcoded to eliminate things that could be causing it to fail, If i use all the connection strings within the activity, It connects and works fine. (This isnt something that will be offered globally either, its a app for changing values locally ONLY) – Dave Hamilton Dec 13 '19 at 13:16
  • any specific reason the connection variable is declared static ? – beginner_coder Dec 13 '19 at 13:28

1 Answers1

0

So the message i was getting back was: android.os.NetworkOnMainThreadException' After some digging i believe i am facing the issue because i am not running it as a asynchronous task.

Its possible to remove this restriction

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy); 

So the connection class would look like the following.

import android.os.StrictMode;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;


public class ConnectionManager {
    static StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    static String serverName ="192.168.1.1";
    static String serverPort ="1433";
    static String databaseName ="DatabaseName";
    static String db = String.format("jdbc:jtds:sqlserver://%s:%s/%s", serverName, serverPort, databaseName);
    static String un = "Username";
    static String pass = "Password";
    static Connection con;


    public static Connection getConnection() {
        try {
            try {
                StrictMode.setThreadPolicy(policy);
                Class.forName("net.sourceforge.jtds.jdbc.Driver");
                con = DriverManager.getConnection(db, un, pass);
            } catch (SQLException ex) {
                // log an exception. fro example:
                System.out.println("Failed to create the database connection.");
            }
        } catch (ClassNotFoundException ex) {
            // log an exception. for example:
            System.out.println("Driver not found.");
        }
        return con;
    }
}

Calling the code from within the activity is untouched from the original post.

As a knock-on effect from this, You may get Application Crash / Lock-ups or slowness on poor network connection / coverage. So its a bit of a sacrifice, but can be handled in other ways.

Dave Hamilton
  • 675
  • 1
  • 12
  • 23