liuyuqi-dellpc 3 years ago
parent
commit
322a6bb571

+ 5 - 1
app/src/main/AndroidManifest.xml

@@ -8,18 +8,22 @@
     <uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
 
     <application
+        android:name=".App"
         android:allowBackup="true"
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name"
         android:supportsRtl="true"
         android:theme="@style/Theme.SafeKeyboard">
-        <activity android:name=".MainActivity">
+        <activity android:name=".view.SplashActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name=".MainActivity" />
+        <activity android:name=".view.Guide1Activity" />
+
         <service
             android:name=".service.KeyboardIME"
             android:label="@string/app_name"

+ 21 - 0
app/src/main/java/me/yoqi/android/safekeyboard/App.java

@@ -0,0 +1,21 @@
+package me.yoqi.android.safekeyboard;
+
+import android.app.Application;
+
+/**
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public class App extends Application {
+    private static App instance;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        instance = this;
+    }
+
+    public static App getInstance() {
+        return instance;
+    }
+}

+ 0 - 23
app/src/main/java/me/yoqi/android/safekeyboard/MainActivity.java

@@ -16,7 +16,6 @@ import me.yoqi.android.safekeyboard.keyboard.KeyBoardDialogUtils;
 public class MainActivity extends AppCompatActivity {
     private KeyBoardDialogUtils keyBoardDialogUtils;
     private EditText et;
-    private Button btnChangeIME;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -26,14 +25,6 @@ public class MainActivity extends AppCompatActivity {
     }
 
     public void initView() {
-        btnChangeIME = findViewById(R.id.btnChangeIME);
-        btnChangeIME.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-               changeIME();
-            }
-        });
-
         et = (EditText) findViewById(R.id.et);
         keyBoardDialogUtils = new KeyBoardDialogUtils(this);
         et.setOnClickListener(new View.OnClickListener() {
@@ -43,18 +34,4 @@ public class MainActivity extends AppCompatActivity {
             }
         });
     }
-
-    public void changeIME() {
-        //1、判断是否系统启用了安全输入法没有启动者跳到设置界面
-        if (true) {
-            Intent enableIntent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS);
-            enableIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            startActivity(enableIntent);
-        } else if (false) {
-            // 2、如果设置了安全输入法,但是没有启动,则跳转到切换输入法界面:
-            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-            imm.showInputMethodPicker();
-        }
-    }
-
 }

+ 43 - 0
app/src/main/java/me/yoqi/android/safekeyboard/base/BaseActivity.java

@@ -0,0 +1,43 @@
+package me.yoqi.android.safekeyboard.base;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.content.PermissionChecker;
+
+import me.yoqi.android.safekeyboard.utils.AppManager;
+
+/**
+ * 基类
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public abstract class BaseActivity extends AppCompatActivity {
+    protected Context mContext;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(getLayoutResID());
+
+        mContext = this;
+        AppManager.getInstance().addActivity(this);
+        init();
+    }
+
+    public boolean hasPermission(String permission) {
+        boolean has = true;
+        try {
+            has = PermissionChecker.checkSelfPermission(this, permission) == PermissionChecker.PERMISSION_GRANTED;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return has;
+    }
+    protected abstract int getLayoutResID();
+    protected abstract void init();
+
+}

+ 20 - 0
app/src/main/java/me/yoqi/android/safekeyboard/base/BaseFragment.java

@@ -0,0 +1,20 @@
+package me.yoqi.android.safekeyboard.base;
+
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+/**
+ * 基类
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public class BaseFragment extends Fragment {
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+}

+ 9 - 0
app/src/main/java/me/yoqi/android/safekeyboard/model/Config.java

@@ -0,0 +1,9 @@
+package me.yoqi.android.safekeyboard.model;
+
+/**
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public class Config {
+    public static String packageName="me.yoqi.android.safekeyboard";
+}

+ 137 - 0
app/src/main/java/me/yoqi/android/safekeyboard/utils/AppManager.java

@@ -0,0 +1,137 @@
+package me.yoqi.android.safekeyboard.utils;
+
+import android.app.Activity;
+
+import java.util.Stack;
+
+/**
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public class AppManager {
+    private static Stack<Activity> activityStack;
+
+    private static class SingleHolder {
+        private static AppManager instance = new AppManager();
+    }
+
+    public static AppManager getInstance() {
+        return SingleHolder.instance;
+    }
+
+    /**
+     * 添加Activity到堆栈
+     */
+    public void addActivity(Activity activity) {
+        if (activityStack == null) {
+            activityStack = new Stack<Activity>();
+        }
+        activityStack.add(activity);
+    }
+
+    /**
+     * 是否有activity
+     */
+    public boolean isActivity() {
+        if (activityStack != null) {
+            return !activityStack.isEmpty();
+        }
+        return false;
+    }
+
+    /**
+     * 获取当前Activity(堆栈中最后一个压入的)
+     */
+    public Activity currentActivity() {
+        Activity activity = activityStack.lastElement();
+        return activity;
+    }
+
+    /**
+     * 结束当前Activity(堆栈中最后一个压入的)
+     */
+    public void finishActivity() {
+        Activity activity = activityStack.lastElement();
+        if (!activity.isFinishing()) {
+            activity.finish();
+        }
+    }
+
+    public void finishActivity(Activity activity) {
+        activityStack.remove(activity);
+    }
+
+
+    /**
+     * 结束指定类名的Activity
+     */
+    public void finishActivity(Class<?> cls) {
+        for (Activity activity : activityStack) {
+            if (activity.getClass().equals(cls)) {
+                if (!activity.isFinishing()) {
+                    activity.finish();
+                }
+                break;
+            }
+        }
+    }
+
+    /**
+     * 返回指定 Activity,当然这个Activity需要存在
+     *
+     * @param cls
+     */
+    public void backActivity(Class<?> cls) {
+        while (!activityStack.empty()) {
+            Activity activity = activityStack.pop(); // 指定activity置顶
+            if (activity.getClass().equals(cls)) {
+                activityStack.push(activity);
+                break;
+            } else {
+                activity.finish();
+            }
+        }
+    }
+
+    /**
+     * 结束所有Activity
+     */
+    public void finishAllActivity() {
+        if (activityStack != null && activityStack.size() > 0) {
+            for (int i = 0, size = activityStack.size(); i < size; i++) {
+                Activity activity = activityStack.get(i);
+                if (null != activityStack.get(i)) {
+                    if (!activity.isFinishing()) {
+                        activity.finish();
+                    }
+                }
+            }
+            activityStack.clear();
+        }
+    }
+
+    /**
+     * 获取指定的Activity
+     */
+    public Activity getActivity(Class<?> cls) {
+        if (activityStack != null) {
+            for (Activity activity : activityStack) {
+                if (activity.getClass().equals(cls)) {
+                    return activity;
+                }
+            }
+        }
+        return null;
+    }
+
+    public void appExit(int code) {
+        try {
+            finishAllActivity();
+            android.os.Process.killProcess(android.os.Process.myPid());
+            System.exit(code);
+        } catch (Exception e) {
+            activityStack.clear();
+            e.printStackTrace();
+        }
+    }
+}

+ 80 - 0
app/src/main/java/me/yoqi/android/safekeyboard/utils/IMEUtils.java

@@ -0,0 +1,80 @@
+package me.yoqi.android.safekeyboard.utils;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public class IMEUtils {
+    public String getIME(Context context) {
+        String mDefaultInputMethodPkg = null;
+        String mDefaultInputMethodCls = Settings.Secure.getString(
+                context.getContentResolver(),
+                Settings.Secure.DEFAULT_INPUT_METHOD);
+        //输入法类名信息
+        if (!TextUtils.isEmpty(mDefaultInputMethodCls)) {
+            //输入法包名
+            mDefaultInputMethodPkg = mDefaultInputMethodCls.split("/")[0];
+        }
+        return mDefaultInputMethodCls;
+    }
+
+    public ArrayList<String> getIMEList(Context context) {
+        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        List<InputMethodInfo> methodList = imm.getInputMethodList();
+        ArrayList<String> res = new ArrayList<String>();
+        for (InputMethodInfo mi : methodList) {
+            res.add(mi.getPackageName());
+        }
+        return res;
+    }
+
+
+    /**
+     * 判断输入法是否设置,有问题
+     *
+     * @param imePkg 输入法包名
+     * @return 输入法是否设置
+     */
+    public boolean isConfigIME(Context context, String imePkg) {
+        return getIMEList(context).contains(imePkg);
+    }
+
+    /**
+     * 判断输入法是否启用
+     *
+     * @param context
+     * @param imePkg
+     * @return
+     */
+    public boolean isEnableIME(Context context, String imePkg) {
+        return getDefaultInputMethodPkgName(context).equals(imePkg);
+    }
+
+    /**
+     * 获取默认输入法
+     *
+     * @param context 上下文对象
+     * @return 输入法字符串
+     */
+    public String getDefaultInputMethodPkgName(Context context) {
+        String mDefaultInputMethodPkg = null;
+        String mDefaultInputMethodCls = Settings.Secure.getString(
+                context.getContentResolver(),
+                Settings.Secure.DEFAULT_INPUT_METHOD);
+        //输入法类名信息
+        if (!TextUtils.isEmpty(mDefaultInputMethodCls)) {
+            //输入法包名
+            mDefaultInputMethodPkg = mDefaultInputMethodCls.split("/")[0];
+        }
+        return mDefaultInputMethodPkg;
+    }
+}

+ 77 - 0
app/src/main/java/me/yoqi/android/safekeyboard/view/Guide1Activity.java

@@ -0,0 +1,77 @@
+package me.yoqi.android.safekeyboard.view;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+
+import androidx.appcompat.app.AlertDialog;
+
+import me.yoqi.android.safekeyboard.MainActivity;
+import me.yoqi.android.safekeyboard.R;
+import me.yoqi.android.safekeyboard.base.BaseActivity;
+import me.yoqi.android.safekeyboard.model.Config;
+import me.yoqi.android.safekeyboard.utils.IMEUtils;
+
+/**
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public class Guide1Activity extends BaseActivity {
+    Button btnFinish, btnStep1Enable, btnStep2Enable;
+    boolean isConfigIME, isEnableIME; // 当前输入法是否启用
+
+    @Override
+    protected int getLayoutResID() {
+        return R.layout.activity_guide1;
+    }
+
+    @Override
+    protected void init() {
+        btnFinish = findViewById(R.id.btnFinish);
+        btnStep1Enable = findViewById(R.id.btnStep1Enable);
+        btnStep2Enable = findViewById(R.id.btnStep2Enable);
+
+        btnFinish.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (isConfigIME && isEnableIME) {
+                    startActivity(new Intent(Guide1Activity.this, MainActivity.class));
+                } else {
+                    new AlertDialog.Builder(mContext)
+                            .setMessage("请勾选安全输入法!")
+                            .setCancelable(false)
+                            .setPositiveButton("确定", null)
+                            .show();
+                }
+            }
+        });
+        btnStep1Enable.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent enableIntent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS);
+                enableIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivity(enableIntent);
+            }
+        });
+        btnStep2Enable.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+                imm.showInputMethodPicker();
+            }
+        });
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        IMEUtils imeUtils = new IMEUtils();
+        isConfigIME = imeUtils.isConfigIME(mContext, Config.packageName);
+        isEnableIME = imeUtils.isEnableIME(mContext, Config.packageName);
+        btnStep1Enable.setEnabled(isConfigIME);
+        btnStep2Enable.setEnabled(isEnableIME);
+    }
+}

+ 41 - 0
app/src/main/java/me/yoqi/android/safekeyboard/view/SplashActivity.java

@@ -0,0 +1,41 @@
+package me.yoqi.android.safekeyboard.view;
+
+import android.content.Intent;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+import me.yoqi.android.safekeyboard.MainActivity;
+import me.yoqi.android.safekeyboard.R;
+import me.yoqi.android.safekeyboard.base.BaseActivity;
+import me.yoqi.android.safekeyboard.model.Config;
+import me.yoqi.android.safekeyboard.utils.IMEUtils;
+
+/**
+ * @author liuyuqi.gov@msn.cn
+ * @date 3/17/2021
+ */
+public class SplashActivity extends BaseActivity {
+    TextView tvInfo;
+
+    @Override
+    protected int getLayoutResID() {
+        return R.layout.activity_splash;
+    }
+
+    @Override
+    protected void init() {
+        tvInfo = findViewById(R.id.tvInfo);
+        ArrayList<String> res = new IMEUtils().getIMEList(mContext);
+        IMEUtils imeUtils = new IMEUtils();
+        boolean isconfigIME = imeUtils.isConfigIME(mContext, Config.packageName);
+        String defaultInputMethodPkgName = imeUtils.getIME(mContext);
+
+        if (isconfigIME && defaultInputMethodPkgName.equals(Config.packageName)) {
+            //已经设置了输入法
+            startActivity(new Intent(SplashActivity.this, MainActivity.class));
+        } else {
+            startActivity(new Intent(SplashActivity.this, Guide1Activity.class));
+        }
+    }
+}

+ 92 - 0
app/src/main/res/layout/activity_guide1.xml

@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#EBEDEC">
+
+    <LinearLayout
+        android:id="@+id/linearLayout"
+        android:layout_width="match_parent"
+        android:layout_height="120dp"
+        android:layout_marginLeft="30dp"
+        android:layout_marginTop="60dp"
+        android:layout_marginRight="30dp"
+        android:background="#F8F8F8"
+        android:orientation="vertical"
+        android:padding="10dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Step 1:"
+            android:textSize="20dp" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Select SafeKeyboard IME" />
+
+        <Button
+            android:id="@+id/btnStep1Enable"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="right"
+            android:background="#D6D2D2"
+            android:text="未勾选" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/linearLayout3"
+        android:layout_width="match_parent"
+        android:layout_height="120dp"
+        android:layout_marginLeft="30dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginRight="30dp"
+        android:background="#F8F8F8"
+        android:orientation="vertical"
+        android:padding="10dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.733"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/linearLayout">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Step 2:"
+            android:textSize="20dp" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Active SafeKeyboard IME" />
+
+        <Button
+            android:id="@+id/btnStep2Enable"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="right"
+            android:background="#D6D2D2"
+            android:text="未勾选" />
+    </LinearLayout>
+
+    <Button
+        android:id="@+id/btnFinish"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:width="120dp"
+        android:text="@string/finish"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/linearLayout3" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 0 - 11
app/src/main/res/layout/activity_main.xml

@@ -6,17 +6,6 @@
     android:layout_height="match_parent"
     tools:context=".MainActivity">
 
-    <Button
-        android:id="@+id/btnChangeIME"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="51dp"
-        android:layout_marginLeft="51dp"
-        android:layout_marginTop="134dp"
-        android:text="切换输入法"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"></Button>
-
     <EditText
         android:id="@+id/et"
         android:layout_width="200dp"

+ 30 - 0
app/src/main/res/layout/activity_splash.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/textView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="196dp"
+        android:text="SefeKeyboard"
+        android:textSize="50dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/tvInfo"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:text="keep your input safe."
+        android:textSize="20dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/textView" />
+</androidx.constraintlayout.widget.ConstraintLayout>