This commit is contained in:
yutou 2021-02-22 18:34:56 +08:00
parent 0c5bebf60a
commit 9057f8b765
9 changed files with 504 additions and 88 deletions

View File

@ -38,4 +38,10 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.alibaba:fastjson:1.2.68'
def room_version = "2.2.6"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
}

View File

@ -1,30 +1,51 @@
package com.yutou.passmanage.Adapters;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import com.yutou.passmanage.Datas.PassWordData;
import com.alibaba.fastjson.JSONObject;
import com.yutou.passmanage.Datas.ToolsPassword;
import com.yutou.passmanage.Datas.ToolsPasswordDao;
import com.yutou.passmanage.Interfaces.NetworkInterface;
import com.yutou.passmanage.R;
import com.yutou.passmanage.Tools.NetworkTool;
import com.yutou.passmanage.Tools.RoomDatabaseManager;
import java.util.List;
import static com.yutou.passmanage.Tools.RoomDatabaseManager.addPassword;
public class PassWordListAdapter extends RecyclerView.Adapter<PassWordListAdapter.MyViewHolder> {
private Context context;
private List<PassWordData> list;
private List<ToolsPassword> list;
ToolsPasswordDao dao;
public PassWordListAdapter(Context context, List<PassWordData> list) {
public PassWordListAdapter(Context context, List<ToolsPassword> list) {
this.context = context;
this.list = list;
this.dao = RoomDatabaseManager.build(context).passwordDao();
}
public void setList(List<ToolsPassword> list) {
this.list = list;
}
@NonNull
@ -33,31 +54,146 @@ public class PassWordListAdapter extends RecyclerView.Adapter<PassWordListAdapte
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.recycler_list, parent, false));
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
PassWordData data=list.get(position);
holder.name.setText(data.getName());
holder.user.setText(data.getUser());
holder.password.setText(data.getPassword());
ToolsPassword data = list.get(position);
holder.name.setText(data.getTitle());
holder.user.setText("账号:" + data.getAccount());
holder.password.setText("密码:" + data.getPassword());
holder.copy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("simple text", data.getPassword());
clipboard.setPrimaryClip(clip);
Toast.makeText(context, "已复制密码", Toast.LENGTH_LONG).show();
}
});
holder.item_layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(data);
}
});
}
AlertDialog removeDialog = null;
private void showDialog(ToolsPassword data) {
View view = LayoutInflater.from(context.getApplicationContext()).inflate(R.layout.dialog_add_passworld, null);
Button delete = view.findViewById(R.id.delete);
EditText title, account, password;
title = view.findViewById(R.id.title);
account = view.findViewById(R.id.account);
password = view.findViewById(R.id.myPassword);
title.setText(data.getTitle());
account.setText(data.getAccount());
password.setText(data.getPassword());
delete.setVisibility(View.VISIBLE);
delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle("确认删除操作")
.setMessage("确定删除这条密码吗?本操作不可反悔")
.setPositiveButton("删除", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
JSONObject json = new JSONObject();
json.put("id", data.getId());
NetworkTool.httpPost(NetworkTool.NetworkAPI.PASSWORD_REMOVE, json, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
remove(false);
}
@Override
public void httpError(Exception e) {
remove(true);
}
void remove(boolean isError) {
new Thread(() -> {
if (isError) {
data.setRemove(true);
dao.update(data);
} else {
dao.delete(data);
}
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> {
dialog.dismiss();
Toast.makeText(context, "删除成功", Toast.LENGTH_LONG).show();
notifyDataSetChanged();
});
}).start();
}
});
dialog.dismiss();
}
})
.setNegativeButton("取消", (dialog13, which) -> dialog13.dismiss()).create();
dialog.show();
}
});
removeDialog = new AlertDialog.Builder(context)
.setTitle("查看信息")
.setView(view)
.setPositiveButton("更新", (dialog1, which) -> {
addPassword(title.getText().toString(), account.getText().toString(), password.getText().toString(), data.getId(), false, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
addDatabase(title.getText().toString(),
account.getText().toString(),
password.getText().toString(),
true);
}
@Override
public void httpError(Exception e) {
addDatabase(title.getText().toString(),
account.getText().toString(),
password.getText().toString(),
false);
}
void addDatabase(String title1, String account1, String password1, boolean upload) {
new Thread(() -> {
data.setTitle(title1);
data.setPassword(password1);
data.setUpload(upload);
dao.update(data);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "更新成功", Toast.LENGTH_LONG).show();
notifyDataSetChanged();
}
});
}).start();
}
});
dialog1.dismiss();
})
.setNegativeButton("取消", (dialog12, which) -> dialog12.dismiss()).create();
removeDialog.show();
}
@Override
public int getItemCount() {
return list.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
ImageButton icon;
TextView name, user, password;
Button copy;
LinearLayout item_layout;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
@ -66,6 +202,8 @@ public class PassWordListAdapter extends RecyclerView.Adapter<PassWordListAdapte
user = itemView.findViewById(R.id.user);
password = itemView.findViewById(R.id.password);
copy = itemView.findViewById(R.id.copy);
}
item_layout = itemView.findViewById(R.id.item_layout);
}
}
}

View File

@ -1,26 +1,37 @@
package com.yutou.passmanage.Datas;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
/**
* tools_password
* @author
*/
@Entity
public class ToolsPassword{
@PrimaryKey
private Integer id;
@ColumnInfo
private String title;
private String username;
@ColumnInfo
private String account;
@ColumnInfo
private String password;
@Ignore
private String url;
@Ignore
private String info;
@ColumnInfo
private Integer type;
@Ignore
private Integer uid;
@ColumnInfo
private boolean upload;
@ColumnInfo
private boolean remove;
public Integer getId() {
return id;
@ -38,12 +49,12 @@ public class ToolsPassword{
this.title = title;
}
public String getUsername() {
return username;
public String getAccount() {
return account;
}
public void setUsername(String username) {
this.username = username;
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
@ -85,4 +96,20 @@ public class ToolsPassword{
public void setUid(Integer uid) {
this.uid = uid;
}
public boolean isUpload() {
return upload;
}
public void setUpload(boolean upload) {
this.upload = upload;
}
public boolean isRemove() {
return remove;
}
public void setRemove(boolean remove) {
this.remove = remove;
}
}

View File

@ -0,0 +1,27 @@
package com.yutou.passmanage.Datas;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
@Dao
public interface ToolsPasswordDao {
@Query("select * from ToolsPassword")
List<ToolsPassword> getAll();
@Query("select * from ToolsPassword where title=:title and account=:account and password=:password")
ToolsPassword isExist(String title,String account,String password);
@Query("select * from ToolsPassword where title like :title and remove=0")
List<ToolsPassword> queryPassword(String title);
@Insert
void insert(ToolsPassword password);
@Insert
void insertAll(List<ToolsPassword> list);
@Delete
void delete(ToolsPassword password);
@Update
void update(ToolsPassword password);
}

View File

@ -2,34 +2,53 @@ package com.yutou.passmanage;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.MultiAutoCompleteTextView;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.yutou.passmanage.Adapters.PassWordListAdapter;
import com.yutou.passmanage.Datas.AppData;
import com.yutou.passmanage.Datas.ToolsPassword;
import com.yutou.passmanage.Datas.ToolsPasswordDao;
import com.yutou.passmanage.Interfaces.NetworkInterface;
import com.yutou.passmanage.Tools.NetworkTool;
import com.yutou.passmanage.Tools.RoomDatabaseManager;
import com.yutou.passmanage.Tools.Tools;
import java.util.ArrayList;
import java.util.List;
import static com.yutou.passmanage.Tools.RoomDatabaseManager.addPassword;
public class MainActivity extends AppCompatActivity {
EditText search;
ImageButton clearSearch;
RecyclerView passList;
FloatingActionButton floatButton;
PassWordListAdapter adapter;
Handler handler = new Handler(Looper.getMainLooper());
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -40,46 +59,105 @@ public class MainActivity extends AppCompatActivity {
}
void initView() {
dao = RoomDatabaseManager.build(this).passwordDao();
adapter = new PassWordListAdapter(this, new ArrayList<>());
search = findViewById(R.id.search);
clearSearch = findViewById(R.id.clearSearch);
passList = findViewById(R.id.passList);
floatButton = findViewById(R.id.floatButton);
floatButton.setOnClickListener(new View.OnClickListener() {
floatButton.setOnClickListener(v -> showAddPasswordDialog());
passList.setLayoutManager(new LinearLayoutManager(this));
passList.setAdapter(adapter);
clearSearch.setOnClickListener(v -> {
search.setText("");
new Thread(this::showData).start();
});
search.addTextChangedListener(new TextWatcher() {
@Override
public void onClick(View v) {
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.dialog_add_passworld, null);
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
.setTitle("添加账号")
.setView(view)
.setPositiveButton("保存", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
}).create();
dialog.show();
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
new Thread(() -> {
List<ToolsPassword> list;
if (Tools.isEmpty(s.toString())) {
list = dao.getAll();
} else {
list = dao.queryPassword("%" + s.toString() + "%");
}
handler.post(() -> {
adapter.setList(list);
adapter.notifyDataSetChanged();
});
}).start();
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
void showAddPasswordDialog() {
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.dialog_add_passworld, null);
EditText title, account, password;
title = view.findViewById(R.id.title);
account = view.findViewById(R.id.account);
password = view.findViewById(R.id.myPassword);
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
.setTitle("添加账号")
.setView(view)
.setPositiveButton("保存", (dialog1, which) -> {
addPassword(title.getText().toString(), account.getText().toString(), password.getText().toString(), -1, true, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
addDatabase(title.getText().toString(),
account.getText().toString(),
password.getText().toString(),
true);
}
@Override
public void httpError(Exception e) {
addDatabase(title.getText().toString(),
account.getText().toString(),
password.getText().toString(),
false);
}
void addDatabase(String title1, String account1, String password1, boolean upload) {
new Thread(() -> {
ToolsPassword psd = new ToolsPassword();
psd.setTitle(title1);
psd.setAccount(account1);
psd.setPassword(password1);
psd.setUpload(upload);
dao.insert(psd);
showData();
}).start();
}
});
dialog1.dismiss();
})
.setNegativeButton("取消", (dialog12, which) -> dialog12.dismiss()).create();
dialog.show();
}
void init() {
AppData.key = Tools.getConfig("key", this);
AppData.key = "6B059119-C8F6-4E19-A8F0-71801D776A1F";
if (Tools.isEmpty(AppData.key)) {
EditText key = new EditText(this);
key.setHint("激活码");
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("输入激活码")
.setView(key)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
.setPositiveButton("确定", (dialog1, which) -> {
String k = key.getText().toString().trim();
if (Tools.isEmpty(k)) {
Toast.makeText(MainActivity.this, "激活码不能为空", Toast.LENGTH_LONG).show();
@ -87,24 +165,31 @@ public class MainActivity extends AppCompatActivity {
}
Tools.setConfig("key", k, MainActivity.this);
AppData.key = k;
dialog.dismiss();
dialog1.dismiss();
initData();
}
}).create();
dialog.show();
} else {
initData();
}
}
ToolsPasswordDao dao;
void initData() {
NetworkTool.httpGet(NetworkTool.NetworkAPI.PASSWORD_ALL, new JSONObject(), new NetworkInterface() {
new Thread(() -> {
List<ToolsPassword> list = dao.getAll();
for (ToolsPassword password : list) {
System.out.println(JSONObject.toJSONString(password));
if (!password.isUpload()&&!password.isRemove()) {
addPassword(password.getTitle(), password.getAccount(), password.getPassword(), -1, true, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
JSONObject json=JSONObject.parseObject((String) data);
if(json.getInteger("code")==0){
List<ToolsPassword> list= JSONArray.parseArray(json.getJSONArray("data").toJSONString(),ToolsPassword.class);
showData(list);
}
new Thread(() -> {
password.setUpload(true);
dao.update(password);
}).start();
}
@Override
@ -112,8 +197,71 @@ public class MainActivity extends AppCompatActivity {
}
});
}else if(password.isRemove()){
JSONObject json = new JSONObject();
json.put("id", password.getId());
NetworkTool.httpPost(NetworkTool.NetworkAPI.PASSWORD_REMOVE, json, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
remove(false);
}
void showData(List<ToolsPassword> list){
@Override
public void httpError(Exception e) {
remove(true);
}
void remove(boolean isError) {
new Thread(new Runnable() {
@Override
public void run() {
if (isError) {
password.setRemove(true);
dao.update(password);
} else {
dao.delete(password);
}
}
}).start();
}
});
}
}
NetworkTool.httpGet(NetworkTool.NetworkAPI.PASSWORD_ALL, new JSONObject(), new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
JSONObject json = JSONObject.parseObject((String) data);
if (json.getInteger("code") == 0) {
List<ToolsPassword> list = JSONArray.parseArray(json.getJSONArray("data").toJSONString(), ToolsPassword.class);
new Thread(() -> {
for (ToolsPassword password : list) {
if (dao.isExist(password.getTitle(), password.getAccount(), password.getPassword()) == null) {
password.setUpload(true);
dao.insert(password);
}
}
showData();
}).start();
}
}
@Override
public void httpError(Exception e) {
new Thread(() -> showData()).start();
}
});
}).start();
}
void showData() {
List<ToolsPassword> list = dao.getAll();
handler.post(() -> {
adapter.setList(list);
adapter.notifyDataSetChanged();
});
}
}

View File

@ -37,6 +37,7 @@ public class NetworkTool {
public static String PASSWORD_ALL = HOME + "get/all.do";
public static String PASSWORD_ADD = HOME + "set/add.do";
public static String PASSWORD_UPDATE = HOME + "set/update.do";
public static String PASSWORD_REMOVE = HOME + "set/remove.do";
public static String PASSWORD_TYPE_ALL = HOME + "type/get/list.do";
public static String PASSWORD_TYPE_ADD = HOME + "type/set/add.do";
@ -142,14 +143,13 @@ public class NetworkTool {
connection.setReadTimeout(10 * 1000);
//connection.addRequestProperty("Connection", "keep-alive");
//connection.addRequestProperty("User-Agent", getExtUa());
connection.addRequestProperty("content-type", "application/json");
// connection.addRequestProperty("content-type", "application/json");
connection.addRequestProperty("charset", "UTF-8");
OutputStream outputStream = connection.getOutputStream();
outputStream.write(body.toJSONString().getBytes());
outputStream.write(toGetSplice(body).getBytes());
outputStream.flush();
outputStream.close();
System.out.println(connection.getResponseCode());
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((tmp = reader.readLine()) != null) {
str.append(tmp);

View File

@ -0,0 +1,59 @@
package com.yutou.passmanage.Tools;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.DatabaseConfiguration;
import androidx.room.InvalidationTracker;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteOpenHelper;
import com.alibaba.fastjson.JSONObject;
import com.yutou.passmanage.Datas.ToolsPassword;
import com.yutou.passmanage.Datas.ToolsPasswordDao;
import com.yutou.passmanage.Interfaces.NetworkInterface;
@Database(entities = {ToolsPassword.class}, version = 1,exportSchema = false)
public abstract class RoomDatabaseManager extends RoomDatabase {
public abstract ToolsPasswordDao passwordDao();
@NonNull
@Override
protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
return null;
}
@NonNull
@Override
protected InvalidationTracker createInvalidationTracker() {
return null;
}
@Override
public void clearAllTables() {
}
public static RoomDatabaseManager build(Context context) {
return Room.databaseBuilder(context.getApplicationContext(), RoomDatabaseManager.class, "password.db").build();
}
public static void addPassword(String title, String account, String password,int id,boolean isAdd, NetworkInterface networkInterface) {
JSONObject json = new JSONObject();
json.put("title", title);
json.put("username", account);
json.put("password", password);
json.put("url", "");
json.put("info", "");
json.put("type", "-1");
if(id!=-1){
json.put("id",id);
}
if(isAdd) {
NetworkTool.httpPost(NetworkTool.NetworkAPI.PASSWORD_ADD, json, networkInterface);
}else{
NetworkTool.httpPost(NetworkTool.NetworkAPI.PASSWORD_UPDATE, json, networkInterface);
}
}
}

View File

@ -16,14 +16,16 @@
android:layout_gravity="center"
android:layout_marginStart="20dp"
android:layout_weight="1"
android:text="对应软件" />
android:text="名字" />
<ImageButton
android:id="@+id/imageButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="end"
android:src="@android:drawable/ic_input_add" />
<EditText
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
android:hint="软件名字" />
</LinearLayout>
@ -41,7 +43,7 @@
android:text="账号" />
<EditText
android:id="@+id/address"
android:id="@+id/account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
@ -70,4 +72,12 @@
android:ems="10"
android:hint="密码" />
</LinearLayout>
<Button
android:id="@+id/delete"
android:visibility="gone"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除" />
</LinearLayout>

View File

@ -2,6 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
@ -13,15 +14,15 @@
android:layout_height="60dp"
android:layout_weight="0"
app:srcCompat="@drawable/ic_launcher_foreground"
tools:visibility="gone" />
android:visibility="gone" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:layout_weight="2"
android:orientation="vertical">
<TextView