Android连接mysql数据库实现登录小案例,填坑之路
本人目前在实习阶段,学的是java,但是公司让学Android,做一些小界面。这个案例是初学Android,来测试一下连接mysql数据库。虽然看着简单,但是在实现的路上还是踩了不少的坑,因此简单记录一下。
在网上找了一个类似的小案例,原文是这个,尊重一下作者。
https://blog.csdn.net/qq_37141773/article/details/84255926
一、实现效果
二、实现步骤
1、新建一个工程
这个案例是在模拟器上实现的。
2、开启网络权限!!!
这一步非常重要,在这个地方踩了大坑,希望后面的读者不要踩了。
找到目录结构下的AndroidManifest.xml文件,添加网络权限。
<uses-permission android:name="android.permission.INTERNET"/>
还有一个很重要的坑!!!!
就是一开始你没有给程序添加网络权限,后来发现后给程序添加权限,但是由于程序已经安装了,他的权限是默认一开始的。所以后面你运行程序,就会一直报错,然后你就一直连不上数据库。
java.net.SocketException: socket failed: EPERM (Operation not permitted)
解决的办法就是卸载你模拟器上的程序,重新运行,OK就是这么简单。。我弄了半天,佛了。
完整xml文件
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.htn.androidstudy"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".login.infoActivity">activity> <activity android:name=".login.LoginActivity" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> intent-filter> activity> application>manifest>
3、导入jar包
实现直连MySql数据库需要导入mysql-connector-java-5.1.30-binjar包(百度网盘提取码为:ctxa)。(借个楼,要是不能用了就自己去找叭)
将jar下载后,在新建项目的app/src/main 目录下 创建libs文件夹,将jar包复制到该文件夹下,然后右键选择 Add As Library 进行导入即可。
等待gradle同步成功后,打开build.gradle文件依赖内容如下说明导入成功:
implementation files('src/main/libs/mysql-connector-java-5.1.30-bin.jar')
4、登录界面
activity_login.xml文件
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="15dp" > <EditText android:id="@+id/username" android:layout_width="match_parent" android:layout_height="50dp" android:hint="用户名" android:background="@drawable/bg_username" android:textColor="#000000" android:textSize="16sp" android:paddingLeft="10dp" android:paddingRight="10dp" android:drawablePadding="5dp" android:drawableLeft="@mipmap/username" android:layout_marginTop="50dp" /> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="50dp" android:layout_below="@id/username" android:layout_marginTop="15dp" android:hint="密码" android:background="@drawable/bg_username" android:inputType="textPassword" android:textColor="#000000" android:textSize="16sp" android:paddingLeft="10dp" android:paddingRight="10dp" android:drawablePadding="5dp" android:drawableLeft="@mipmap/password"/> <Button android:id="@+id/btn_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/password" android:layout_marginTop="10dp" android:text="登录" /> <Button android:id="@+id/btn_cancle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/btn_login" android:layout_marginTop="10dp" android:text="取消" />RelativeLayout>
5、展示信息界面
activity_info.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_info" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/info_username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Text" android:textSize="30sp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/info_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Text" android:textSize="30sp" android:layout_marginTop="36dp" android:layout_below="@+id/info_username" android:layout_alignLeft="@+id/info_username" android:layout_alignStart="@+id/info_username" />RelativeLayout>
6、新建User类
package com.htn.androidstudy.login;import java.io.Serializable;public class User implements Serializable { private int user_id; private String username; private String password; public User() { } public User(int user_id, String username, String password) { this.user_id = user_id; this.username = username; this.password = password; } public void setUser_id(int user_id) { this.user_id = user_id; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public int getUser_id() { return user_id; } public String getUsername() { return username; } public String getPassword() { return password; } @Override public String toString() { return "User{" + "user_id=" + user_id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; }}
7、LoginActivity类
这部分代码,就是监听登录按钮,然后连接数据库。
package com.htn.androidstudy.login;import androidx.appcompat.app.AppCompatActivity;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import com.htn.androidstudy.R;import com.htn.androidstudy.utils.DBUtils;import java.util.Map;public class LoginActivity extends AppCompatActivity implements View.OnClickListener { private Button btn_login,btn_cancle; private EditText usr,pwd; private String username,password; private User u; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); //找到按钮 btn_login = findViewById(R.id.btn_login); btn_cancle = findViewById(R.id.btn_cancle); //找到editText的值 usr = findViewById(R.id.username); pwd = findViewById(R.id.password); btn_login.setOnClickListener(this); btn_cancle.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.btn_login://这个是登录按钮 username = usr.getText().toString().trim(); password = pwd.getText().toString().trim(); u = new User(); u.setUsername(username); u.setPassword(password); checkLogin(u); break; case R.id.btn_cancle://这个是取消按钮 break; } } class DBThread implements Runnable { private User user; private Context context; public void setUser(User user) { this.user = user; } public void setContext(Context context) { this.context = context; } @Override public void run() { Map<String,String> result= DBUtils.Login(user); if (result != null && result.size() > 0) { Intent intent=new Intent(LoginActivity.this,infoActivity.class); intent.putExtra("user",u); context.startActivity(intent); } } } private void checkLogin(User u) { DBThread dt = new DBThread(); dt.setUser(u); dt.setContext(this); Thread thread = new Thread(dt); thread.start(); }}
8、DBUtils类
这个是连接数据库的工具类,然后里面有个登录login的方法。
这里又有一个坑,MYSQL数据库连接Url,这个url里面的ip问题。
反正在这里坑了好久,
情况一: 默认ip
有个说法是,Android的默认ip是:10.0.2.2,当时改了之也能够连上数据库。
情况二: 用本机IPv4地址,不用localhost
改了自己本机的ip,添加了网络权限。报错。。具体错误好像是连接被拒绝什么的解决方法是:在mysql数据库中执行语句:允许用户使用123456密码从任何主机连接到mysql服务器grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
package com.htn.androidstudy.utils;import android.util.Log;import com.htn.androidstudy.login.User;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;import java.util.HashMap;import java.util.Map;/** * 数据库工具类:连接数据库用、获取数据库数据用 * 相关操作数据库的方法均可写在该类 */public class DBUtils { private static String driver = "com.mysql.jdbc.Driver";//MySQL 驱动 private static String url = "jdbc:mysql://192.168.3.3/test";//MYSQL数据库连接Url private static String user = "root";//用户名 private static String password = "123456";//密码 private static Connection getConn(){ Connection connection = null; try{ Class.forName(driver);// 动态加载类 // url的ip写成本机地址,不能写成localhost,同时手机和电脑连接的网络必须是同一个 // 尝试建立到给定数据库URL的连接 connection = DriverManager.getConnection(url,user,password); }catch (Exception e){ e.printStackTrace(); } return connection; } //登录 public static Map<String, String> Login(User user) { HashMap<String, String> map = new HashMap<>(); Connection conn = getConn(); try { Statement st = conn.createStatement(); String sql= "select * from user where username ='" + user.getUsername() + "' and password ='" + user.getPassword() + "'"; ResultSet res = st.executeQuery(sql); if (res == null) { return null; } else { int cnt = res.getMetaData().getColumnCount(); res.next(); for (int i = 1; i <= cnt; ++i) { String field = res.getMetaData().getColumnName(i); map.put(field, res.getString(field)); } conn.close(); st.close(); res.close(); return map; } } catch (Exception e) { e.printStackTrace(); return null; } }}
9、展示信息infoActivity类
package com.htn.androidstudy.login;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.widget.TextView;import com.htn.androidstudy.R;public class infoActivity extends AppCompatActivity { TextView tv1,tv2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_info); tv1=findViewById(R.id.info_username); tv2=findViewById(R.id.info_password); Intent getData=getIntent(); User user = (User)getData.getSerializableExtra("user"); tv1.setText("用户名为:" +user.getUsername()); tv2.setText("密码为:"+user.getPassword()); }}
三、总结
初学Android,公司也没人教,出了问题全靠自己百度。个中滋味,甚是酸爽。发现问题,解决问题。实习的两个月里,发现了一个事情就是遇到了问题并不可怕,给点时间磨一下,总会解决的(个人观点哈)。一名正在奋斗路上的小han。
更多相关文章
- Android系统配置数据库注释(settings.db)
- Android(安卓)给 app默认权限(不弹窗申请权限)
- android获取经纬度和地方名称
- Android(安卓)中数据库查询方法 query() 中的 select
- android学习轨迹之二:Android权限标签uses-permission的书写位置
- [置顶] android orm映射框架(类似hibernate)基本使用
- Android:getWritableDatabase/getReadableDatabase无法调用onCre
- Android(安卓)用sp存储登录状态以及退出登录
- android 仿写 screen lock