I'm trying to connect my Android app to Oracle Database Express Edition 11g hosted on my laptop. I'm testing the app on my phone with its hotspot ON to which the laptop is connected via WiFi.
I've added ojdbc14.jar to app/libs directory and selected Add as Library option on it through Android Studio.
I'm getting the following errors:
Rejecting re-init on previously-failed class java.lang.Class<oracle.jdbc.pool.OracleDataSource>: java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/naming/Referenceable;
Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.naming.Referenceable" on path: DexPathList
W/System.err: java.sql.SQLException: Io exception: The Network Adapter could not establish the connection
P.s. I know using a server is a better approach. Doing this for a client who wants to use it in a secure private network and they don't want to host a separate server for the database connection.
I read elsewhere that I need to use Async task for connecting JDBC but I'm not sure how; consider me a beginner. All other answers I found related to this keep going off topic. I just want to know how to make JDBC work on Android, considering the risks.
Here's my MainActivity.java:
package com.absingh.apptest;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MainActivity extends AppCompatActivity {
private static final String DEFAULT_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DEFAULT_URL = "jdbc:oracle:thin:#192.168.42.49:1521:XE";
private static final String DEFAULT_USERNAME = "myusername";
private static final String DEFAULT_PASSWORD = "mypassword";
private Connection connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
TextView tv = (TextView) findViewById(R.id.hello);
try {
this.connection = createConnection();
Toast.makeText(MainActivity.this, "Connected",
Toast.LENGTH_SHORT).show();
Statement stmt=connection.createStatement();
StringBuffer stringBuffer = new StringBuffer();
ResultSet rs=stmt.executeQuery("select * from testtable");
while(rs.next()) {
stringBuffer.append( rs.getString(1)+"\n");
}
tv.setText(stringBuffer.toString());
connection.close();
}
catch (Exception e) {
Toast.makeText(MainActivity.this, ""+e,
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
public static Connection createConnection() throws ClassNotFoundException, SQLException {
return createConnection(DEFAULT_DRIVER, DEFAULT_URL, DEFAULT_USERNAME, DEFAULT_PASSWORD);
}
}
Nevermind, I figured it out.
The code in the question works fine if you add this above the application tag in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
I'll leave the question be, in case someone else gets the same problem.
Related
CODE:
package assessmentForSale;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;
public class Calculator {
public static AndroidDriver driver;
public static void main(String[] args) {
try {
OpenCalculator();
} catch (Exception exp) {
System.out.println(exp.getCause());
System.out.println(exp.getMessage());
exp.printStackTrace();
}
}
public static void OpenCalculator() throws Exception {
DesiredCapabilities cap = new DesiredCapabilities();
//device capabilities
cap.setCapability("deviceName","Redmi");
cap.setCapability("udid","8727c8a1");
cap.setCapability("platformName","Android");
cap.setCapability("platformVersion","9.0.0");
//App capabilities
cap.setCapability("AppPackage","com.miui.calculator");
cap.setCapability("AppActivity","com.miui.calculator.cal.CalculatorActivity");
URL url = new URL("http://0.0.0.0:4723/wd/hub");
driver = new AndroidDriver(url,cap);
System.out.println("Application has started...");
}
}
Error: Could not find or load main class assessmentForSale.Calculator
Caused by: java.lang.ClassNotFoundException: assessmentForSale.Calculator
i've looked into many resources and they assumed that this happens because the white spaces so i 've removed all white spaces from the code and the naming of the class might be wrong but i think mine is fine.
Looks like you copied this example and package assessmentForSale doesn't exist
Please look at this topic
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I’m new to Android, in order to prepare for my last school exam, I was asked to put an Android application solution using an external database on phpmyadmin ( wampserver).
My connection is done in the MainActivity file, using OkHttp3 and overriding AsyncTask with a request on an external php file for the authentification.
After a few days of work the connection still doesn’t work and my tests are coming soon, every launch of the android application is in debug mode and here are my error logs when i'm trying to connect :
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.brobert.biorelai, PID: 6002
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:354)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String okhttp3.Response.toString()' on a null object reference
at com.example.brobert.biorelai.MainActivity$BackTaskAuthentification.doInBackground(MainActivity.java:76)
at com.example.brobert.biorelai.MainActivity$BackTaskAuthentification.doInBackground(MainActivity.java:46)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
I/Process: Sending signal. PID: 6002 SIG: 9
Disconnected from the target VM, address: 'localhost:8600', transport:
'socket'
I already tried to add the internet permission via the AndroidManifest.xml :
<uses-permission android:name="android.permission.INTERNET"/>
To add the okhttp3 dependencies and put the proxy option on auto-detect.
MoreOver with the log function i verified that my EditText was working and my variable request too.
I think the error is on the line 70-71 of my MainActivity file :
response = client.newCall(request).execute();
responseStr = response.body().toString();
My MainActivity File code :
package com.example.brobert.biorelai;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View.OnClickListener;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import okhttp3.*;
public class MainActivity extends AppCompatActivity {
String responseStr;
OkHttpClient client = new OkHttpClient();
String textLogin1;
String mdp1;
Response response;
RequestBody formBody;
Request request;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button buttonValiderAuthentification = (Button)
findViewById(R.id.button2);
buttonValiderAuthentification.setOnClickListener(new
View.OnClickListener() {
#Override
public void onClick(View v){
new BackTaskAuthentification().execute();
}
});
}
private class BackTaskAuthentification extends AsyncTask<Void, Void,
Void> {
#Override
protected void onPreExecute() {
final EditText textLogin = findViewById(R.id.login1);
final EditText textMdp = findViewById(R.id.mdp1);
textLogin1 = textLogin.getText().toString();
mdp1 = textMdp.getText().toString();
}
#Override
protected Void doInBackground(Void... params){
try {
formBody = new FormBody.Builder()
.add("login", textLogin1)
.add("mdp", mdp1)
.build();
request = new Request.Builder()
.url("http://127.0.0.1/bio- relais/controleurMobil/json.php")
.post(formBody)
.build();
response = client.newCall(request).execute();
responseStr = response.body().toString();
} catch (Exception e) {
Log.d("test", textLogin1);
Log.d("test1", mdp1);
Log.d("test3", request.toString());
Log.d("test2", response.toString());
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (responseStr.compareTo("false") != 0){
try {
JSONObject membre = new JSONObject(responseStr);
String nom = membre.getString("nomM");
Intent intent = new Intent(MainActivity.this,
MainProducteurActivity.class);
intent.putExtra("membre", membre.toString());
startActivity(intent);}
catch(JSONException e){
Toast.makeText(MainActivity.this, "Erreur de connexion !",
Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(MainActivity.this, "Login ou mot de
passe non valide !",
Toast.LENGTH_SHORT).show();
}
}
}
}
A request is made on a local url http:///127.0.0.1/bio-relais/controleurMobil/json.php containing the code :
require_once '. /lib/autoloadMobil.php';
print(json_encode(MembreDAO::authentication($_POST['login'],
$_POST['mdp'])));
to pass the login and mdp of my Text edit in my method of the class MembreDao "authentification" containing the code :
public static function authentification($login, $mdp){
try{
$sql="select login, nomM ,prenomM
from MEMBRE
where login = :login
and mdp = :mdp ";
$requetePrepa = DBConnex::getInstance()->prepare($sql);
$mdp = md5($mdp);
$requetePrepa->bindParam("login", $login);
$requetePrepa->bindParam("mdp", $mdp);
$requetePrepa->execute();
$reponse = $requetePrepa->fetch(PDO::FETCH_ASSOC);
}catch(Exception $e){
$reponse = "";
}
return $reponse;
}
The expected result is a working authentification allowing the user present in the database to access to the interface of the MainProducteurActivity.
Thank you very much in advance for your help.
I finally found the problem, i was trying to connect to my localhost personal computer url on the avd with :
.url("http://127.0.0.1/bio- relais/controleurMobil/json.php")
But for the avd the localhost url of my json.php file is :
.url("http://10.0.2.2/bio-relais/controleurMobil/json.php")
( Localhost for avd = 10.0.2.2 ) .
I'm new to Android Studio and I hope you don't consider my question silly.I am trying to write a small program in the terminal of the android studio.When I try to run the same program in my terminal(not android studio) it's working fine.I added the MySQL-connector.jar file in android studio lib by going through this mysql JDBC driver to the android studio.But it didn't work.Please help me.Thanks in advance.
//MySQConnectionExample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class MySQLConnectionExample {
public static void main(String[] args) {
Connection conn1 = null;
String result = " ";
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
if (conn1 != null) {
System.out.println("Connected to the database test1");
}
String sql = " select address from pharmacy";
PreparedStatement prest = conn1.prepareStatement(sql);
ResultSet rs = prest.executeQuery();
while(rs.next()) {
result = rs.getString(1);
System.out.println(result);
}
} catch (SQLException ex) {
System.out.println("An error occurred. Maybe user/password is invalid");
ex.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//Error after execution
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at MySQLConnectionExample.main(MySQLConnectionExample.java:16)
When I remove "Class.forName("com.mysql.jdbc.Driver")" from the program this is the error i get
An error occurred. Maybe user/password is invalid
java.sql.SQLException: No suitable driver found for
jdbc:mysql://127.0.0.1:3306/demo
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at MySQLConnectionExample.main(MySQLConnectionExample.java:22)
You can't connect directly to databases from android devices. Build APIs that connects to your database. then connect your Android Application to these APIs.
Check this answer for a the same question https://stackoverflow.com/a/12233178/4442067
I assume you're trying to directly connect to a MySQL database from your Android device. But first, you have a ClassNotFound exception, which means you haven't imported the library.
And when you get the driver to work, there's more problem in this part:
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
By specifying 127.0.0.1 on your Android device, you're trying to connect to a MySQL server on your device. Now I don't know if you can install MySQL on Android, but you may want to install a MySQL server on your computer. This goes without saying that you must use the IP of that computer and have the MySQL port (3306) open on your computer.
So, what you may want to see is something like
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://192.168.1.10:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
This assumes your MySQL server is installed and configured on your computer with IP address 192.168.1.10
Good luck.
EDIT: I can't really recommend this approach for a production application though, because I'm afraid what a hacker who can decompile your code can do with it.
I'm a complete beginner in android programming and am trying to make an app which requires access to the database on local host using the android studio, using the IP address of the server, I've watched many tutorial videos but still am not sure where to pass the IP address of the server.
The server uses MySQL, I've tried using JDBC but still unable to achieve the result.
Here is my code, any help would be appreciated.
`package com.example.vishal.connectiontest;
import java.sql.*;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import static android.R.attr.name;
import static com.example.vishal.connectiontest.DemoClass.main;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button B1 = (Button)findViewById(R.id.button);
final TextView e1 = (TextView) findViewById(R.id.HelloWorld);
B1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
String result = main();
e1.setText(result.toString());
}
catch(java.lang.Exception e){
System.out.println("Exception");
}
}
});
}
}
class DemoClass
{
public static String main()throws Exception
{
String url = "jdbc:mysql://125.10.10.214/demo" ;
String uname = "root";
String pass = "";
String ip = "";
String query = "Select UserName from user_info where Id = '90000515'";
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, uname,pass);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(query);
rs.next();
String name = rs.getString("UserName");
return (name);
}
}`
Easiest way of integrating Database to your Android Application is using Firebase.
It's really easy to use and other than Database, it has File Storage Services, Cloud Messaging, Analytics and many more.
I would recommend use of firebase database.
Here have a look at it's Documentation:
https://firebase.google.com/docs/database/
Here is all of my code. I am trying to connect to my SQL server. These contents in sentences are actually exist. Real username and passwords. But I am getting Null on error catch (not connected). Please let me know where the error could be.
And I also added Internet permission in manifest.
I came across from this article - link
package com.eample.databasetester;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class MainActivity extends Activity {
TextView txv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txv1=(TextView)findViewById(R.id.text_view);
query2();
}
public void query2()
{
txv1.setText("connected");
Log.i("Android"," MySQL Connect Example.");
Connection conn = null;
try {
String driver = "net.sourceforge.jtds.jdbc.Driver";
Class.forName(driver).newInstance();
String connString = "jdbc:jtds:sqlserver://50.62.209.49:3306/test;encrypt=fasle;user=XXXX;password=YYYY;instance=SQLEXPRESS;";
String username = "XXXX";
String password = "YYYY";
conn = DriverManager.getConnection(connString,username,password);
Log.w("Connection","open");
Statement stmt = conn.createStatement();
ResultSet reset = stmt.executeQuery("select * from test");
while(reset.next()){
txv1.setText("Data:"+reset.getString(3));
}
conn.close();
} catch (Exception e)
{
txv1.setText("Error connection" + e.getMessage());
}
}
}
THis is a really bad idea. You should not connect to a database over the network from a phone. First off, it requires your DB to be publically addressable which is a security risk. Secondly, it means your password for the db is on the clients, and you don't physically control them. Your app will be reverse engineered, they'll get your password, and then your data is fucked. You should always abstract access to the database from any hardware you don't control by use of a webservice. Then the password never leaves your machines and the damage an attacker can do is limited.
Third, this code wont work anyway, you cant do network IO on the UI thread. That's likely why conn returned null. But take this as a sign of the universe telling you to fix things the right way rather than just changing threads.