diff --git a/app/build.gradle b/app/build.gradle index f078951..fc06fc0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,5 +43,6 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" + implementation "androidx.biometric:biometric:1.1.0" } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c559a6c..5ab2851 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ { if (isError) { - data.setRemove(true); - dao.update(data); + if (data.isUpload()) { + data.setRemove(true); + dao.update(data); + } else { + dao.delete(data); + } } else { dao.delete(data); } Handler handler = new Handler(Looper.getMainLooper()); handler.post(() -> { dialog.dismiss(); + removeDialog.dismiss(); Toast.makeText(context, "删除成功", Toast.LENGTH_LONG).show(); + list.remove(position); notifyDataSetChanged(); }); }).start(); diff --git a/app/src/main/java/com/yutou/passmanage/Datas/PassWordData.java b/app/src/main/java/com/yutou/passmanage/Datas/PassWordData.java deleted file mode 100644 index a744a9f..0000000 --- a/app/src/main/java/com/yutou/passmanage/Datas/PassWordData.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.yutou.passmanage.Datas; - -public class PassWordData { - private String icon; - private String packageName; - private String name; - private String user; - private String password; - - public String getIcon() { - return icon; - } - - public void setIcon(String icon) { - this.icon = icon; - } - - public String getPackageName() { - return packageName; - } - - public void setPackageName(String packageName) { - this.packageName = packageName; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUser() { - return user; - } - - public void setUser(String user) { - this.user = user; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } -} diff --git a/app/src/main/java/com/yutou/passmanage/Datas/ToolsPasswordDao.java b/app/src/main/java/com/yutou/passmanage/Datas/ToolsPasswordDao.java index 8597ea8..2db493e 100644 --- a/app/src/main/java/com/yutou/passmanage/Datas/ToolsPasswordDao.java +++ b/app/src/main/java/com/yutou/passmanage/Datas/ToolsPasswordDao.java @@ -11,6 +11,8 @@ import java.util.List; @Dao public interface ToolsPasswordDao { @Query("select * from ToolsPassword") + List getAllAndRemove(); + @Query("select * from ToolsPassword where remove=0") List getAll(); @Query("select * from ToolsPassword where title=:title and account=:account and password=:password") ToolsPassword isExist(String title,String account,String password); @@ -24,4 +26,6 @@ public interface ToolsPasswordDao { void delete(ToolsPassword password); @Update void update(ToolsPassword password); + @Query("DELETE FROM ToolsPassword") + void clear(); } diff --git a/app/src/main/java/com/yutou/passmanage/MainActivity.java b/app/src/main/java/com/yutou/passmanage/MainActivity.java index 7412291..ac990c9 100644 --- a/app/src/main/java/com/yutou/passmanage/MainActivity.java +++ b/app/src/main/java/com/yutou/passmanage/MainActivity.java @@ -1,28 +1,15 @@ 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.view.WindowManager; 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; @@ -40,6 +27,17 @@ import com.yutou.passmanage.Tools.Tools; import java.util.ArrayList; import java.util.List; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.biometric.BiometricManager; +import androidx.biometric.BiometricPrompt; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK; +import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; import static com.yutou.passmanage.Tools.RoomDatabaseManager.addPassword; public class MainActivity extends AppCompatActivity { @@ -52,10 +50,65 @@ public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - initView(); - init(); + auth(); + + } + BiometricPrompt prompt; + void auth() { + BiometricManager manager = BiometricManager.from(this); + if (manager.canAuthenticate(BIOMETRIC_WEAK | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + /* Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL); + enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, + BIOMETRIC_STRONG | DEVICE_CREDENTIAL); + startActivityForResult(enrollIntent, 233);*/ + + } + prompt=new BiometricPrompt(this, ContextCompat.getMainExecutor(this), new BiometricPrompt.AuthenticationCallback() { + @Override + public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) { + super.onAuthenticationSucceeded(result); + Toast.makeText(MainActivity.this, "验证成功", Toast.LENGTH_LONG).show(); + initView(); + init(); + } + + @Override + public void onAuthenticationFailed() { + super.onAuthenticationFailed(); + Toast.makeText(MainActivity.this, "验证失败,已退出", Toast.LENGTH_LONG).show(); + exit(); + } + + @Override + public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) { + super.onAuthenticationError(errorCode, errString); + System.out.println("errorCode = " + errorCode + ", errString = " + errString); + if(errorCode==10){ + auth(); + }else if(errorCode==13){ + + } + } + }); + BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() + .setTitle("验证指纹") + .setSubtitle("使用指纹来解锁应用") + .setAllowedAuthenticators(BIOMETRIC_WEAK | DEVICE_CREDENTIAL) + .build(); + prompt.authenticate(promptInfo); + System.out.println("调用指纹"); + } else { + + Toast.makeText(this, "必须在支持指纹的设备上使用", Toast.LENGTH_LONG).show(); + } + } + void exit(){ + MainActivity.this.finish(); + System.exit(0); } void initView() { @@ -72,6 +125,7 @@ public class MainActivity extends AppCompatActivity { search.setText(""); new Thread(this::showData).start(); }); + search.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -150,13 +204,13 @@ public class MainActivity extends AppCompatActivity { 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) + .setCancelable(false) .setPositiveButton("确定", (dialog1, which) -> { String k = key.getText().toString().trim(); if (Tools.isEmpty(k)) { @@ -178,10 +232,10 @@ public class MainActivity extends AppCompatActivity { void initData() { new Thread(() -> { - List list = dao.getAll(); + List list = dao.getAllAndRemove(); for (ToolsPassword password : list) { System.out.println(JSONObject.toJSONString(password)); - if (!password.isUpload()&&!password.isRemove()) { + if (!password.isUpload() && !password.isRemove()) { addPassword(password.getTitle(), password.getAccount(), password.getPassword(), -1, true, new NetworkInterface() { @Override public void httpGetData(Object data, int state) { @@ -197,7 +251,7 @@ public class MainActivity extends AppCompatActivity { } }); - }else if(password.isRemove()){ + } else if (password.isRemove()) { JSONObject json = new JSONObject(); json.put("id", password.getId()); NetworkTool.httpPost(NetworkTool.NetworkAPI.PASSWORD_REMOVE, json, new NetworkInterface() { @@ -216,11 +270,16 @@ public class MainActivity extends AppCompatActivity { @Override public void run() { if (isError) { - password.setRemove(true); - dao.update(password); + if (password.isUpload()) { + password.setRemove(true); + dao.update(password); + } else { + dao.delete(password); + } } else { dao.delete(password); } + showData(); } }).start(); @@ -236,13 +295,26 @@ public class MainActivity extends AppCompatActivity { if (json.getInteger("code") == 0) { List 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); + try { + for (ToolsPassword password : list) { + if (dao.isExist(password.getTitle(), password.getAccount(), password.getPassword()) == null) { + password.setUpload(true); + dao.insert(password); + } } + } catch (Exception e) { + e.printStackTrace(); + dao.clear(); + for (ToolsPassword password : list) { + if (dao.isExist(password.getTitle(), password.getAccount(), password.getPassword()) == null) { + password.setUpload(true); + dao.insert(password); + } + } + } finally { + showData(); } - showData(); + }).start(); } } diff --git a/app/src/main/java/com/yutou/passmanage/Tools/NetworkTool.java b/app/src/main/java/com/yutou/passmanage/Tools/NetworkTool.java index e4e9937..defbe8b 100644 --- a/app/src/main/java/com/yutou/passmanage/Tools/NetworkTool.java +++ b/app/src/main/java/com/yutou/passmanage/Tools/NetworkTool.java @@ -9,22 +9,13 @@ import com.yutou.passmanage.Datas.AppData; import com.yutou.passmanage.Interfaces.NetworkInterface; import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.net.ConnectException; import java.net.HttpURLConnection; -import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Set; @@ -33,7 +24,7 @@ public class NetworkTool { private final static String TAG = NetworkTool.class.getSimpleName(); public static class NetworkAPI { - public static String HOME = "http://192.168.137.1/tools/password/"; + public static String HOME = "http://tools.yutou233.cn/tools/password/"; 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"; @@ -45,11 +36,6 @@ public class NetworkTool { } - private NetworkTool() { - //HOME = "http://192.168.31.92:8000/nas"; - } - - public static void httpGet(String url, JSONObject body, NetworkInterface networkInterface) { new Thread(new Runnable() { @Override diff --git a/app/src/main/res/mipmap-anydpi-v26/app_icon.xml b/app/src/main/res/mipmap-anydpi-v26/app_icon.xml new file mode 100644 index 0000000..7699432 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/app_icon.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml b/app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml new file mode 100644 index 0000000..7699432 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/app_icon_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/app_icon.png b/app/src/main/res/mipmap-hdpi/app_icon.png new file mode 100644 index 0000000..d2a80ad Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon.png differ diff --git a/app/src/main/res/mipmap-hdpi/app_icon_foreground.png b/app/src/main/res/mipmap-hdpi/app_icon_foreground.png new file mode 100644 index 0000000..2686d5f Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon_foreground.png differ diff --git a/app/src/main/res/mipmap-hdpi/app_icon_round.png b/app/src/main/res/mipmap-hdpi/app_icon_round.png new file mode 100644 index 0000000..8802963 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/app_icon_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/app_icon.png b/app/src/main/res/mipmap-mdpi/app_icon.png new file mode 100644 index 0000000..db77993 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/app_icon.png differ diff --git a/app/src/main/res/mipmap-mdpi/app_icon_foreground.png b/app/src/main/res/mipmap-mdpi/app_icon_foreground.png new file mode 100644 index 0000000..4b2d00c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/app_icon_foreground.png differ diff --git a/app/src/main/res/mipmap-mdpi/app_icon_round.png b/app/src/main/res/mipmap-mdpi/app_icon_round.png new file mode 100644 index 0000000..bfd1f77 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/app_icon_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/app_icon.png b/app/src/main/res/mipmap-xhdpi/app_icon.png new file mode 100644 index 0000000..1c71685 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/app_icon.png differ diff --git a/app/src/main/res/mipmap-xhdpi/app_icon_foreground.png b/app/src/main/res/mipmap-xhdpi/app_icon_foreground.png new file mode 100644 index 0000000..d82d440 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/app_icon_foreground.png differ diff --git a/app/src/main/res/mipmap-xhdpi/app_icon_round.png b/app/src/main/res/mipmap-xhdpi/app_icon_round.png new file mode 100644 index 0000000..3dde67f Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/app_icon_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/app_icon.png b/app/src/main/res/mipmap-xxhdpi/app_icon.png new file mode 100644 index 0000000..f182813 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/app_icon.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/app_icon_foreground.png b/app/src/main/res/mipmap-xxhdpi/app_icon_foreground.png new file mode 100644 index 0000000..3fddc0c Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/app_icon_foreground.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/app_icon_round.png b/app/src/main/res/mipmap-xxhdpi/app_icon_round.png new file mode 100644 index 0000000..8394f48 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/app_icon_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/app_icon.png b/app/src/main/res/mipmap-xxxhdpi/app_icon.png new file mode 100644 index 0000000..fe080f6 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/app_icon.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/app_icon_foreground.png b/app/src/main/res/mipmap-xxxhdpi/app_icon_foreground.png new file mode 100644 index 0000000..7032b32 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/app_icon_foreground.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/app_icon_round.png b/app/src/main/res/mipmap-xxxhdpi/app_icon_round.png new file mode 100644 index 0000000..f5ae096 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/app_icon_round.png differ diff --git a/app/src/main/res/values/app_icon_background.xml b/app/src/main/res/values/app_icon_background.xml new file mode 100644 index 0000000..176ccea --- /dev/null +++ b/app/src/main/res/values/app_icon_background.xml @@ -0,0 +1,4 @@ + + + #639BFF + \ No newline at end of file