数据库 #1

Open
pu5twshpv wants to merge 2 commits from anyh into main

@ -1,2 +1,7 @@
<<<<<<< HEAD
#Mon May 26 14:33:47 GMT+08:00 2025
java.home=D\:\\Android\\AS_INstall\\jbr
=======
#Sat May 24 23:39:46 CST 2025
java.home=D\:\\Andr\\jbr
>>>>>>> a11e684a7b53b2288bd2435ed63bc73bcd82db22

Binary file not shown.

@ -1 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,123 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

@ -4,6 +4,14 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-05-26T13:46:32.570753600Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=83784f3e" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
<SelectionState runConfigName="MovenetLightningTest">
<option name="selectionMode" value="DROPDOWN" />

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">

@ -49,8 +49,11 @@ dependencies {
implementation 'org.tensorflow:tensorflow-lite:2.14.0'
implementation 'org.tensorflow:tensorflow-lite-gpu:2.5.0'
implementation 'org.tensorflow:tensorflow-lite-support:0.3.0'
implementation 'org.mindrot:jbcrypt:0.4'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation "com.google.truth:truth:1.1.3"
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

@ -2,18 +2,24 @@ package org.tensorflow.lite.examples.poseestimation
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.textfield.TextInputEditText
import android.widget.Button
import android.widget.TextView
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import org.tensorflow.lite.examples.poseestimation.auth.UserDao
import org.tensorflow.lite.examples.poseestimation.utils.PasswordUtils
class LoginActivity : AppCompatActivity() {
private lateinit var userDao: UserDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
// 初始化 UserDao
userDao = UserDao(this)
// 获取从上一个页面传递的数据
val selectedGender = intent.getStringExtra("selected_gender")
val selectedAge = intent.getIntExtra("selected_age", 0)
@ -42,16 +48,44 @@ class LoginActivity : AppCompatActivity() {
return@setOnClickListener
}
// 执行数据库查询验证
val user = userDao.getUserByUsername(email)
if (user != null) {
// 验证密码
if (PasswordUtils.verifyPassword(password, user.passwordHash)) {
// 登录成功
Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show()
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("selected_gender", selectedGender)
intent.putExtra("selected_age", selectedAge)
intent.putExtra("selected_weight", selectedWeight)
intent.putExtra("selected_height", selectedHeight)
//intent.putExtra("user_id", user.id) // 传递用户ID
startActivity(intent)
finish()
} else {
//密码错误
passwordEdit.error = "密码不正确"
}
}else {
//用户不存在
emailEdit.error = "用户不存在"
}
// TODO: 这里添加实际的登录验证逻辑
// 目前仅做演示,直接跳转到主页面
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("selected_gender", selectedGender)
intent.putExtra("selected_age", selectedAge)
intent.putExtra("selected_weight", selectedWeight)
intent.putExtra("selected_height", selectedHeight)
startActivity(intent)
finish()
}
// val intent = Intent(this, MainActivity::class.java)
// intent.putExtra("selected_gender", selectedGender)
// intent.putExtra("selected_age", selectedAge)
// intent.putExtra("selected_weight", selectedWeight)
// intent.putExtra("selected_height", selectedHeight)
// startActivity(intent)
// finish()
}
// 忘记密码点击事件
forgotPassword.setOnClickListener {

@ -6,12 +6,18 @@ import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import org.tensorflow.lite.examples.poseestimation.auth.UserDao
import org.tensorflow.lite.examples.poseestimation.auth.User
import org.tensorflow.lite.examples.poseestimation.utils.PasswordUtils
class SignupActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_signup)
// 初始化 UserDao
var userDao = UserDao(this)
// 绑定控件
val usernameEdit = findViewById<EditText>(R.id.editUsername)
val passwordEdit = findViewById<EditText>(R.id.editPassword)
@ -46,9 +52,29 @@ class SignupActivity : AppCompatActivity() {
return@setOnClickListener
}
// TODO: 这里添加实际的注册逻辑
Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show()
finish()
// 检查用户名是否已存在
if (userDao.checkUsernameExists(username)) {
usernameEdit.error = "用户名已存在"
Toast.makeText(this, "用户名已存在", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
// 加密密码
val passwordHash = PasswordUtils.hashPassword(password)
val user = User()
user.setUsername(username)
user.setPasswordHash(passwordHash)
// 保存到数据库
val userId = userDao.addUser(user)
if (userId != (-1).toLong()) {
Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show()
finish()
} else {
Toast.makeText(this, "注册失败,请重试", Toast.LENGTH_SHORT).show()
}
}
// Login Tab点击事件

@ -0,0 +1,49 @@
package org.tensorflow.lite.examples.poseestimation.auth;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper{
// 数据库信息
private static final String DATABASE_NAME = "user_database";
private static final int DATABASE_VERSION = 1;
// 表名和列名
public static final String TABLE_USERS = "users";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_USERNAME = "username";
public static final String COLUMN_PASSWORD_HASH = "password_hash";
public static final String COLUMN_AGE = "age";
public static final String COLUMN_WEIGHT = "weight";
public static final String COLUMN_GENDER = "gender";
public static final String COLUMN_HEIGHT = "height";
// 创建表的SQL语句
private static final String CREATE_TABLE_USERS =
"CREATE TABLE " + TABLE_USERS + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_USERNAME + " TEXT UNIQUE NOT NULL,"
+ COLUMN_PASSWORD_HASH + " TEXT NOT NULL"
// + COLUMN_AGE + " INTEGER,"
// + COLUMN_WEIGHT + " REAL,"
// + COLUMN_GENDER + " TEXT,"
// + COLUMN_HEIGHT + " REAL"
+ ")";
// 构造函数
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_USERS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_USERS);
onCreate(db);
}
}

@ -0,0 +1,46 @@
package org.tensorflow.lite.examples.poseestimation.auth;
import java.io.Serializable;
public class User implements Serializable{
private long id;
private String username;
private String passwordHash;
// private int age;
// private float weight;
// private String gender;
// private float height;
// 构造函数、Getter和Setter方法
public User() {}
public User(String username, String passwordHash) {
this.username = username;
this.passwordHash = passwordHash;
// this.age = age;
// this.weight = weight;
// this.gender = gender;
// this.height = height;
}
// Getter和Setter方法
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPasswordHash() { return passwordHash; }
public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
// public int getAge() { return age; }
// public void setAge(int age) { this.age = age; }
//
// public float getWeight() { return weight; }
// public void setWeight(float weight) { this.weight = weight; }
//
// public String getGender() { return gender; }
// public void setGender(String gender) { this.gender = gender; }
//
// public float getHeight() { return height; }
// public void setHeight(float height) { this.height = height; }
}

@ -0,0 +1,130 @@
package org.tensorflow.lite.examples.poseestimation.auth;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import org.tensorflow.lite.examples.poseestimation.auth.User;
import java.util.ArrayList;
import java.util.List;
public class UserDao {
private DatabaseHelper databaseHelper;
public UserDao(Context context) {
databaseHelper = new DatabaseHelper(context);
}
// 添加用户
public long addUser(User user) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DatabaseHelper.COLUMN_USERNAME, user.getUsername());
values.put(DatabaseHelper.COLUMN_PASSWORD_HASH, user.getPasswordHash());
// values.put(DatabaseHelper.COLUMN_AGE, user.getAge());
// values.put(DatabaseHelper.COLUMN_WEIGHT, user.getWeight());
// values.put(DatabaseHelper.COLUMN_GENDER, user.getGender());
// values.put(DatabaseHelper.COLUMN_HEIGHT, user.getHeight());
long id = db.insert(DatabaseHelper.TABLE_USERS, null, values);
db.close();
return id;
}
// 根据用户名获取用户
public User getUserByUsername(String username) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
String[] projection = {
DatabaseHelper.COLUMN_ID,
DatabaseHelper.COLUMN_USERNAME,
DatabaseHelper.COLUMN_PASSWORD_HASH,
// DatabaseHelper.COLUMN_AGE,
// DatabaseHelper.COLUMN_WEIGHT,
// DatabaseHelper.COLUMN_GENDER,
// DatabaseHelper.COLUMN_HEIGHT
};
String selection = DatabaseHelper.COLUMN_USERNAME + " = ?";
String[] selectionArgs = { username };
Cursor cursor = db.query(
DatabaseHelper.TABLE_USERS,
projection,
selection,
selectionArgs,
null,
null,
null
);
User user = null;
if (cursor.moveToFirst()) {
user = new User();
user.setId(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.COLUMN_ID)));
user.setUsername(cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_USERNAME)));
user.setPasswordHash(cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_PASSWORD_HASH)));
// user.setAge(cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COLUMN_AGE)));
// user.setWeight(cursor.getFloat(cursor.getColumnIndex(DatabaseHelper.COLUMN_WEIGHT)));
// user.setGender(cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_GENDER)));
// user.setHeight(cursor.getFloat(cursor.getColumnIndex(DatabaseHelper.COLUMN_HEIGHT)));
}
cursor.close();
db.close();
return user;
}
// 检查用户名是否存在
public boolean checkUsernameExists(String username) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
String[] projection = { DatabaseHelper.COLUMN_USERNAME };
String selection = DatabaseHelper.COLUMN_USERNAME + " = ?";
String[] selectionArgs = { username };
Cursor cursor = db.query(
DatabaseHelper.TABLE_USERS,
projection,
selection,
selectionArgs,
null,
null,
null
);
boolean exists = cursor.moveToFirst();
cursor.close();
db.close();
return exists;
}
// 获取所有用户
public List<User> getAllUsers() {
List<User> userList = new ArrayList<>();
String selectQuery = "SELECT * FROM " + DatabaseHelper.TABLE_USERS;
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
User user = new User();
user.setId(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.COLUMN_ID)));
user.setUsername(cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_USERNAME)));
user.setPasswordHash(cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_PASSWORD_HASH)));
// user.setAge(cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COLUMN_AGE)));
// user.setWeight(cursor.getFloat(cursor.getColumnIndex(DatabaseHelper.COLUMN_WEIGHT)));
// user.setGender(cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_GENDER)));
// user.setHeight(cursor.getFloat(cursor.getColumnIndex(DatabaseHelper.COLUMN_HEIGHT)));
userList.add(user);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return userList;
}
}

@ -0,0 +1,40 @@
package org.tensorflow.lite.examples.poseestimation.utils;
import android.util.Base64;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class PasswordUtils {
private static final String ALGORITHM = "SHA-256";
private static final String SECRET_KEY = "YourSecretKey123"; // 实际应用中应存储在安全位置
// 生成密码哈希
public static String hashPassword(String password) {
try {
MessageDigest digest = MessageDigest.getInstance(ALGORITHM);
byte[] encodedHash = digest.digest(password.getBytes());
StringBuilder hexString = new StringBuilder(2 * encodedHash.length);
for (byte b : encodedHash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
// 验证密码
public static boolean verifyPassword(String password, String hashedPassword) {
String hashedInput = hashPassword(password);
return hashedInput != null && hashedInput.equals(hashedPassword);
}
}

@ -4,5 +4,10 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
<<<<<<< HEAD
#Mon May 26 14:34:26 GMT+08:00 2025
sdk.dir=D\:\\wangjiachen\\sdk
=======
#Sat May 24 23:39:55 CST 2025
sdk.dir=C\:\\Users\\26891\\AppData\\Local\\Android\\Sdk
>>>>>>> a11e684a7b53b2288bd2435ed63bc73bcd82db22

Loading…
Cancel
Save