1. 说明
本音乐播放器基于Android开发,原为我和另外两个小伙伴在上学期间一起做的一个小项目,近来有时间整理一下。之前我有文章已经介绍了播放界面的功能实现(Android音乐播放器开发),但介绍的比较粗糙,接下来会做更细致化的整理。源码已同步到Gitee仓库,GitHub仓库,觉得还不错的话帮忙点个“star”吧,非常感谢。
当初代码写的很随意,目的只为实现功能。现在更倾向于代码可读性和简洁性,因此会在原来的程序基础上做一些小修改。也有可能不会一步到位,计划慢慢修改,以增强自己的理解。
服务端使用的是比较传统的servlet和jdbc传递数据,整理完之后,新版本会修改为SSM框架,更加简洁高效。安卓端使用的也都是基础的工具,比如音乐播放功能的实现也是借助于入门级的MediaPlayer类,目前关于安卓端没有什么更改的想法。
(适用于平时做个小课设的小伙伴们)
看过登录和注册的小伙伴再看这篇肯定会觉得非常眼熟了,因为它们几个的逻辑上非常相似。
2. 修改密码界面设计
<?xml version="1.0" encoding="utf-8"?>
<!--修改密码界面-->
<!--这里的布局放置是: 1 个 ImageView 控件,用于显示用户头像;4个 EditText 控件,用于输入用户名、密码、新密码,再次输入新密码;1 个 Button 控件为修改密码按钮-->
<!--修改 activity_register.xml 为 LinearLayout 布局-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_register"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/c"
android:orientation="vertical">
<include layout="@layout/main_title_bar"></include><!--引入标题栏-->
<ImageView
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="25dp"
android:src="@drawable/x"/>
<!--三个编辑框-->
<EditText
android:id="@+id/et_user_name"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:layout_marginTop="35dp"
android:background="@drawable/register_user_name_bg"
android:drawableLeft="@drawable/user_name_icon"
android:drawablePadding="10dp"
android:gravity="center_vertical"
android:hint="请输入用户名"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="#000000"
android:textColorHint="#a3a3a3"
android:textSize="14sp"/>
<EditText
android:id="@+id/et_psw"
android:layout_width="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_height="48dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:background="@drawable/register_psw_bg"
android:drawableLeft="@drawable/psw_icon"
android:drawablePadding="10dp"
android:hint="请输入密码"
android:inputType="textPassword"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="#000000"
android:textColorHint="#a3a3a3"
android:textSize="14sp"/>
<EditText
android:id="@+id/et_new_psw"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:background="@drawable/register_psw_again_bg"
android:drawableLeft="@drawable/psw_icon"
android:drawablePadding="10dp"
android:hint="请输入修改后的密码"
android:inputType="textPassword"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="#000000"
android:textColorHint="#a3a3a3"
android:textSize="14sp"/>
<EditText
android:id="@+id/et_new_psw_again"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:background="@drawable/register_psw_again_bg"
android:drawableLeft="@drawable/psw_icon"
android:drawablePadding="10dp"
android:hint="请再输入修改后的密码"
android:inputType="textPassword"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="#000000"
android:textColorHint="#a3a3a3"
android:textSize="14sp"/>
<Button
android:id="@+id/btn_change_psw"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:layout_marginTop="15dp"
android:background="@drawable/register_selector"
android:text="修改"
android:textColor="@android:color/white"
android:textSize="18sp"/>
</LinearLayout>
3. 修改密码功能实现
照例,先贴全部代码
package cn.sjcup.musicplayer;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONObject;
import cn.sjcup.musicplayer.servlet.RequestServlet;
public class ChangePwdActivity extends Activity {
private EditText mUserName;
private EditText mPassword;
private EditText mNewPwd;
private EditText mNewPwdAgain;
private TextView mTitle;
private Button mChangePwd;
private TextView mBack;
private String userName, password, newPwd, newPwdAgain;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_change_pwd);
initView(); //初始化界面
initEvent(); //初始化事件
}
private void initView(){
mUserName = this.findViewById(R.id.et_user_name);
mPassword = this.findViewById(R.id.et_psw);
mNewPwd = this.findViewById(R.id.et_new_psw);
mNewPwdAgain = this.findViewById(R.id.et_new_psw_again);
mTitle = this.findViewById(R.id.tv_main_title);
mChangePwd = this.findViewById(R.id.btn_change_psw);
mBack = this.findViewById(R.id.tv_back);
mTitle.setText("修改密码");
}
private void initEvent(){
mBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ChangePwdActivity.this.finish();
}
});
mChangePwd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
userName = mUserName.getText().toString().trim();
password = mPassword.getText().toString().trim();
newPwd = mNewPwd.getText().toString().trim();
newPwdAgain = mNewPwdAgain.getText().toString().trim();
if (TextUtils.isEmpty(userName)) {
Toast.makeText(ChangePwdActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
return;
} else if(TextUtils.isEmpty(password)){
Toast.makeText(ChangePwdActivity.this, "请输入原密码", Toast.LENGTH_SHORT).show();
return;
}else if (TextUtils.isEmpty(newPwd)){
Toast.makeText(ChangePwdActivity.this, "请输入新密码",Toast.LENGTH_SHORT).show();
return;
}else if(TextUtils.isEmpty(newPwdAgain)){
Toast.makeText(ChangePwdActivity.this, "请再次输入新密码", Toast.LENGTH_SHORT).show();
return;
}
if(!newPwd.equals(newPwdAgain)){
Toast.makeText(ChangePwdActivity.this, "两次新密码输入不一致", Toast.LENGTH_SHORT).show();
return;
}
if(newPwd.equals(password)){
Toast.makeText(ChangePwdActivity.this, "新密码与原密码相同", Toast.LENGTH_SHORT).show();
}
isTrueThread(); //判断用户信息是否正确
}
});
}
private void isTrueThread(){
new Thread(){
public void run(){
JSONObject result = RequestServlet.login(userName, password);
Message msg = new Message();
msg.what = 1;
msg.obj = result;
handler.sendMessage(msg);
}
}.start();
}
private Handler handler = new Handler(){
public void handleMessage(Message msg){
if(msg.what==1){
JSONObject userInformation = (JSONObject) msg.obj;
if(userInformation == null || !userInformation.optString("account").equals(userName)){
Toast.makeText(ChangePwdActivity.this, "该账户不存在", Toast.LENGTH_SHORT).show();
return;
}else if(!userInformation.optString("password").equals(password)){
Toast.makeText(ChangePwdActivity.this, "原密码错误", Toast.LENGTH_SHORT).show();
return;
}else{
changePwdThread(); //修改密码线程
}
}
}
};
private void changePwdThread(){
new Thread(){
public void run(){
JSONObject result = RequestServlet.changePwd(userName, newPwd);
Message msg = new Message();
msg.what = 2;
msg.obj = result;
handler2.sendMessage(msg);
}
}.start();
}
private Handler handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==2){
JSONObject result = (JSONObject) msg.obj;
String str = result.optString("result");
if(str.equals("修改成功!")){
Toast.makeText(ChangePwdActivity.this, "修改成功", Toast.LENGTH_SHORT).show();
ChangePwdActivity.this.finish();
}else if(str.equals("修改失败!")){
Toast.makeText(ChangePwdActivity.this, "修改失败", Toast.LENGTH_SHORT).show();
}
}
}
};
}
声明一些变量,是为了绑定界面中的控件,实现功能
private EditText mUserName;
private EditText mPassword;
private EditText mNewPwd;
private EditText mNewPwdAgain;
private TextView mTitle;
private Button mChangePwd;
private TextView mBack;
private String userName, password, newPwd, newPwdAgain;
加载时就需要初始化界面和一些事件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_change_pwd);
initView(); //初始化界面
initEvent(); //初始化事件
}
初始化界面,首先需要绑定界面中的控件,如果需要在加载界面时操作界面变化,都是在这里设置
private void initView(){
mUserName = this.findViewById(R.id.et_user_name);
mPassword = this.findViewById(R.id.et_psw);
mNewPwd = this.findViewById(R.id.et_new_psw);
mNewPwdAgain = this.findViewById(R.id.et_new_psw_again);
mTitle = this.findViewById(R.id.tv_main_title);
mChangePwd = this.findViewById(R.id.btn_change_psw);
mBack = this.findViewById(R.id.tv_back);
mTitle.setText("修改密码");
}
初始化事件,主要是监听各个按钮,按钮被点击是做出事件响应。
private void initEvent(){
mBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ChangePwdActivity.this.finish();
}
});
mChangePwd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
userName = mUserName.getText().toString().trim();
password = mPassword.getText().toString().trim();
newPwd = mNewPwd.getText().toString().trim();
newPwdAgain = mNewPwdAgain.getText().toString().trim();
if (TextUtils.isEmpty(userName)) {
Toast.makeText(ChangePwdActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
return;
} else if(TextUtils.isEmpty(password)){
Toast.makeText(ChangePwdActivity.this, "请输入原密码", Toast.LENGTH_SHORT).show();
return;
}else if (TextUtils.isEmpty(newPwd)){
Toast.makeText(ChangePwdActivity.this, "请输入新密码",Toast.LENGTH_SHORT).show();
return;
}else if(TextUtils.isEmpty(newPwdAgain)){
Toast.makeText(ChangePwdActivity.this, "请再次输入新密码", Toast.LENGTH_SHORT).show();
return;
}
if(!newPwd.equals(newPwdAgain)){
Toast.makeText(ChangePwdActivity.this, "两次新密码输入不一致", Toast.LENGTH_SHORT).show();
return;
}
if(newPwd.equals(password)){
Toast.makeText(ChangePwdActivity.this, "新密码与原密码相同", Toast.LENGTH_SHORT).show();
}
isTrueThread(); //判断用户信息是否正确
}
});
}
点击返回,返回主界面。点击修改按钮,向数据库请求数据,这里首先判断填入的用户信息是否正确。
private void isTrueThread(){
new Thread(){
public void run(){
JSONObject result = RequestServlet.login(userName, password);
Message msg = new Message();
msg.what = 1;
msg.obj = result;
handler.sendMessage(msg);
}
}.start();
}
这里根据账户和原始密码向服务端请求用户信息,使用Message将数据传递到主线程。
private Handler handler = new Handler(){
public void handleMessage(Message msg){
if(msg.what==1){
JSONObject userInformation = (JSONObject) msg.obj;
if(userInformation == null || !userInformation.optString("account").equals(userName)){
Toast.makeText(ChangePwdActivity.this, "该账户不存在", Toast.LENGTH_SHORT).show();
return;
}else if(!userInformation.optString("password").equals(password)){
Toast.makeText(ChangePwdActivity.this, "原密码错误", Toast.LENGTH_SHORT).show();
return;
}else{
changePwdThread(); //修改密码线程
}
}
}
};
主线程判断填写的账户和密码是否正确,如果都正确,启动修改密码的子线程。子线程调用了RequestServlet类中的changePwd方法,修改信息提交后,将服务端返回的信息传递到主线程。
private void changePwdThread(){
new Thread(){
public void run(){
JSONObject result = RequestServlet.changePwd(userName, newPwd);
Message msg = new Message();
msg.what = 2;
msg.obj = result;
handler2.sendMessage(msg);
}
}.start();
}
主线程解析服务端返回的信息,并根据该信息判断密码是否修改成功。
private Handler handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==2){
JSONObject result = (JSONObject) msg.obj;
String str = result.optString("result");
if(str.equals("修改成功!")){
Toast.makeText(ChangePwdActivity.this, "修改成功", Toast.LENGTH_SHORT).show();
ChangePwdActivity.this.finish();
}else if(str.equals("修改失败!")){
Toast.makeText(ChangePwdActivity.this, "修改失败", Toast.LENGTH_SHORT).show();
}
}
}
};
RequestServlet.changePwd
如果使用虚拟机测试,连接servlet一般使用"http://localhost:8080"或"http://127.0.0.1:8080"。这里我使用了一个局域网做测试,需要将url修改为服务端的ip。windows系统查询本地ip的方法为:cmd–>ipconfig
在changePwd方法中,首先需要根据url获取网络连接HttpURLConnection,根据连接获取文件流,再将文件流转为string型数据,最后转为json型数据,返回信息。
private static final String CHANGEPWD_SERVLET ="http://192.168.43.xxx:8080/musicplayer/UpdatePwd";
public static JSONObject changePwd(String account, String newPassword){
JSONObject result = null;
String path = CHANGEPWD_SERVLET+"?account="+account+"&newPassword="+newPassword;
HttpURLConnection conn;
try {
conn = getConn(path);
int code = conn.getResponseCode(); //http相应状态吗,200代表相应成功
if (code == 200){
InputStream stream = conn.getInputStream();
String str = streamToString(stream);
result = getJSON(str);
conn.disconnect();
}
}catch (Exception e){
e.printStackTrace();
}
return result;
}
4. 测试
测试两次密码输入不同
测试新密码与旧密码相同
测试使用不存在的账户名
测试将‘cun’这个账户名的密码由‘123456’修改为‘456789’
查看数据库,可以发现数据库里的数据已经被修改
后面就正式步入音乐播放
的内容了。
5.
近来发现一些小伙伴不看开头啊。
程序已经放到两个仓库了,觉得有用的话,就请给本文点个赞,给仓库点个star吧!万分感谢!