diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fd45b12
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches/build_file_checksums.ser
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml
new file mode 100644
index 0000000..57927c5
--- /dev/null
+++ b/.idea/markdown-navigator/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..eb4e391
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..89e996d
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,43 @@
+apply plugin: 'com.android.application'
+
+android {
+ signingConfigs {
+ config {
+ keyAlias 'hongbao'
+ keyPassword '123456'
+ storeFile file('hongbao.jks')
+ storePassword '123456'
+ }
+ }
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "group.tonight.hongbao"
+ minSdkVersion 18
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0.0 alpha-1"
+ signingConfig signingConfigs.config
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ signingConfig signingConfigs.config
+ }
+ debug {
+ signingConfig signingConfigs.config
+ }
+ }
+ productFlavors {
+ }
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'com.github.zhaokaiqiang.klog:library:1.6.0'
+ //必须使用
+ implementation 'com.lzy.net:okgo:3.0.4'
+ implementation 'com.github.bumptech.glide:glide:4.8.0'
+}
diff --git a/app/hongbao.jks b/app/hongbao.jks
new file mode 100644
index 0000000..8f5442b
Binary files /dev/null and b/app/hongbao.jks differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..72cd53e
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/group/tonight/hongbao/App.java b/app/src/main/java/group/tonight/hongbao/App.java
new file mode 100644
index 0000000..4d7f799
--- /dev/null
+++ b/app/src/main/java/group/tonight/hongbao/App.java
@@ -0,0 +1,13 @@
+package group.tonight.hongbao;
+
+import android.app.Application;
+
+import com.lzy.okgo.OkGo;
+
+public class App extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ OkGo.getInstance().init(this);
+ }
+}
diff --git a/app/src/main/java/group/tonight/hongbao/HongBaoAccessibilityService.java b/app/src/main/java/group/tonight/hongbao/HongBaoAccessibilityService.java
new file mode 100644
index 0000000..89f31af
--- /dev/null
+++ b/app/src/main/java/group/tonight/hongbao/HongBaoAccessibilityService.java
@@ -0,0 +1,120 @@
+package group.tonight.hongbao;
+
+import android.accessibilityservice.AccessibilityService;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.socks.library.KLog;
+
+import java.util.List;
+
+public class HongBaoAccessibilityService extends AccessibilityService {
+ private Handler mHandler = new Handler(Looper.getMainLooper());
+ private static final String TAG = HongBaoAccessibilityService.class.getSimpleName();
+ //聊天列表
+ private static final String LAYOUT_CHAT_LIST = "com.tencent.mm.ui.LauncherUI";
+ //拆红包界面
+ private static final String LAYOUT_OPEN_RED_BAG = "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyNotHookReceiveUI";
+ //红包详情
+ private static final String LAYOUT_RED_BAG_DETAIL = "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI";
+
+ private static final String LAYOUT_UNKNOW = "com.tencent.mm.ui.base.p";
+
+ private String mCurrentActivityName;
+ private boolean mOpenningRedBag;
+
+ @Override
+ public void onAccessibilityEvent(AccessibilityEvent event) {
+ int eventType = event.getEventType();
+ CharSequence className = event.getClassName();
+ int itemCount = event.getItemCount();
+ if (className != null) {
+ if (className.toString().contains("com.tencent.mm")) {
+ KLog.e("onAccessibilityEvent: " + eventType + " " + className);
+ mCurrentActivityName = className.toString();
+ }
+ }
+
+ boolean hasRedBag = hasRedBag();
+ KLog.e("onAccessibilityEvent: 有红包--->" + hasRedBag);
+ switch (eventType) {
+ case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
+ KLog.e("onAccessibilityEvent: TYPE_WINDOW_STATE_CHANGED");
+
+ break;
+ case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
+// KLog.e( "onAccessibilityEvent: TYPE_WINDOW_CONTENT_CHANGED");
+ KLog.e("onAccessibilityEvent: 有红包--->" + hasRedBag);
+
+ if (mCurrentActivityName != null) {
+ final AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
+ switch (mCurrentActivityName) {
+ case LAYOUT_CHAT_LIST:
+ if (mOpenningRedBag) {
+ return;
+ }
+ if (hasRedBag()) {
+ List nodeInfosByViewId = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/ao4");//点开红包弹窗
+ if (!nodeInfosByViewId.isEmpty()) {
+ KLog.e("点击最后一个未拆开过的红包");
+ nodeInfosByViewId.get(nodeInfosByViewId.size() - 1).performAction(AccessibilityNodeInfo.ACTION_CLICK);
+ mOpenningRedBag = true;
+ }
+ }
+ break;
+ case LAYOUT_OPEN_RED_BAG:
+ for (AccessibilityNodeInfo nodeInfo : rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/cv0")) {//拆开红包
+ if (nodeInfo.isClickable() && nodeInfo.getClassName().equals("android.widget.Button")) {
+ nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+ KLog.e("onAccessibilityEvent: 点击拆开红包按钮");
+ break;
+ }
+ }
+ break;
+ case LAYOUT_RED_BAG_DETAIL:
+ mOpenningRedBag = false;
+ for (AccessibilityNodeInfo nodeInfo : rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/k4")) {//返回
+ if (nodeInfo.isClickable()) {
+ nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
+// KLog.e( "onAccessibilityEvent: TYPE_NOTIFICATION_STATE_CHANGED");
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ private boolean hasRedBag() {
+ AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
+ if (rootInActiveWindow == null) {
+ return false;
+ }
+ //每个聊天联系人item
+ //红包布局,包含红包图标、恭喜发财、已被领完
+ List nodeInfoList = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/ao4");
+ if (!nodeInfoList.isEmpty()) {
+ AccessibilityNodeInfo nodeInfo = nodeInfoList.get(nodeInfoList.size() - 1);//最后一个item
+
+ List infoList = nodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/ape");//已被领完
+ return infoList.isEmpty();
+ }
+ return false;
+ }
+
+ @Override
+ public void onInterrupt() {
+
+ }
+}
diff --git a/app/src/main/java/group/tonight/hongbao/MainActivity.java b/app/src/main/java/group/tonight/hongbao/MainActivity.java
new file mode 100644
index 0000000..468629d
--- /dev/null
+++ b/app/src/main/java/group/tonight/hongbao/MainActivity.java
@@ -0,0 +1,235 @@
+package group.tonight.hongbao;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.Settings;
+import android.support.v4.content.FileProvider;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import com.bumptech.glide.Glide;
+import com.lzy.okgo.OkGo;
+import com.lzy.okgo.callback.FileCallback;
+import com.lzy.okgo.callback.StringCallback;
+import com.lzy.okgo.model.Progress;
+import com.lzy.okgo.model.Response;
+import com.lzy.okgo.request.base.Request;
+import com.socks.library.KLog;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.util.Date;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ findViewById(R.id.setting).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
+ }
+ });
+ ImageView imageView = (ImageView) findViewById(R.id.qr_code);
+ Glide.with(imageView)
+ .load("http://qr.liantu.com/api.php?text=" + "https://fir.im/zr2t")
+ .into(imageView);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_main_activity, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.actioin_update) {
+ OkGo.get("https://download.fir.im/zr2t")
+ .execute(new StringCallback() {
+ @Override
+ public void onSuccess(Response response) {
+ String json = response.body();
+ try {
+ JSONObject jsonObject = new JSONObject(json);
+ JSONObject app = jsonObject.getJSONObject("app");
+ String id = app.getString("id");
+ String download_token = app.getString("token");
+
+ JSONObject master = app.getJSONObject("releases").getJSONObject("master");
+ final String release_id = master.getString("id");
+ final String version = master.getString("version");
+ final int build = master.getInt("build");
+ final String changelog = master.getString("changelog");
+ final long fsize = master.getLong("fsize");
+ final long created_at = master.getLong("created_at");
+
+ OkGo.post("https://download.fir.im/apps/" + id + "/install")
+ .params("download_token", download_token)
+ .params("release_id", release_id)
+ .execute(new StringCallback() {
+ @Override
+ public void onSuccess(Response response) {
+ String json = response.body();
+ try {
+ JSONObject jsonObject1 = new JSONObject(json);
+ final String apkUrl = jsonObject1.getString("url");
+ KLog.e("apk下载地址:" + apkUrl);
+
+ final UpdateBean updateBean = new UpdateBean();
+ updateBean.setId(release_id);
+ updateBean.setVersion(version);
+ updateBean.setBuild(build);
+ updateBean.setChangelog(changelog);
+ updateBean.setFsize(fsize);
+ updateBean.setCreated_at(created_at);
+ updateBean.setApkUrl(apkUrl);
+
+ KLog.e(updateBean.toString());
+
+
+ PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
+ String versionName = packageInfo.versionName;
+ int versionCode = packageInfo.versionCode;
+ if (versionName.equals(version) && versionCode == build) {
+ Toast.makeText(MainActivity.this, "已是最新版本", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ DecimalFormat format = new DecimalFormat("0.00");
+ double fileSize = fsize / 1024.0f / 1024.f;
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("版本号:")
+ .append(build)
+ .append("\n")
+ .append("版本名称:")
+ .append(version)
+ .append("\n")
+ .append("Apk大小:")
+ .append(format.format(fileSize) + "MB")
+ .append("\n")
+ .append("发布时间:")
+ .append("\n")
+ .append(DateFormat.getDateTimeInstance().format(new Date(created_at * 1000)))
+ .append("\n")
+ .append("\n")
+ .append("更新内容:")
+ .append("\n")
+ .append(changelog);
+
+ new AlertDialog.Builder(MainActivity.this)
+ .setTitle("发现新版本")
+ .setMessage(builder.toString())
+ .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ }
+ })
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
+ progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+
+ OkGo.get(apkUrl)
+ .execute(new FileCallback() {
+ @Override
+ public void onStart(Request request) {
+ super.onStart(request);
+ progressDialog.show();
+ }
+
+ @Override
+ public void onFinish() {
+ super.onFinish();
+ progressDialog.dismiss();
+ }
+
+ @Override
+ public void downloadProgress(Progress progress) {
+ super.downloadProgress(progress);
+ float fraction = progress.fraction;
+
+ }
+
+ @Override
+ public void onSuccess(Response response) {
+ File body = response.body();
+ KLog.e(body.getPath());
+ installApk(MainActivity.this, body.getPath());
+ }
+ });
+ }
+ })
+ .show();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ } catch (JSONException e) {
+ e.printStackTrace();
+ Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * 安装apk
+ *
+ * @param context
+ * @param apkPath
+ */
+ public static void installApk(Context context, String apkPath) {
+ try {
+ /**
+ * provider
+ * 处理android 7.0 及以上系统安装异常问题
+ */
+ File file = new File(apkPath);
+ Intent install = new Intent(Intent.ACTION_VIEW);
+ install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ Uri apkUri = FileProvider.getUriForFile(context, context.getString(R.string.file_provider_authorities), file);//在AndroidManifest中的android:authorities值
+ Log.d("======", "apkUri=" + apkUri);
+ install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件
+ install.setDataAndType(apkUri, "application/vnd.android.package-archive");
+ } else {
+ install.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
+ }
+ context.startActivity(install);
+ } catch (Exception e) {
+ e.printStackTrace();
+ Log.d("======", e.getMessage());
+ }
+ }
+}
diff --git a/app/src/main/java/group/tonight/hongbao/UpdateBean.java b/app/src/main/java/group/tonight/hongbao/UpdateBean.java
new file mode 100644
index 0000000..8f2008d
--- /dev/null
+++ b/app/src/main/java/group/tonight/hongbao/UpdateBean.java
@@ -0,0 +1,93 @@
+package group.tonight.hongbao;
+
+import java.io.Serializable;
+
+public class UpdateBean implements Serializable {
+
+ /**
+ * id : 5c2f2886548b7a7d78997185
+ * version : 1.0.0 alpha-37
+ * build : 11
+ * changelog : 修复版本更新内容显示不全的bug
+ * fsize : 7581932
+ * created_at : 1546594438
+ */
+
+ private String id;
+ private String version;
+ private long build;
+ private String changelog;
+ private long fsize;
+ private long created_at;
+
+ private String apkUrl;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public long getBuild() {
+ return build;
+ }
+
+ public void setBuild(long build) {
+ this.build = build;
+ }
+
+ public String getChangelog() {
+ return changelog;
+ }
+
+ public void setChangelog(String changelog) {
+ this.changelog = changelog;
+ }
+
+ public long getFsize() {
+ return fsize;
+ }
+
+ public void setFsize(long fsize) {
+ this.fsize = fsize;
+ }
+
+ public long getCreated_at() {
+ return created_at;
+ }
+
+ public void setCreated_at(long created_at) {
+ this.created_at = created_at;
+ }
+
+ public String getApkUrl() {
+ return apkUrl;
+ }
+
+ public void setApkUrl(String apkUrl) {
+ this.apkUrl = apkUrl;
+ }
+
+ @Override
+ public String toString() {
+ return "UpdateBean{" +
+ "id='" + id + '\'' +
+ ", version='" + version + '\'' +
+ ", build=" + build +
+ ", changelog='" + changelog + '\'' +
+ ", fsize=" + fsize +
+ ", created_at=" + created_at +
+ ", apkUrl='" + apkUrl + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..1f6bb29
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d025f9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..eaa3dac
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_main_activity.xml b/app/src/main/res/menu/menu_main_activity.xml
new file mode 100644
index 0000000..3bae7be
--- /dev/null
+++ b/app/src/main/res/menu/menu_main_activity.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed465
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..69b2233
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #008577
+ #00574B
+ #D81B60
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e4a0647
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ HongBao
+ group.tonight.hongbao.FileProvider
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/accessibility_service_config.xml b/app/src/main/res/xml/accessibility_service_config.xml
new file mode 100644
index 0000000..6386a0b
--- /dev/null
+++ b/app/src/main/res/xml/accessibility_service_config.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml
new file mode 100644
index 0000000..57374e0
--- /dev/null
+++ b/app/src/main/res/xml/filepaths.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..8d3ef8e
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,27 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.2.1'
+
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..82618ce
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,15 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9a4163a
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'