关于Android直接连MySQL获取数据的真机测试的一些坑
一、 要设置好IP地址
在Java中一般使用JDBC访问MySQL都是使用127.0.0.1或者localhost来代表本地地址,但是在Android中使用localhost代表的是手机本机IP地址,所以在访问是需要修改IP地址;
在打开CMD(win+R)输入ipconfig后回车,显示如下:
以太网适配器 SSTAP 1:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
以太网适配器 VirtualBox Host-Only Network:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::4099:6c06:65a:4884%15
IPv4 地址 . . . . . . . . . . . . : 192.168.56.1
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . :
以太网适配器 VirtualBox Host-Only Network #2:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::3c64:b170:10bf:605d%8
IPv4 地址 . . . . . . . . . . . . : 192.168.251.2
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . :
无线局域网适配器 本地连接* 1:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
无线局域网适配器 本地连接* 2:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::a89e:772:c850:8422%20
IPv4 地址 . . . . . . . . . . . . : 192.168.137.1
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . :
以太网适配器 VMware Network Adapter VMnet8:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::2d9e:45e7:a8:35e1%21
IPv4 地址 . . . . . . . . . . . . : 192.168.64.1
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . :
以太网适配器 VMware Network Adapter VMnet1:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::1e3:965e:ed9e:85a0%3
IPv4 地址 . . . . . . . . . . . . : 192.168.174.1
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . :
无线局域网适配器 WLAN:
连接特定的 DNS 后缀 . . . . . . . : lan
本地链接 IPv6 地址. . . . . . . . : fe80::ace0:8e4a:46ba:ed3c%16
IPv4 地址 . . . . . . . . . . . . : 192.168.1.129
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.1.1
1.AVD
对于AVD(即AndroidStudio自带的模拟器),可以将IP地址改为10.0.2.2(即运行的PC本地地址)或者直接改为本机地址,即上面的ipconfig查询的最后一项<无线局域网适配器 WLAN>中的IPv4地址,如上所示为192.168.1.129,代码部分如下
final String DB_URL = "jdbc:mysql://10.0.2.2:3306/meeting?useSSL=false"
final String DB_URL = "jdbc:mysql://192.168.1.129:3306/meeting?useSSL=false"
2.Genymotion
对于Genymotion模拟器,它是运行在虚拟机Oracle VM VirtualBox之上的,所以要访问本地服务器时,应该IP地址设置为ipconfig查询结果中的<以太网适配器 VirtualBox Host-Only Network #2>中的IPv4地址,如上面查询结果所示,本人例子中使用的IP地址是192.168.251.2,
final String DB_URL = "jdbc:mysql://192.168.251.2:3306/meeting?useSSL=false"
3.真机
真机测试时,相对于模拟器多了一些其他步骤,在这里先将IP地址的设置,其他步骤请在下文查找,程序要在真机测试时,需将代码中要访问的数据库的IP地址设为数据库所在主机的IP地址,即上面ipconfig查询结果中的<无线局域网适配器 WLAN>中的IPv4地址,如上面所示,此处为192.168.1.129
final String DB_URL = "jdbc:mysql://192.168.1.129:3306/meeting?useSSL=false"
关于JDBC连接MySQL的IP地址设置的介绍就先这样,接下来是访问数据库的用户设置。因为MySQL的root用户不允许远程访问,所以我们应该创建一个新用户
二、创建数据库新用户并授权允许远程访问
CMD登入MySQL(mysql -uroot -ppassword),然后执行以下步骤
//创建新用户,可以远程访问//%表示任意IP地址,也可以自己制定,password设置此新用户登录时应该输入的密码create user newuser@'%' identified by 'password';//授予新用户对指定数据库的全部表或者某张表的操作权限//DataBase替换成自己制定的数据库名字,Table替换成要访问的指定数据库的指定表//要是要设置允许访问全部数据库的全部表,则将DataBase.Table改为 *.*GRANT ALL PRIVILEGES ON DataBase.Table TO newuser@"%" IDENTIFIED BY "password";
设置后访问数据库的用户账号后,就该动手编程通过JDBC连接MySQL,来访问数据库,但是Android访问数据库需要在子线程中执行,所以在访问时应该创建新线程
三、在新线程中连接数据库获取信息(贴代码)
1.导入jar包,将下载的mysql-connector-java-XX.XX.XX-bin.jar(XX.XX.XX代表版本号)复制到工程的/app/libs或/app/src/main/libs(没有的话可以自己建一个)目录下,然后点击该jar包右键点击Add As Library.. 然后按提示再Syns一下,如果没报错就是成功添加了。
2.连接数据库,下面我提一个我在练习的时候写的代码展示一下,可以参考改成自己需要的,将‘Android’改成自己创建的用户名,将‘android’改成自己创建的用户的密码,
public class UserDataSource implements UserDataBase { String TABLE_NAME = "user"; DatabaseHelper databaseHelper ; SQLiteDatabase sqLiteDatabase; BasePresenter basePresenter; final String DB_URL = "jdbc:mysql://192.168.1.129:3306/meeting?useSSL=false";//数据库地址,10.10.2.2在虚拟机中,指本机ip;若是真机测试,则需要改为真是ip final String DB_USER="Android"; final String DB_PASSWORD="android"; public UserDataSource(Context context,BasePresenter basePresenter){ databaseHelper = new DatabaseHelper (context); this.basePresenter = basePresenter; } @Override //改为连接数据库查找信息 public void getUserData(final String nameOrPhoneOrMail, final String password){ Thread loginThread = new Thread() { @Override public void run() { try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(DB_URL,DB_USER,DB_PASSWORD); Statement stat = conn.createStatement(); //查找数据语句 String exe_query = "SELECT * FROM " + TABLE_NAME + " WHERE username = '" + nameOrPhoneOrMail + "' OR phone = '" + nameOrPhoneOrMail + "' OR mail = '" + nameOrPhoneOrMail+"'"; ResultSet resultSet = stat.executeQuery(exe_query); resultSet.last(); if (resultSet.getRow() == 1) { resultSet.first(); if (password.equals(resultSet.getString("password"))) {//密码正确// basePresenter.setResult(1); basePresenter.setResult(1); User user = new User(); user.setId(resultSet.getInt("u_id")); user.setUserName(resultSet.getString("username")); user.setPhone(resultSet.getString("phone")); user.setMail(resultSet.getString("mail")); user.setCredit(resultSet.getInt("credit")); basePresenter.setSuccessLoginUser(user);//成功登录后返回用户具体信息 } else { basePresenter.setResult(0);//密码错误 } } else {//该用户未注册 basePresenter.setResult(0); } stat.close(); conn.close(); } catch ( Exception e) { e.printStackTrace(); } } }; loginThread.start(); try { loginThread.join();//使线程顺序执行 }catch (InterruptedException e){ e.printStackTrace(); } } @Override //改为将用户信息存储到MySQL数据库 public void saveUserData(final User register){ Thread registThread = new Thread(){ @Override public void run(){ try{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(DB_URL,DB_USER,DB_PASSWORD); Statement stat = conn.createStatement(); //查询数据语句:注册之前要先查看该用户名或者 ResultSet resultSet; String query_username = "SELECT * FROM " + TABLE_NAME + " WHERE username = '" + register.getUserName() +"'" ; String query_phone = "SELECT * FROM " + TABLE_NAME + " WHERE phone = '" + register.getPhone() +"'" ; String query_mail = "SELECT * FROM " + TABLE_NAME + " WHERE mail = '" + register.getMail()+"'" ; resultSet = stat.executeQuery(query_username); resultSet.last(); if(resultSet.getRow() != 0){//查询到有同样的用户名 basePresenter.setResult(2); return; } resultSet = stat.executeQuery(query_phone); resultSet.last(); if(resultSet.getRow() != 0){//查询到有同样的手机号 basePresenter.setResult(3); return; } resultSet = stat.executeQuery(query_mail); resultSet.last(); if(resultSet.getRow() != 0){//查询到有同样的手机号 basePresenter.setResult(4); return; } //插入数据语句 String exe_insert = "INSERT INTO "+TABLE_NAME+ " VALUES(NULL,'"+register.getUserName()+"','"+register.getPhone()+"','"+register.getMail()+"','"+register.getPassword()+"',"+register.getCredit()+")"; int exe_result = stat.executeUpdate(exe_insert);//返回1:添加成功;返回其他:添加失败; if (exe_result == 1){ basePresenter.setResult(1); }else{ basePresenter.setResult(0); } stat.close(); conn.close(); }catch (Exception e){ e.printStackTrace(); } } }; registThread.start(); try { registThread.join(); }catch (InterruptedException e){ e.printStackTrace(); } }}
四、 关闭防火墙(真机测试)
本文主要是针对连接本地数据库的Android程序的真机测试,所以以下两个步骤是真机测试所必须的,如果是AVD或者Genymotion那么完成上面步骤之后就可以运行尝试了。
在进行真机测试时,应先关闭本地的防火墙(win10) 设置-->更新与安全-->Windows安全中心-->防火墙与网络保护(或者其他已知的关闭方法)
五 、连接电脑热点(真机测试)
在进行真机测试时,如果要访问本地服务,还需保证真机与本地处于同一网络,较容易的方法就是代开电脑的移动热点,然后手机连接热点既可,然后运行程序就可以在真机上愉快地访问数据库了(或者尝试其他已知方法);
因为我是新手,暂时还没接触到http+webserver(应该是这个)来访问数据,所以只能做个简单的,通过jdbc直接访问MySQL来获取数据,但是网上说这种方法是不安全的,不建议的,但是我个人认为对于新手来说,这也可以算是一个学习的过程,所以整理了一下在连接MySQL过程中看的很多教程,使之成为一篇较完整的教程,可以方便像我一样的新手。
更多相关文章
- MapMe
- Android(安卓)SDK和ADT无法更新的解决办法
- 安卓数据库sqlite增删查改—模拟用户登录与管理(2020-6-19)
- Android(安卓)ContentProvider的线程安全(一)
- android SQLite实现本地登录注册功能,SQLite简单应用(android stu
- Android数据库的操作之存储和获取
- Android应用开发———Android中的常用UI组件
- Android中使用SQLiteOpenHelper管理SD卡中的数据库
- Android常用适配器分析(如何制作简易Launcher)