最近在学Android(初学者吖),写下这个【Android学习之路】系列记录一下自己学习的过程,欢迎阅读~ ① 总体页面框架基本成型,初始界面和登录界面经过一定的美化 我用的开发工具是Android Studio,是谷歌基于IntelliJ IDEA开发的IDE,因为习惯于用IDEA写Java,所以我选择使用用Android Studio来进行安卓开发,而不是Eclipse(而且谷歌已经停止对Eclipse Android开发工具的一切支持)。 附上我用的版本的百度网盘链接: 模拟器我用的是夜神,使用效果还可以,同样附上链接: 链接:https://pan.baidu.com/s/1JOI0bWH1aOvP1gpc4-79pQ — — — — — — — — — — — — — — — — — — 功能方面我的计划是: APP启动后会进入初始的选择登录身份的界面,如下图(是我手机上的截屏): emm,这个代码的颜色有些刺眼哈哈,接下来分别是教师和学生登录页面(因为手机短信验证功能还没调试成功,所以教师页面暂时也是用户名+密码的注册和登录形式): 首先是注册/登录界面功能: 注册/登录页面的Activity中的代码如下(以学生页面 当填入的用户名或密码中有一个为空时,注册失败同时通过Toast弹出消息提示框,注册成功并登录后会弹出一个欢迎的消息提示框,如下图: 查看SQLite数据库中的相关记录(我使用的Navicat Premium 15): 这些设置在文档中都有:SMSSDK for Android,写的挺详细的,该短信验证功能的具体代码实现和调用在下一阶段会完成~ 第一阶段主要是构造好了基本的大的框架和初级的登录功能,数据库的详细的各个关系模式将在最近几天设计出来,目前只有 下一阶段会在这周更新出来,然后在本文附上链接~ (ps:因为目前代码中一些地方写的还不够好,在最终项目完成后会将项目源码上传至GitHub😊,目前发表出的代码中如有问题和需改进的地方希望大家积极指出~)
目前进度
② 注册和登录功能已经实现,密码采用MD5算法进行加密存储
③ 能成功连接SQLite数据库并进行数据的CRUD操作
④ 手机验证码登录功能进行至一半(采用的是MobTech平台)准备阶段
开发工具以及方向构思
Android Studio:链接:https://pan.baidu.com/s/1y2uXHEUl0ungSwA2eaAO7A 提取码:twmm
SDK: 链接:https://pan.baidu.com/s/1OdKp84vJnbMcm8ky-L28AQ 提取码:h5zi
提取码:odn9
构思自己要做的项目时,方向是和学校相关的,因为这样也比较贴近我的生活,更加熟悉一些,哈哈。然后本取名鬼才给该项目和APP均取名为:SchoolSystem
,哈哈,不过现在我发现这个名字在手机里显示不全,后半截直接省略号了😂
要实现的功能计划
① 分为教师和学生两种登录方式(密码采用MD5加密),登录后所能使用的功能是不同的(拿【学习】页面来说老师能出题和修改学生的分数等,学生只能查看成绩结果和分析以及做题等)
② 老师注册和登录时有一定的限制(我提前准备好可以注册的手机号,老师注册的时候比学生多出手机短信验证这一限制),然后在登录后学生需进行身份认证,认证成功后可享受全部功能,否则只有【计划】这一页面可供使用
③ 【学习】页面有学生的成绩绘制成的图表分析,以及自己的所有成绩查询(和全班的成绩),然后在该页面会实现一个可以做题的功能(教师在该页面可出题,然后学生在该页面做题)
④ 【计划】这一页面可供大家写下自己的计划(可设置为自己可见和全部人可见)
⑤ 如果能力达到的条件下,完善【论坛】页面,连接云数据库,大家可在其中发表一些内容
第一阶段
UI展示
APP的图标我采用了AS里提供的炒鸡好用的Image Asset功能进行制作,好处是基本能适应各种机型,包括图标是圆形,设计界面如下图:
选择登录身份的初始界面InitActivity
的布局采用了LinearLayout
垂直方向线性布局,页面中有ImageView
组件显示我设计的欢迎那一张图片和底部的图片,然后是“请选择您的身份”和“Copyright”的TextView
组件,下面部分我采用了RelativeLayout
相对布局,并在其中嵌套了一个相对布局用于教师选择和学生选择的位置控制,使其具有更好地适应能力,该activity_init.xml
文件源代码如下:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@mipmap/bg1" android:padding="3dp" tools:context=".InitActivity"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@mipmap/welcome" android:adjustViewBounds="true"> </ImageView> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="10dp" android:layout_marginEnd="8dp" android:padding="8dp" android:background="@drawable/translucent2" android:lineSpacingExtra="4sp" android:text="请选择您的身份" android:textAlignment="center" android:textSize="20sp" android:textStyle="bold" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/ChooseTeacher" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/translucent2" android:layout_toLeftOf="@+id/canzhao" android:layout_marginRight="45dp" android:layout_marginTop="50dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/teacher_ico" android:layout_margin="10dp" android:src="@mipmap/teacher_ico"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:text="我是教师" android:layout_centerHorizontal="true" android:textColor="#576B95" android:layout_marginTop="5dp" android:layout_below="@id/teacher_ico" android:textStyle="bold"/> </RelativeLayout> <TextView android:id="@+id/canzhao" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" /> <RelativeLayout android:id="@+id/ChooseStudent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/translucent2" android:layout_toRightOf="@+id/canzhao" android:layout_marginLeft="45dp" android:layout_marginTop="50dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/student_ico" android:layout_margin="10dp" android:src="@mipmap/student_ico"/> <TextView android:id="@+id/nameLogined" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:text="我是学生" android:layout_centerHorizontal="true" android:textColor="#576B95" android:layout_marginTop="5dp" android:layout_below="@id/student_ico" android:textStyle="bold"/> </RelativeLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/translucent2" android:lineSpacingExtra="4sp" android:text="Copyright © 2020 Henry. All Rights Reserved" android:layout_marginTop="300dp" android:textAlignment="center" android:textSize="12sp" android:textStyle="bold" /> <ImageView android:id="@+id/welcomebottom" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:src="@mipmap/welcomebottom" android:adjustViewBounds="true"> </ImageView> </RelativeLayout> </LinearLayout>
成功登录后跳转一个新的Activity,其中能通过点击底部的导航栏在4个Fragment中切换
(暂时还未设计出其他三个页面的布局框架,目前初步定下【我的】页面):
在【我的】页面中,点击【关于】可跳转至【关于我】页面,里面简单写了一点我的联系方式,然后可以通过点击图标直接拨打电话或发送短信(需要同意相应的权限):
该【关于我】页面的调用拨号和发短信功能实现具体代码如下(我在这里把我的号码改成123456了嘻嘻):package com.henry.schoolsystem.ui.me; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.ImageButton; import com.henry.schoolsystem.R; public class AboutActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); ImageButton imageButton = (ImageButton) findViewById(R.id.imageButton_phone); //获取电话图片按钮 ImageButton imageButton1 = (ImageButton) findViewById(R.id.imageButton_sms); //获取短信图片按钮 imageButton.setOnClickListener(l); //为电话图片按钮设置单击事件 imageButton1.setOnClickListener(l);//为短信图片按钮设置单击事件 } //创建监听事件对象 View.OnClickListener l = new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); //创建Intent对象 switch (v.getId()) { //根据ImageButton组件的id进行判断 case R.id.imageButton_phone: //如果是电话图片按钮 intent.setAction(intent.ACTION_DIAL); //调用拨号面板 intent.setData(Uri.parse("tel:123456")); //设置要拨打的号码 startActivity(intent); //启动Activity break; case R.id.imageButton_sms: //如果是短信图片按钮 intent.setAction(intent.ACTION_SENDTO); //调用发送短信息 intent.setData(Uri.parse("smsto:123456")); //设置要发送的号码 intent.putExtra("sms_body", "您好!"); //设置要发送的信息内容 startActivity(intent); //启动Activity } } }; }
功能展示
写入数据库需要使用SQLiteOpenHelper
类,该类是一个抽象类,需要创建该类的派生类,我这里是DBOpenHelper
,源代码如下:package com.henry.schoolsystem.ui.login; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by Henry */ public class DBOpenHelper extends SQLiteOpenHelper { public static final String USER_INFO = "userInfo"; public static final String USER_LOGIN = "userLogin"; public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, null, version); //重写构造方法并设置factory为null } @Override public void onCreate(SQLiteDatabase db) { /** * 当该子类被实例化时会创建指定名的数据库,在onCreate中创建用户信息表和登录信息表 * **/ db.execSQL("CREATE TABLE IF NOT EXISTS " + USER_INFO + "( " + "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "userName VARCHAR, " + "nickName VARCHAR, " + "sex VARCHAR, " + "qq VARCHAR, " + "wechat VARCHAR, " + "motto VARCHAR " + ")"); db.execSQL("CREATE TABLE IF NOT EXISTS " + USER_LOGIN + "( " + "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "userName VARCHAR, " + "password VARCHAR" + ")"); } @Override // 重写基类的onUpgrade()方法,以便数据库版本更新 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //提示版本更新并输出旧版本信息与新版本信息 System.out.println("---版本更新-----" + oldVersion + "--->" + newVersion); } }
SLoginActivity
为例):package com.henry.schoolsystem.ui.login; import androidx.appcompat.app.AppCompatActivity; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.henry.schoolsystem.R; import com.henry.schoolsystem.SMainActivity; import com.henry.schoolsystem.TMainActivity; import com.henry.schoolsystem.utils.MD5Utils; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class SLoginActivity extends AppCompatActivity { private DBOpenHelper dbOpenHelper; //定义DBOpenHelper,用于与数据库连接 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_slogin); //创建DBOpenHelper对象,指定名称、版本号并保存在databases目录下 dbOpenHelper = new DBOpenHelper(SLoginActivity.this, "student.db", null, 1); final EditText usernameEditText = (EditText) findViewById(R.id.add_username); //获取添加用户名的编辑框 final EditText passwordEditText = (EditText) findViewById(R.id.add_password); //获取添加密码的编辑框 final Button btn_Save = (Button) findViewById(R.id.register2); //获取注册按钮 final Button btn_Login = (Button) findViewById(R.id.login2); //获取登录按钮 //登录 btn_Login.setOnClickListener(new View.OnClickListener() { //单击登录按钮查看是否有该用户以及密码是否正确 @Override public void onClick(View v) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); String key = usernameEditText.getText().toString(); //获取输入的登录名 //用Cursor游标进行查询 Cursor cursor = db.query("userLogin", null , "userName = ?", new String[]{key}, null, null, null); ArrayList<Map<String, String>> resultList = new ArrayList<Map<String, String>>(); //创建ArrayList对象,用于保存查询出的结果 while (cursor.moveToNext()) { // 遍历Cursor结果集 Map<String, String> map = new HashMap<>(); // 将结果集中的数据存入HashMap中 // 取出查询记录中第2、3列的值 if (resultList.size() != 0) break; map.put("userName", cursor.getString(1)); map.put("password", cursor.getString(2));//将查询出的数据存入ArrayList中 resultList.add(map); } if (resultList.size() == 0) { //如果数据库中没有数据 Toast.makeText(SLoginActivity.this, "用户名不存在,请重新输入或注册!", Toast.LENGTH_SHORT).show(); cursor.close(); } else { // 否则比较password是否一致 String passwordIn = passwordEditText.getText().toString(); //获取输入的密码 String passwordNeed = cursor.getString(cursor.getColumnIndex("password")); //获取需要填写的密码 if (passwordNeed.equals(MD5Utils.md5(passwordIn))) { //只是比较内容,不能用== Toast.makeText(SLoginActivity.this, "登录成功!"+key+",欢迎您~", Toast.LENGTH_LONG).show(); cursor.close(); Intent intent = new Intent(SLoginActivity.this, SMainActivity.class); //登录成功跳转至学生端 startActivity(intent); } else { Toast.makeText(SLoginActivity.this, "密码错误,请重新输入!", Toast.LENGTH_SHORT).show(); } } } }); //注册 btn_Save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String username = usernameEditText.getText().toString(); //获取填写的用户名 String password = passwordEditText.getText().toString(); //获取填写的密码 if (username.equals("")||password.equals("")){ //如果填写的用户名或密码为空时 Toast.makeText(SLoginActivity.this, "用户名或密码为空,请重新填写", Toast.LENGTH_SHORT).show(); }else { // 调用insertData()方法,实现插入用户数据 insertData(dbOpenHelper.getReadableDatabase(), username, password); // 显示提示信息 dbOpenHelper.close(); Toast.makeText(SLoginActivity.this, "注册成功!可以登录啦", Toast.LENGTH_SHORT).show(); } } }); } //创建insertData()方法实现插入数据 private void insertData(SQLiteDatabase readableDatabase, String username, String password) { ContentValues values = new ContentValues(); values.put("userName", username); //保存用户名 values.put("password", MD5Utils.md5(password)); //保存密码 try { readableDatabase.insert("userLogin", null, values);//执行插入操作 } catch (SQLException e) { Log.e("SQLiteDatabase", "Error inserting " + values, e); } } }
对了,上一步中,如果密码输入错误或是用户名不存在会有如下的登录失败提示:
然后该注册的密码在数据库中是经过MD5算法加密后存储的,MD5加密算法的java类如下:package com.henry.schoolsystem.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * 创建一个md5()方法 * 通过 MessageDigest 的 getInstance()方法 * 获取数据加密对象 digest,然后通过该对象的 digest()方法对密码进行加密 * 由于注册登录涉及密码,需要对用户的密码进行 MD5 算法加密 */ public class MD5Utils { // md5 加密的算法 public static String md5(String text){ MessageDigest digest = null; try { //获取数据指纹对象 digest = MessageDigest.getInstance("md5"); //字节数组 byte[] result = digest.digest(text.getBytes()); //16进制转换 StringBuffer sb = new StringBuffer(); //获取所有字节进行转换 for (byte b: result){ //使用『与算法』,java使用unicode字符,所以每个字符占位两个 // 需要与两位16进制最大值进行与运算,获取number值 int number = b & 0xff; //number值转换字符串 String hex = Integer.toHexString(number); if (hex.length() == 1){ //若转换后的字符长度等于1则进行字符串拼接 sb.append("0"+hex); }else { sb.append(hex); } } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); //发送异常return空字符串 return ""; } } }
相关教程可参考:快速激活Navicat Premium 12
打开后连接我从AS中导出的数据库student.db,查看userLogin表:
— — — — — — — — — — — — — — — — — — — — — — — — — — — —
短信验证功能可以有很多平台使用,我选择的是MobTech(免费的),可由此查看相关文档:SMSSDK for Android
需要在AndroidManifest.xml
中添加以下权限:
以及在项目根目录的build.gradle
中添加依赖,不过你可能还需要像我一样添加上两个库:
以及在使用SMSSDK模块的build.gradle中,添加MobSDK插件和扩展:// 添加插件 apply plugin: 'com.mob.sdk' // 在MobSDK的扩展中注册SMSSDK的相关信息 MobSDK { appKey "申请Mob的appkey" appSecret "申请Mob的AppSecret" SMSSDK {} }
userLogin
和userInfo
两个表,每个页面的设计也会在第二阶段弄出来,不过刚学不久,在很多地方遇到了障碍,在努力克服中,继续加油叭💪!
对了,安卓连接SQLite数据库的一些具体介绍我会在近期发表一篇博客~
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算