How to call stored procedures from android app? - android

I want to call a stored procedure from sql server to operate a login page
but keep getting this error:
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Sp
{
public static void main(String[] args)
{
String dbName = "My_database";
String serverip="192.168.5.10";
String serverport="1433";
String url = "jdbc:sqlserver://"+serverip+"\\SQLEXPRESS:"+serverport+";databaseName="+dbName+"";
try
{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
}
Connection con=null;
CallableStatement cstmt=null;
try
{
String databaseUserName = "sa";
String databasePassword = "a123";
con= DriverManager.getConnection(url, databaseUserName, databasePassword);
cstmt=con.prepareCall("{? = call spLoginvalidate(#CO_ID)}");//called the procedure
//how to create procedure had writen in bellow
cstmt.executeUpdate();
System.out.println("done");
}
catch(SQLException ex)
{
ex.printStackTrace();
}
finally
{
try
{
if(cstmt!=null) //close the callablestatement
{
cstmt.close();
cstmt=null;
}
}
catch(SQLException ex)
{
ex.printStackTrace();
}
try
{
if(cstmt!=null) //close the connection
{
cstmt.close();
cstmt=null;
}
}
catch(SQLException ex)
{
ex.printStackTrace();
}
}
}
}
My error message is:
com.microsoft.sqlserver.jdbc.SQLServerException: The value is not set for the parameter number 1.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.buildParamTypeDefinitions(SQLServerPreparedStatement.java:260)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.buildPreparedStrings(SQLServerPreparedStatement.java:219)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doPrepExec(SQLServerPreparedStatement.java:612)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:400)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:314)
at com.first.mainapp.Sp.main(Sp.java:45)
What needs to be done if I want to use the stored procedure to validate a login

Instead of
cstmt=con.prepareCall("{? = call spLoginvalidate(#CO_ID)}");//called the procedure
try
cstmt=con.prepareCall("{EXEC ? = spLoginvalidate(?)}");//called the procedure
cs.registerOutParameter(1, Types.INT);
cs.setInt(2, 1000);//your #CO_ID value here
More information you can get here: http://www.xyzws.com/javafaq/how-to-call-a-stored-procedure-by-jdbc-java-class/169
SQL Server does not know the call statement. Use EXEC instead.

Related

How can I add Async Task in my Android Studio project?

I am new to Android and are trying to connect a mysql database to my android app, but I don't get it with the Async Task to work.
What is the best way to use Async Task in here.
Note: "name_db=readSQL1();
System.out.println(name_db+"###########################");" this prints
hier sollte name###########################
Here is my code:
b_login.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
name_db=readSQL1();
System.out.println(name_db+"###########################");
name_to_check=ed_name.getText().toString();
pw_temp=ed_pw.getText().toString();
try { pw_hash=hash(getSHA(ed_pw.getText().toString()));
} catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
for(int i=0;i<user_arr.size();i++) {
if (name_to_check.equals(user_arr.get(i)) && pw_hash.equals(pw_arr.get(i))) {
startActivity(new Intent(MainActivity.this, com.example.new_app.UserMain.class).putExtra("user_name",name_to_check));
} else {
Toast.makeText(getApplicationContext(), "Wrong Credentials", Toast.LENGTH_SHORT).show();
tx_counter.setVisibility(View.VISIBLE);
tx_counter.setBackgroundColor(Color.WHITE);
counter--;
tx_counter.setText(Integer.toString(counter));
if (counter==0){
b_login.setEnabled(false);
}
}
}
}
});
b_cancel.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
finish();
}
});
}
public static String hash(byte[] hashwert){
BigInteger number=new BigInteger(1,hashwert);
StringBuilder hexString=new StringBuilder(number.toString(16));
while (hexString.length()<32) hexString.insert(0,"0");
return hexString.toString();
}
public static byte[] getSHA(String input) throws NoSuchAlgorithmException{
MessageDigest md=MessageDigest.getInstance("SHA-256");
return md.digest(input.getBytes(StandardCharsets.UTF_8));
}
public static String readSQL1(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
String name="hier sollte name";
try{
String url1 = "jdbc:mysql://host.de:3306/h153555_androidstudio?serverTimezone=UTC";
String user = "username"; String password = "password"; String database="user_db"; //password and username temporary
conn = DriverManager.getConnection(url1, user, password);
if (conn != null) {
stmt=conn.createStatement();
String select="SELECT NAME, PW FROM "+database;
rs=stmt.executeQuery(select);
System.out.println("read");
while(rs.next()){
name=rs.getString("NAME"); String pw=rs.getString("PW");
}
}
}catch(SQLException e){
System.out.println(e); System.out.println("read fehler");
}finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { stmt.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}
return name;
}
Take a look in android developers references:
https://developer.android.com/reference/android/os/AsyncTask
And you can simply use the FutureTask class
https://developer.android.com/reference/java/util/concurrent/FutureTask
You can use it this way, the Callable call function is the function that run in the task execute process.
FutureTask futureTask_1 = new FutureTask(new Callable<Integer>()
{
#Override
public Integer call() throws Exception {
return 0;
}
});
ExecutorService executor = Executors.newFixedThreadPool(1);
List<FutureTask> taskList = new ArrayList<FutureTask>();
taskList.add(futureTask_1);
executor.execute(futureTask_1);
futureTask_1.get();

Can i connect an android client through native java.net.Socket with a node js server which uses socket.io?

I built a server using node.js and socket.io for a chat application and I want to connect to the server from my android client application that uses native java.net.Socket. Can I do it?
Here I found a solution that works fine. This code section is for server side socket.
var net = require('net');
var sockets = [];
var svr = net.createServer(function(sock) {
console.log('Connected: ' + sock.remoteAddress + ':' + sock.remotePort);
sockets.push(sock);
sock.write('Welcome to the server!\n');
sock.on('data', function(data) {
for (var i=0; i<sockets.length ; i++) {
if (sockets[i] != sock) {
if (sockets[i]) {
sockets[i].write(data);
}
}
}
});
sock.on('end', function() {
console.log('Disconnected: ' + sock.remoteAddress + ':' + sock.remotePort);
var idx = sockets.indexOf(sock);
if (idx != -1) {
delete sockets[idx];
}
});
});
var svraddr = '192.168.0.8';
var svrport = 1234;
svr.listen(svrport, svraddr);
console.log('Server Created at ' + svraddr + ':' + svrport + '\n');
Android client side code is given below: connect to the given ip and port for server through android client side.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
public class Client {
private Socket socket;
private OutputStream socketOutput;
private BufferedReader socketInput;
private String ip;
private int port;
private ClientCallback listener=null;
public Client(String ip, int port){
this.ip=ip;
this.port=port;
}
public void connect(){
new Thread(new Runnable() {
#Override
public void run() {
socket = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress(ip, port);
try {
socket.connect(socketAddress);
socketOutput = socket.getOutputStream();
socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
new ReceiveThread().start();
if(listener!=null)
listener.onConnect(socket);
} catch (IOException e) {
if(listener!=null)
listener.onConnectError(socket, e.getMessage());
}
}
}).start();
}
public void disconnect(){
try {
socket.close();
} catch (IOException e) {
if(listener!=null)
listener.onDisconnect(socket, e.getMessage());
}
}
public void send(String message){
try {
socketOutput.write(message.getBytes());
} catch (IOException e) {
if(listener!=null)
listener.onDisconnect(socket, e.getMessage());
}
}
private class ReceiveThread extends Thread implements Runnable{
public void run(){
String message;
try {
while((message = socketInput.readLine()) != null) { // each line must end with a \n to be received
if(listener!=null)
listener.onMessage(message);
}
} catch (IOException e) {
if(listener!=null)
listener.onDisconnect(socket, e.getMessage());
}
}
}
public void setClientCallback(ClientCallback listener){
this.listener=listener;
}
public void removeClientCallback(){
this.listener=null;
}
public interface ClientCallback {
void onMessage(String message);
void onConnect(Socket socket);
void onDisconnect(Socket socket, String message);
void onConnectError(Socket socket, String message);
}
}
MainActivity is:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Client socket = new Client("192.168.0.8", 1234);
socket.setClientCallback(new Client.ClientCallback () {
#Override
public void onMessage(String message) {
}
#Override
public void onConnect(Socket socket) {
socket.send("Hello World!\n");
socket.disconnect();
}
#Override
public void onDisconnect(Socket socket, String message) {
}
#Override
public void onConnectError(Socket socket, String message) {
}
});
socket.connect();
}
}
The answer to your question is No. A java.net.socket cannot be connected with a nodejs socket.io because the protocol specifications are different for both.
Note: Socket.IO is not a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds some metadata to each packet: the packet type, the namespace and the ack id when a message acknowledgement is needed. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a WebSocket server (like ws://echo.websocket.org) either. Please see the protocol specification here.
Quoted From nodejs socket.io github page.So when web socket cannot be connected to socket.io so the java.net.socket can also be not connected.
If you want to have communication with the java client you can use the Socket.io library designed for java.
In Nodejs, You can use from this example
And in Sockect.io blog
In Java, as a server, you can use PrintWriter to write your data on Socket in a very simple situation. like below open socket on port 9090 and send current date to the client:
/**
* Runs the server.
*/
public static void main(String[] args) throws IOException {
ServerSocket listener = new ServerSocket(9090);
try {
while (true) {
Socket socket = listener.accept();
try {
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
out.println(new Date().toString());
} finally {
socket.close();
}
}
}
finally {
listener.close();
}
}
Code from here

ResultSet to Android Cursor

I my connecting to a MySQL database that is on PC from my android application.
I am using java.sql.jdb for that. Now I want my result set to get in android.database.cursor??
How can I do that..??
Thats my code I am using in android application its getting the results for database but can't cast to Cursor:
Connection connect = null;
ResultSet resultSet = null;
Statement statement = null;
try {
connect = DriverManager.getConnection("jdbc:mysql://"+DbHelper.DB_Path+"/"+DbHelper.DB_Name+"?"
+ "user="+ DbHelper.DB_UserName+ "&password="+ DbHelper.DB_Pass);
statement = connect.createStatement();
// Result set get the result of the SQL query
resultSet = statement
.executeQuery("Select * from btag_store "+
"Where "+
"guid='"+filterArgs+"'");
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Cursor cc;
cc = (Cursor) resultSet; // error in type casr
I know that type casting will give me error, but is there any other way for that..??
Thanks
To put it simply, you cannot. Unless you are willing to do all the work to define an object that implements the Cursor interface and uses a ResultSet to fulfil Cursor's implementation details. That would be somewhat silly, though, as the ResultSet object is already designed to iterate over results returned from the database. The cleanest approach is to use the ResultSet object as it was intended.
What Dave said is correct. My database items were constructed upon Cursor (Sqlite) but I need the same entrypoint wiht MySQL. So I tried this:
I created a base class
AbstractCursorGen.java:
import android.database.Cursor;
import java.sql.ResultSet;
public abstract class AbstractCursorGen {
protected Cursor c;
protected ResultSet rs;
public abstract int getColumnIndex(String iName);
public abstract String getString(String iName);
public abstract int getInt(String iName);
public abstract long getLong(String iName);
public abstract boolean moveToNext();
public abstract void close();
}
Then the one using Cursor will hold the instance of cursor. There is an additional benefit by getting result giving directly the column string. My code uses this for SQLite.
CursonGen.Java:
import android.database.Cursor;
public class CursorGen extends AbstractCursorGen{
public CursorGen(Cursor c)
{
this.c = c;
}
public int getColumnIndex(String iName)
{
return c.getColumnIndex(iName);
}
public String getString(String iName){
return c.getString(getColumnIndex(iName));
}
public int getInt(String iName){
return c.getInt(getColumnIndex(iName));
}
public long getLong(String iName){
return c.getLong(getColumnIndex(iName));
}
public boolean moveToNext()
{
return c.moveToNext();
}
public void close()
{
c.close();
}
}
And one built upon the resultset. This is used for MySQL results
ResultSetGen.java
import android.util.Log;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ResultSetGen extends AbstractCursorGen{
public ResultSetGen(ResultSet rs)
{
this.rs = rs;
}
public int getColumnIndex(String iName)
{
try {
return rs.findColumn(iName);
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return -1;
}
}
public String getString(String iName){
try {
return rs.getString(getColumnIndex(iName));
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return null;
}
}
public int getInt(String iName){
try {
return rs.getInt(getColumnIndex(iName));
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return -1;
}
}
public long getLong(String iName){
try {
return rs.getLong(getColumnIndex(iName));
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return -1;
}
}
public boolean moveToNext()
{
try {
return rs.next();
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
return false;
}
}
public void close()
{
try {
rs.close();
} catch (SQLException ex)
{
Log.e("PROX","Column not found");
}
}
}
The trick is providing implementation only for the methods I'm actually using.
This is finally called by (one example)
public Person(AbstractCursorGen cursor)
{
setFromCursor(cursor);
}
protected void setFromCursor(AbstractCursorGen cursor)
{
PersonID = cursor.getLong ( COLUMN_PERSON_ID);
ClusterID = cursor.getInt ( COLUMN_CLUSTER_ID);
Name = cursor.getString ( COLUMN_NAME);
.....
}
Hope this helps.

Consume WSDL to implement in Android ListView

I try to get the data from Web Service that I build with JAX-WS, WSDL and I want to implement in Android ListView.
This is my code in web service that I build on Netbeans.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package in.figures.on.mobile;
import db.koneksi.dbKoneksi;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import org.json.simple.JSONValue;
/**
*
* #author Setyadi
*/
#WebService()
public class AksesData {
/**
* Web service operation
*/
#WebMethod(operationName = "Lokasiku")
public String Lokasiku(
#WebParam(name = "lon") String lon,
#WebParam(name = "lat") String lat) {
//TODO write your implementation code here:
dbKoneksi con = new dbKoneksi();
Statement statement;
String sql = "SELECT desa "
+ "FROM dki "
+ "WHERE ST_Within(ST_SetSRID(ST_MakePoint("+lon+","+lat+"),0),geom);";
ResultSet hasil;
String desa = null;
try{
statement = con.getConnection().createStatement();
hasil = statement.executeQuery(sql);
hasil.next();
desa = hasil.getString(1);
}
catch(Exception e){
desa = "desa_thegagals";
}
finally{
}
if (con != null) {
return desa;
}
else {
return "lokasiku_thegagals";
}
}
/**
* Web service operation
*/
#WebMethod(operationName = "Kategori")
public String Kategori() {
//TODO write your implementation code here:
dbKoneksi con = new dbKoneksi();
Statement statement;
Properties properties;
List list = new ArrayList();
String sql = "SELECT kategori FROM kategori ";
ResultSet hasil;
String kategori = null;
try{
statement = con.getConnection().createStatement();
hasil = statement.executeQuery(sql);
while (hasil.next()) {
properties = new Properties();
properties.put("kategori", hasil.getString(1));
list.add(properties);
}
kategori = JSONValue.toJSONString(list);
}
catch(Exception e){
}
return kategori;
}
}
Does anybody want to help me, at least give me a tutorial about this.
Thanks in advance
Android doesn't provide any support for SOAP web services. They prefer we useRESTful web services with XML or JSON. however there are a few SOAP libraries out there. KSOAP is very popular, I personally have had issues with it. http://ksoap2.sourceforge.net/
Another suggestion is icesoap. it is a very simple library to use and understand, it worked like a charm for me.
http://code.google.com/p/icesoap/
For return data in 2D array
just get the data and convert it into String.
Then store it in Array
rs = s.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
colCount = rsmd.getColumnCount();
String[][] result;
result = new String[size][rsmd.getColumnCount()];
int j=0;
while(rs.next())
{
for (int i = 1; i <= colCount; i++)
{
Object value=null;
if(!rsmd.getColumnTypeName(i).matches("varchar"))
{
if(rsmd.getColumnTypeName(i).matches("decimal"))
value=(Object)rs.getDouble(i);
else
value=(Object)rs.getObject(i);
}
else
{
value = (Object)rs.getString(i);
}
if(value!=null)
{
result[j][i-1]=value.toString();
}
else
{
result[j][i-1]="--";
}
}j++;
}
}
catch (SQLException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and In android phone toy need to get that array and convert it into appropriate data type.
If you going to display it then you can display as it is. No need to convert into its original data type.

Android app fails to get access to the network

I am trying to connect to a chat server on the internet from an Android app so first I test whether I have contact with the server from an AsyncTask:
#Override
protected Void doInBackground(SocketAndEditText... soEd) {
try{
InetAddress address1 = InetAddress.getByName("130.237.161.23");
boolean reachable = address1.isReachable(4456);
//...
} catch (Exception e) {
//...
}
}
When I run the above code the variable reachable gets the value false but when I run the same code as a simple Java console application I get true:
import java.net.InetAddress;
public class Test {
public static void main(String[] args) {
try{
InetAddress address1 = InetAddress.getByName("130.237.161.23");
boolean reachable = address1.isReachable(4456);
System.out.println(reachable);
} catch (Exception e) {
//...
}
}
}
In my manifest file I have <uses-permission android:name="android.permission.INTERNET" />
Why does it not work in Android but works as a Java application?

Categories

Resources