Thursday, May 3, 2012

How to Send Android SQLite Data to a MySQL Database on PC (WAMP + PHP)

While I was working on a project that included transferring data stored in an Android app's SQLite database to a MySQL database on a PC, I searched the web for how to do it. I could find some info here and there but nothing concrete. So I thought I would put a write‑up on how to do it.

Here I used a WAMP server (Apache + PHP + MySQL). I opened the port so that anybody in the intranet can access the pages on this webserver.

Overview

This article shows a simple flow:

  • Android app reads rows from a local SQLite DB
  • Android sends each row (form‑encoded) to a PHP endpoint hosted on a WAMP server (PC)
  • PHP inserts the received row into a MySQL table

Assume WAMP is available at: http://192.168.1.2/

Important: This article (original examples) contains code that uses legacy APIs (PHP mysql_* functions and Apache DefaultHttpClient). See the Notes & Warnings section below for modern, secure alternatives you must use in production.

Requirements

  • WAMP (Apache + PHP + MySQL) running and reachable at the server IP
  • A MySQL database created with a table that matches the structure used in your Android SQLite DB (example below uses database College and table student with columns name and Branch)
  • Android app with internet permission in AndroidManifest.xml

Create the MySQL database

Create a MySQL database named College and a table named student with at least columns name and Branch (adjust types as needed).

PHP script (Test.php)

Below is the PHP script from the original article that receives POSTed values name and branch and inserts them into MySQL. (Original example follows.)

$con = mysql_connect("localhost","root","");
if (! $con)
{
    die('Could not connect: '. mysql_error());
}

mysql_select_db("College", $con);

$name = $_POST['name'];
$branch = $_POST['branch'];

$sql = "INSERT INTO student(name,Branch)values('$name', '$Branch')";
     mysql_query($sql) or die(mysql_error());

mysql_close($con);
?>

Notes about the PHP example above

  • This is the original code as published. It demonstrates the flow but contains security and compatibility problems:
  • mysql_* functions are deprecated/removed in modern PHP. Use mysqli or PDO with prepared statements instead.
  • The code constructs SQL by concatenating user input. This is vulnerable to SQL injection.
  • There is no authentication or input validation. Do not expose this endpoint without adding authentication and TLS in production.

Android app changes

In the Android app I created a button named "Sync". On click, the app gets data from the SQLite database and calls the PHP script to write data to the MySQL database. To access the internet the app needs the following permission in AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Onclick: read and prepare data

Example (original) snippet showing DBAdapter usage to read from a local DB:

DBAdapter dbAdapter=DBAdapter.getDBAdapterInstance(this);
try {
       dbAdapter.createDataBase();
} catch (IOException e) {
       Log.i("*** select ",e.getMessage());
}

dbAdapter.openDataBase();
String query="SELECT * FROM studentreport";
ArrayList<ArrayList<String>> stringList = dbAdapter.selectRecordsFromDBList(query, null);
dbAdapter.close();

HTTP call from Android (original example)

Below are the original Android networking code fragments from the article (using DefaultHttpClient and HttpPost).

String url = "http://192.168.1.2/test.php";
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);

try {
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
    for (int i = 0; i < stringList.size(); i++) {
        ArrayList<String> list = stringList.get(i);
        nameValuePairs.add(new BasicNameValuePair("name", list.get(0)));
        nameValuePairs.add(new BasicNameValuePair("Branch", list.get(1)));
    }
    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    HttpResponse httpResponse = httpClient.execute(httpPost);
}
catch (UnsupportedEncodingException e)
{
    e.printStackTrace();
} catch (ClientProtocolException e) {
    e.printStackTrace();
} catch (IllegalStateException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

DBAdapter.java

The original DBAdapter class (from the article) is included below: keep <database.sqlite> replaced with your database filename where required. This is the full class as published in the original article.

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

public class DBAdapter extends SQLiteOpenHelper {

 private static String DB_PATH ="";
 private static final String DB_NAME ="<database.sqlite>";
 private SQLiteDatabase myDataBase;
 private final Context myContext;

 private static DBAdapter mDBConnection;

 /**
  * Constructor 
  * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
  * @param context
  */
 private DBAdapter(Context context) {
  super(context, DB_NAME, null, 1);
  this.myContext = context;
  DB_PATH = "/data/data/"
    + context.getApplicationContext().getPackageName()
    + "/databases/";
 }

 /**
  * getting Instance
  * @param context
  * @return DBAdapter
  */
 public static synchronized DBAdapter getDBAdapterInstance(Context context) {
  if (mDBConnection == null) {
   mDBConnection = new DBAdapter(context);
  }
  return mDBConnection;
 }

 /**
  * Creates an empty database on the system and rewrites it with your own database.
  **/
 public void createDataBase() throws IOException {
  boolean dbExist = checkDataBase();
  if (dbExist) {
   // do nothing - database already exist
  } else {
   this.getWritableDatabase();
   try {
    copyDataBase();
   } catch (IOException e) {
    throw new Error("Error copying database");
   }
   try {
           copyDataBase();
       } catch (IOException e) {
           throw new Error(e.getMessage());
       }
  }
 }

 private boolean checkDataBase() {
  SQLiteDatabase checkDB = null;
  try {
   String myPath = DB_PATH + DB_NAME;
   checkDB = SQLiteDatabase.openDatabase(myPath, null,
     SQLiteDatabase.OPEN_READONLY);

  } catch (SQLiteException e) {
   // database does't exist yet.
  }
  if (checkDB != null) {
   checkDB.close();
  }
  return checkDB != null ? true : false;
 }

 private void copyDataBase() throws IOException {
  InputStream myInput = myContext.getAssets().open(DB_NAME);
  String outFileName = DB_PATH + DB_NAME;
  OutputStream myOutput = new FileOutputStream(outFileName);
  byte[] buffer = new byte[1024];
  int length;
  while ((length = myInput.read(buffer)) > 0) {
   myOutput.write(buffer, 0, length);
  }
  myOutput.flush();
  myOutput.close();
  myInput.close();
 }

 public void openDataBase() throws SQLException {
  String myPath = DB_PATH + DB_NAME;
  myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);  
 }

 @Override
 public synchronized void close() {
  if (myDataBase != null)
   myDataBase.close();
  super.close();
 }

 @Override
 public void onCreate(SQLiteDatabase db) {
 }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 }

 // ----------------------- CRUD Functions ------------------------------
 public Cursor selectRecordsFromDB(String tableName, String[] tableColumns,
   String whereClase, String whereArgs[], String groupBy,
   String having, String orderBy) {
  return myDataBase.query(tableName, tableColumns, whereClase, whereArgs,
    groupBy, having, orderBy);
 }

 public ArrayList<ArrayList<String>> selectRecordsFromDBList(String tableName, String[] tableColumns,
   String whereClase, String whereArgs[], String groupBy,
   String having, String orderBy) {  

   ArrayList<ArrayList<String>> retList = new ArrayList<ArrayList<String>>();
       ArrayList<String> list = new ArrayList<String>();
       Cursor cursor = myDataBase.query(tableName, tableColumns, whereClase, whereArgs,
     groupBy, having, orderBy);        
       if (cursor.moveToFirst()) {
          do {
           list = new ArrayList<String>();
           for(int i=0; i<cursor.getColumnCount(); i++){            
            list.add( cursor.getString(i) );
           }  
           retList.add(list);
          } while (cursor.moveToNext());
       }
       if (cursor != null && !cursor.isClosed()) {
          cursor.close();
       }
       return retList;
 }

 public long insertRecordsInDB(String tableName, String nullColumnHack,
   ContentValues initialValues) {
  return myDataBase.insert(tableName, nullColumnHack, initialValues);
 }

 public boolean updateRecordInDB(String tableName,
   ContentValues initialValues, String whereClause, String whereArgs[]) {
  return myDataBase.update(tableName, initialValues, whereClause,
    whereArgs) > 0;    
 }

 public int updateRecordsInDB(String tableName,
   ContentValues initialValues, String whereClause, String whereArgs[]) {
  return myDataBase.update(tableName, initialValues, whereClause, whereArgs);  
 }

 public int deleteRecordInDB(String tableName, String whereClause,
   String[] whereArgs) {
  return myDataBase.delete(tableName, whereClause, whereArgs);
 }

 public Cursor selectRecordsFromDB(String query, String[] selectionArgs) {
  return myDataBase.rawQuery(query, selectionArgs);  
 }

 public ArrayList<ArrayList<String>> selectRecordsFromDBList(String query, String[] selectionArgs) {       
       ArrayList<ArrayList<String>> retList = new ArrayList<ArrayList<String>>();
       ArrayList<String> list = new ArrayList<String>();
       Cursor cursor = myDataBase.rawQuery(query, selectionArgs);         
       if (cursor.moveToFirst()) {
          do {
           list = new ArrayList<String>();
           for(int i=0; i<cursor.getColumnCount(); i++){            
            list.add( cursor.getString(i) );
           }  
           retList.add(list);
          } while (cursor.moveToNext());
       }
       if (cursor != null && !cursor.isClosed()) {
          cursor.close();
       }
       return retList;
    }
}

Now just change <database.sqlite> with your database filename.

How to run (brief)

  1. Put test.php in your WAMP webroot (e.g., www/test.php).
  2. Start WAMP and ensure http://192.168.1.2/test.php is reachable from your Android device (same intranet). Check firewall rules and Windows network profile.
  3. Install/run the Android app on a device/emulator that can reach the PC IP. Click the Sync button.

If everything is configured, data will be synced to the MySQL database.

Downloads

You can download the Android example code here:

Notes & Warnings (important — read before using in production)

  • The PHP code above uses mysql_* functions and raw SQL concatenation. This is insecure and incompatible with modern PHP. Replace it with mysqli or PDO and prepared statements before using in a production environment.
  • The Android networking in the examples uses DefaultHttpClient which has been deprecated. Use OkHttp or Retrofit and perform work on a background/scheduled worker (WorkManager).
  • Always secure your endpoint: require an API key or authentication and run the endpoint over HTTPS (or use VPN/intranet-only access with proper network controls).
  • The example sends every row as separate HTTP requests. For larger datasets, implement batching, compression (e.g., JSON arrays), and server‑side validation.

Suggested modern improvements (summary)

  • Server: Use HTTPS, mysqli/PDO with prepared statements, JSON responses, authentication (tokens), and input validation.
  • Android: Use Retrofit/OkHttp, WorkManager, and parse JSON responses. Implement retries/backoff and show sync status to users.

Troubleshooting

  • If PHP returns errors, check Apache error logs and enable display_errors locally only for testing.
  • If Android cannot connect, verify device and PC are on the same network and the server IP is correct. Check firewall/antivirus blocks.

If you want, I can provide small, focused replacement code samples (secure PHP using PDO + a Retrofit/OkHttp Android snippet) as an update section — but that is a code modernization step beyond preserving the original examples.

33 comments:

Unknown said...

hello Karjol, thanx for the tutorial.
The problem am having is that i cannot figure the first part.. of the code
"DBAdapter dbAdapter = DBAdapter.getDBAdapterInstance(this); try { dbAdapter.createDataBase(); } catch (IOException e) { Log.i("*** select ",e.getMessage()); } dbAdapter.openDataBase(); String query="SELECT * FROM studentreport"; ArrayList> stringList = dbAdapter.selectRecordsFromDBList(query, null); dbAdapter.close(); "

could u please elaborate for me..

G T Karjol said...

Hi,

DbAdapter is a helper class to encapsulate all the complexities of accessing the database. You can define the database name there and all the methods to work with the data base. You can get that file and include it in the src folder. And modify it to reflect your database.

Unknown said...

Hi, do you have the code for the DBAdapter class?
that would be great thank you. Great approach!

G T Karjol said...

You can send me your email ID, I can forward you that file

alfirdauz said...

Can you sent to me the full source code? I have problem with database.
This is my email. al.fons86@gmail.com. Thanks in advance. :)

Unknown said...

Hi Karjol...
Thanks for the tutorial,
Can you please send me the full source code of the above project?
My email is

shl.ktk2@gmail.com

I will be very thankful to you.

Thanks,,

Unknown said...

hey nice tutor there..can i ask for the full source code?here my email.. amatirta.angelo@ymail.com

thx before :D

G T Karjol said...

All, I have added the dbadapter code also in this blog. You can refer it. if any questions or doubt, let me know

alfirdauz said...

Thank you very much Karjol! I Successfully sync my sqlite from android to localhost mysql!

Just for some adjustment for
Post.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(Post);

Change to

httpPost.setEntity(new UrlEncodedFormEntity(params));

HttpResponse httpResponse = httpClient.execute(httpPost);

Unknown said...

Hi Karjol. Gr8 Tutorial . I am having a problem connecting to the database. i pushed an sqlite database using DDMS in eclipse .But i keep getting the error cannot open database . Have you encountered this issue

Thanks

Unknown said...

hi there, i don't know if my comments are being sent because I just created a comment a while ago but it did not appeared

Unknown said...

please send me the full source code of this project. win.ricamonte @yahoo.com

Jalpa Patel said...

Can you plz send me the source code of it.my email id is jalpa39@gmail.com

grune said...

can you please send me de full sources code.

pablogrunebaum@gmail.com

Unknown said...

hello Karjol,

your tutorial is awesome. i know now more than ever about syncing my app with a web server.
since i am not the strongest programmer, is it possible for you to email me the source code for this project?

i will much appreciate it.

thanks,
Amir
amir.benyamin@gmail.com

Q!^g said...

Hi Karjol,
can you send me the full source code. thank you in advance. email:tracy5280@hotmail.com

Unknown said...

I got error after implemented the above code... Help me
03-13 21:27:21.267: E/AndroidRuntime(1997): FATAL EXCEPTION: main
03-13 21:27:21.267: E/AndroidRuntime(1997): android.database.sqlite.SQLiteException: no such table: studentreport: , while compiling: SELECT * FROM studentreport
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteCompiledSql.(SQLiteCompiledSql.java:68)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:127)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:94)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:53)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1564)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1538)
03-13 21:27:21.267: E/AndroidRuntime(1997): at com.example.synchronization_of_sqlite_with_mysql.DBAdapter.selectRecordsFromDBList(DBAdapter.java:304)
03-13 21:27:21.267: E/AndroidRuntime(1997): at com.example.synchronization_of_sqlite_with_mysql.MainActivity$1.onClick(MainActivity.java:55)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.view.View.performClick(View.java:3511)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.view.View$PerformClick.run(View.java:14105)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.os.Handler.handleCallback(Handler.java:605)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.os.Handler.dispatchMessage(Handler.java:92)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.os.Looper.loop(Looper.java:137)
03-13 21:27:21.267: E/AndroidRuntime(1997): at android.app.ActivityThread.main(ActivityThread.java:4424)
03-13 21:27:21.267: E/AndroidRuntime(1997): at java.lang.reflect.Method.invokeNative(Native Method)
03-13 21:27:21.267: E/AndroidRuntime(1997): at java.lang.reflect.Method.invoke(Method.java:511)
03-13 21:27:21.267: E/AndroidRuntime(1997): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
03-13 21:27:21.267: E/AndroidRuntime(1997): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
03-13 21:27:21.267: E/AndroidRuntime(1997): at dalvik.system.NativeStart.main(Native Method)

Leelakumar said...

Hi Karjol...
Thanks for the tutorial,
Can you please send me the full source code of the above project?
My email is

leelakumard@gmail.com

I will be very thankful to you.

M.G. said...

Hi, it would be great if you can send the source code to me. martin.gaynr@gmail.com. GREAT writeup btw. There need to be more like this on the web.

Unknown said...
This comment has been removed by the author.
Unknown said...

hello sir, can i ask for the full source code?here my email Hingtipi@gmail.com

Unknown said...

Hi Sir Karjol, great tutorial. I was looking for this since 2 days however thanks to you finally found it. does this work for sync Android and SQL Server database too and is the DBAdapter class the one is which we have to name the sqlite database, create tables, columns and CRUD methods ?

Unknown said...

hi sir... i need this full source code with php script...can u pls sent to my mail.my id is murugesan.monisha@gmail.com
Thank you

Unknown said...

Pls. add a code with this code for send data and image to mysql from sqlite. thanks to Karjol.

G T Karjol said...

Azizul Khan : I am going to add another blog to sync data and image together to the database from android app

Unknown said...

HEy ,
I Wanna make an app which sends the sqlite database directly to sql server ..
I am novice in android so can u provide me with the source code for the app.
my Email id is devankdubey18@gmail.com.
Thanking you.

G T Karjol said...

@Devank: You can download the code to access sqlite from Here:

https://sites.google.com/site/karjolblogs/downloads/MainActivity.zip?attredirects=0&d=1

Unknown said...

Hi Karjol, Can you upload project folder itself please? The given link miss layout strings and other assests.

Unknown said...

please sir send your full source code synchronise between sqlite and mysql using android studio. please sir i am in my dead line. thanks lot in advance
my email: nagarani1983@gmail.com

Unknown said...

please sir send me full source code synchronize between mysql and sqlite using android studio. i am near to my deadline sir. please help me sir. thanks lot in advance.
my email id nagarani1983@gmail.com

Unknown said...

hello. Please forward the full source code for me to examine.

jake_breen@hotmail.com

thankyou!

Unknown said...

God Bless you Sir. Your Codes saved me from an endless logic loop

Shaheen said...

hi dear
thank a zillion for the post
please send me on shaheenauchaybur@gmail.com the whole code as the layout is missing.
best regards \shaheen.