本人目前在实习阶段,学的是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。

更多相关文章

  1. Android系统配置数据库注释(settings.db)
  2. Android(安卓)给 app默认权限(不弹窗申请权限)
  3. android获取经纬度和地方名称
  4. Android(安卓)中数据库查询方法 query() 中的 select
  5. android学习轨迹之二:Android权限标签uses-permission的书写位置
  6. [置顶] android orm映射框架(类似hibernate)基本使用
  7. Android:getWritableDatabase/getReadableDatabase无法调用onCre
  8. Android(安卓)用sp存储登录状态以及退出登录
  9. android 仿写 screen lock

随机推荐

  1. Android OpenGL ES2.0编程教程系列之总览
  2. 解析Android重要包功能描述
  3. Android 获得sdcard大小与内存大小工具类
  4. Android时间倒计时的简单实线
  5. android的ANR原理剖析及图解(基于android
  6. Android studio引用包冲突
  7. Android程序安装和卸载
  8. 关于Android的TimePicker和DatePicker一
  9. android之WebView的使用
  10. Android 实现开机自启动 Service