├── .gitignore ├── GameBox ├── .gitignore ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── top │ │ │ └── naccl │ │ │ └── gamebox │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── top │ │ │ │ └── naccl │ │ │ │ └── gamebox │ │ │ │ ├── activity │ │ │ │ ├── ArticleActivity.java │ │ │ │ ├── FavoriteActivity.java │ │ │ │ ├── HomeActivity.java │ │ │ │ ├── LoginActivity.java │ │ │ │ ├── MeLoginActivity.java │ │ │ │ ├── MeUpdateActivity.java │ │ │ │ ├── RegisterActivity.java │ │ │ │ └── SettingActivity.java │ │ │ │ ├── api │ │ │ │ └── ApiConfig.java │ │ │ │ ├── bean │ │ │ │ ├── Article.java │ │ │ │ ├── Comment.java │ │ │ │ ├── Image.java │ │ │ │ └── User.java │ │ │ │ ├── dao │ │ │ │ ├── ArticleDao.java │ │ │ │ ├── ImageDao.java │ │ │ │ └── UserDao.java │ │ │ │ ├── dialog │ │ │ │ └── InputTextMsgDialog.java │ │ │ │ ├── fragment │ │ │ │ ├── BaseFragment.java │ │ │ │ ├── CommunityFragment.java │ │ │ │ ├── HomeFragment.java │ │ │ │ └── MeFragment.java │ │ │ │ ├── main │ │ │ │ └── MainActivity.java │ │ │ │ ├── qrcode │ │ │ │ ├── activity │ │ │ │ │ └── CaptureActivity.java │ │ │ │ ├── camera │ │ │ │ │ ├── AutoFocusCallback.java │ │ │ │ │ ├── CameraConfigurationManager.java │ │ │ │ │ ├── CameraManager.java │ │ │ │ │ ├── FlashlightManager.java │ │ │ │ │ ├── PlanarYUVLuminanceSource.java │ │ │ │ │ └── PreviewCallback.java │ │ │ │ ├── decoding │ │ │ │ │ ├── CaptureActivityHandler.java │ │ │ │ │ ├── DecodeFormatManager.java │ │ │ │ │ ├── DecodeHandler.java │ │ │ │ │ ├── DecodeThread.java │ │ │ │ │ ├── FinishListener.java │ │ │ │ │ ├── InactivityTimer.java │ │ │ │ │ ├── Intents.java │ │ │ │ │ └── RGBLuminanceSource.java │ │ │ │ ├── encoding │ │ │ │ │ └── EncodingHandler.java │ │ │ │ └── view │ │ │ │ │ ├── ViewfinderResultPointCallback.java │ │ │ │ │ └── ViewfinderView.java │ │ │ │ ├── service │ │ │ │ ├── ArticleService.java │ │ │ │ ├── ImageService.java │ │ │ │ ├── UserService.java │ │ │ │ └── impl │ │ │ │ │ ├── ArticleServiceImpl.java │ │ │ │ │ ├── ImageServiceImpl.java │ │ │ │ │ └── UserServiceImpl.java │ │ │ │ └── util │ │ │ │ ├── Base64Utils.java │ │ │ │ ├── BitmapUtil.java │ │ │ │ ├── Constant.java │ │ │ │ ├── DBUtils.java │ │ │ │ ├── HtmlUtils.java │ │ │ │ ├── ImageUtils.java │ │ │ │ ├── MD5Utils.java │ │ │ │ ├── OkHttpUtils.java │ │ │ │ ├── RoundImageView.java │ │ │ │ └── ToastUtils.java │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ ├── abc_ic_menu_moreoverflow_mtrl_alpha.png │ │ │ ├── active_nor.png │ │ │ ├── arrow_go_back.png │ │ │ ├── arrow_right.png │ │ │ ├── avatar_login_default.png │ │ │ ├── avatar_logout.png │ │ │ ├── btn_back.png │ │ │ ├── chuapp.png │ │ │ ├── community.xml │ │ │ ├── eye.png │ │ │ ├── flash_off.png │ │ │ ├── flash_on.png │ │ │ ├── home.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ic_search_black_24dp.xml │ │ │ ├── icon_article_add.png │ │ │ ├── icon_article_favorite.png │ │ │ ├── icon_article_good.png │ │ │ ├── icon_article_message.png │ │ │ ├── icon_community_find.png │ │ │ ├── icon_community_game.png │ │ │ ├── icon_community_nor.png │ │ │ ├── icon_community_sel.png │ │ │ ├── icon_home_nor.png │ │ │ ├── icon_home_sel.png │ │ │ ├── icon_information_save.png │ │ │ ├── icon_me_nor.png │ │ │ ├── icon_me_sel.png │ │ │ ├── me.xml │ │ │ ├── message.png │ │ │ ├── scan.png │ │ │ ├── scrollimg1.png │ │ │ ├── scrollimg2.png │ │ │ ├── setting.png │ │ │ ├── shape.xml │ │ │ ├── shape_add.xml │ │ │ └── textcolor.xml │ │ │ ├── layout │ │ │ ├── activity_article.xml │ │ │ ├── activity_bottom_navigation_bar.xml │ │ │ ├── activity_favorite.xml │ │ │ ├── activity_login.xml │ │ │ ├── activity_me_update.xml │ │ │ ├── activity_register.xml │ │ │ ├── activity_scanner.xml │ │ │ ├── activity_setting.xml │ │ │ ├── comment_item.xml │ │ │ ├── dialog_input_text_msg.xml │ │ │ ├── fragment_community.xml │ │ │ ├── fragment_home.xml │ │ │ ├── fragment_me.xml │ │ │ ├── message_action_view.xml │ │ │ ├── recycleview_item.xml │ │ │ ├── recycleview_item_image.xml │ │ │ ├── scan_action_view.xml │ │ │ ├── setting_action_view.xml │ │ │ ├── toolbar_main.xml │ │ │ └── toolbar_scanner.xml │ │ │ ├── menu │ │ │ ├── community.xml │ │ │ ├── information_save.xml │ │ │ ├── nologin_setting.xml │ │ │ ├── scanner_menu.xml │ │ │ └── setting.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── raw │ │ │ └── beep.ogg │ │ │ └── values │ │ │ ├── attr.xml │ │ │ ├── attrs.xml │ │ │ ├── colors.xml │ │ │ ├── ids.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── top │ │ └── naccl │ │ └── gamebox │ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── LICENSE ├── README.md ├── SpiderForChuApp.py ├── android-api ├── pom.xml └── src │ ├── main │ ├── java │ │ └── top │ │ │ └── naccl │ │ │ ├── AndroidApiApplication.java │ │ │ ├── controller │ │ │ ├── ArticleController.java │ │ │ ├── FavoriteController.java │ │ │ ├── LoginController.java │ │ │ ├── RegisterController.java │ │ │ └── UserController.java │ │ │ ├── exception │ │ │ ├── BadRequestException.java │ │ │ ├── NotFoundException.java │ │ │ └── PersistenceException.java │ │ │ ├── handler │ │ │ └── ControllerExceptionHandler.java │ │ │ ├── mapper │ │ │ ├── ArticleMapper.java │ │ │ ├── CommentMapper.java │ │ │ ├── FavoriteMapper.java │ │ │ └── UserMapper.java │ │ │ ├── model │ │ │ ├── entity │ │ │ │ ├── Article.java │ │ │ │ ├── Comment.java │ │ │ │ ├── Favorite.java │ │ │ │ └── User.java │ │ │ └── vo │ │ │ │ ├── Comment.java │ │ │ │ └── Result.java │ │ │ ├── service │ │ │ ├── ArticleService.java │ │ │ ├── CommentService.java │ │ │ ├── FavoriteService.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ ├── ArticleServiceImpl.java │ │ │ │ ├── CommentServiceImpl.java │ │ │ │ ├── FavoriteServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── util │ │ │ ├── JwtUtils.java │ │ │ └── MD5Utils.java │ └── resources │ │ ├── application-dev.properties │ │ ├── application.properties │ │ ├── logback-spring.xml │ │ └── mapper │ │ ├── ArticleMapper.xml │ │ ├── CommentMapper.xml │ │ ├── FavoriteMapper.xml │ │ └── UserMapper.xml │ └── test │ └── java │ └── top │ └── naccl │ └── AndroidApiApplicationTests.java ├── gamebox.sql ├── image ├── gamebox.png ├── 修改资料.png ├── 我的.png ├── 扫描二维码.png ├── 收藏夹.png ├── 文章1.png ├── 文章2.png ├── 登录.png ├── 设置.png ├── 评论.png ├── 静态页.png └── 首页.png └── 原型 ├── GameBox.zip └── GameBoxSnapshoot.zip /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | 35 | log -------------------------------------------------------------------------------- /GameBox/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /GameBox/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /GameBox/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 30 5 | buildToolsVersion "30.0.2" 6 | 7 | defaultConfig { 8 | applicationId "top.naccl.gamebox" 9 | minSdkVersion 24 10 | targetSdkVersion 30 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | compileOptions { 24 | sourceCompatibility JavaVersion.VERSION_1_8 25 | targetCompatibility JavaVersion.VERSION_1_8 26 | } 27 | } 28 | 29 | dependencies { 30 | implementation fileTree(dir: "libs", include: ["*.jar"]) 31 | implementation 'androidx.appcompat:appcompat:1.2.0' 32 | implementation 'androidx.constraintlayout:constraintlayout:2.0.2' 33 | testImplementation 'junit:junit:4.12' 34 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 35 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 36 | 37 | implementation 'com.squareup.okhttp3:okhttp:4.7.2' 38 | implementation 'com.alibaba:fastjson:1.2.68' 39 | implementation 'androidx.recyclerview:recyclerview:1.1.0' 40 | implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha02' 41 | implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.3' 42 | implementation 'com.google.zxing:core:3.3.0' 43 | 44 | } -------------------------------------------------------------------------------- /GameBox/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /GameBox/app/src/androidTest/java/top/naccl/gamebox/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("top.naccl.gamebox", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /GameBox/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/activity/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.activity; 2 | 3 | import android.content.Intent; 4 | import android.content.SharedPreferences; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.EditText; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import androidx.appcompat.app.AppCompatActivity; 13 | 14 | import com.alibaba.fastjson.JSON; 15 | import com.alibaba.fastjson.JSONObject; 16 | 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | import java.io.IOException; 20 | 21 | import okhttp3.Call; 22 | import okhttp3.Callback; 23 | import okhttp3.FormBody; 24 | import okhttp3.RequestBody; 25 | import okhttp3.Response; 26 | import top.naccl.gamebox.R; 27 | import top.naccl.gamebox.api.ApiConfig; 28 | import top.naccl.gamebox.bean.User; 29 | import top.naccl.gamebox.main.MainActivity; 30 | import top.naccl.gamebox.service.UserService; 31 | import top.naccl.gamebox.service.impl.UserServiceImpl; 32 | import top.naccl.gamebox.util.OkHttpUtils; 33 | import top.naccl.gamebox.util.ToastUtils; 34 | 35 | public class LoginActivity extends AppCompatActivity { 36 | private UserService userService = new UserServiceImpl(this); 37 | private EditText username_et; 38 | private EditText password_et; 39 | private Button login_btn; 40 | private TextView register_text; 41 | private ImageView imageView; 42 | 43 | @Override 44 | protected void onCreate(Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | setContentView(R.layout.activity_login); 47 | 48 | imageView = findViewById(R.id.button_return); 49 | imageView.setOnClickListener(new View.OnClickListener() { 50 | @Override 51 | public void onClick(View v) { 52 | Intent intent = new Intent(LoginActivity.this, MainActivity.class); 53 | startActivity(intent); 54 | } 55 | }); 56 | 57 | login_btn = findViewById(R.id.button_login); 58 | username_et = findViewById(R.id.editText_username); 59 | password_et = findViewById(R.id.editText_password); 60 | login_btn.setOnClickListener(loginButtonListener); 61 | register_text = findViewById(R.id.register); 62 | register_text.setOnClickListener(new View.OnClickListener() { 63 | @Override 64 | public void onClick(View v) { 65 | Intent intent = new Intent(LoginActivity.this, RegisterActivity.class); 66 | startActivity(intent); 67 | } 68 | }); 69 | } 70 | 71 | View.OnClickListener loginButtonListener = new View.OnClickListener() { 72 | @Override 73 | public void onClick(View v) { 74 | String username = username_et.getText().toString(); 75 | String password = password_et.getText().toString(); 76 | if (checkEditText(username, password)) { 77 | postLogin(username, password); 78 | } 79 | } 80 | }; 81 | 82 | private boolean checkEditText(String username, String password) { 83 | if (username.length() < 3 || username.length() > 10) { 84 | ToastUtils.showToast(LoginActivity.this, "用户名长度为3-10个字符!"); 85 | return false; 86 | } 87 | if (password.length() < 6 || password.length() > 16) { 88 | ToastUtils.showToast(LoginActivity.this, "密码长度为6-16个字符!"); 89 | return false; 90 | } 91 | return true; 92 | } 93 | 94 | private void postLogin(final String username, final String password) { 95 | RequestBody requestBody = new FormBody.Builder() 96 | .add("username", username) 97 | .add("password", password) 98 | .build(); 99 | OkHttpUtils.postRequest(ApiConfig.LOGIN_URL, requestBody, new Callback() { 100 | @Override 101 | public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { 102 | final String result = response.body().string(); 103 | JSONObject jsonResult = JSON.parseObject(result); 104 | int code = jsonResult.getInteger("code"); 105 | String msg = jsonResult.getString("msg"); 106 | JSONObject data = jsonResult.getJSONObject("data"); 107 | ToastUtils.showToast(LoginActivity.this, msg); 108 | if (code == 200) {//登录验证正确 109 | SharedPreferences.Editor editor = getSharedPreferences("jwt", MODE_PRIVATE).edit(); 110 | editor.putString("token", data.getString("token")); 111 | editor.commit(); 112 | final User user = JSON.parseObject(data.getString("user"), User.class); 113 | try { 114 | boolean res = userService.saveUser(user); 115 | if (res) { 116 | Intent intent = new Intent(LoginActivity.this, MainActivity.class); 117 | startActivity(intent); 118 | } else { 119 | userService.deleteUser(); 120 | userService.saveUser(user); 121 | } 122 | } catch (Exception e) { 123 | //已登录状态 主键约束导致存储失败 124 | } 125 | } 126 | } 127 | 128 | @Override 129 | public void onFailure(@NotNull Call call, @NotNull IOException e) { 130 | ToastUtils.showToast(LoginActivity.this, "请求失败"); 131 | } 132 | }); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/activity/MeLoginActivity.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.view.MenuItem; 6 | import android.widget.ImageView; 7 | 8 | import androidx.appcompat.app.AppCompatActivity; 9 | import androidx.appcompat.widget.Toolbar; 10 | 11 | import top.naccl.gamebox.R; 12 | 13 | public class MeLoginActivity extends AppCompatActivity { 14 | private Toolbar toolbar; 15 | private ImageView messageActionView; 16 | private ImageView scanActionView; 17 | private ImageView settingActionView; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.fragment_me); 23 | 24 | toolbar = findViewById(R.id.toolbar_me); 25 | messageActionView = findViewById(R.id.message_action_view); 26 | scanActionView = findViewById(R.id.scan_action_view); 27 | settingActionView = findViewById(R.id.setting_action_view); 28 | 29 | toolbar.inflateMenu(R.menu.setting); 30 | toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { 31 | @Override 32 | public boolean onMenuItemClick(MenuItem item) { 33 | switch (item.getItemId()){ 34 | case R.id.menu_scan: 35 | break; 36 | case R.id.menu_setting: 37 | Intent intent = new Intent(MeLoginActivity.this, SettingActivity.class); 38 | startActivity(intent); 39 | break; 40 | case R.id.menu_message: 41 | break; 42 | } 43 | return true; 44 | } 45 | }); 46 | 47 | toolbar.getMenu().findItem(R.id.menu_message).setActionView(messageActionView); 48 | // messageActionView.setOnClickListener(new View.OnClickListener() { 49 | // @Override 50 | // public void onClick(View v) { 51 | // } 52 | // }); 53 | 54 | toolbar.getMenu().findItem(R.id.menu_scan).setActionView(scanActionView); 55 | // scanActionView.setOnClickListener(new View.OnClickListener() { 56 | // @Override 57 | // public void onClick(View v) { 58 | // } 59 | // }); 60 | 61 | toolbar.getMenu().findItem(R.id.menu_setting).setActionView(settingActionView); 62 | // settingActionView.setOnClickListener(new View.OnClickListener() { 63 | // @Override 64 | // public void onClick(View v) { 65 | // Intent intent = new Intent(MeLoginActivity.this, SettingActivity.class); 66 | // startActivity(intent); 67 | // } 68 | // }); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/activity/RegisterActivity.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.activity; 2 | 3 | import android.content.Intent; 4 | import android.content.SharedPreferences; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.EditText; 9 | 10 | import androidx.appcompat.app.AppCompatActivity; 11 | 12 | import com.alibaba.fastjson.JSON; 13 | import com.alibaba.fastjson.JSONObject; 14 | 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | import java.io.IOException; 18 | 19 | import okhttp3.Call; 20 | import okhttp3.Callback; 21 | import okhttp3.FormBody; 22 | import okhttp3.RequestBody; 23 | import okhttp3.Response; 24 | import top.naccl.gamebox.R; 25 | import top.naccl.gamebox.api.ApiConfig; 26 | import top.naccl.gamebox.bean.User; 27 | import top.naccl.gamebox.main.MainActivity; 28 | import top.naccl.gamebox.service.UserService; 29 | import top.naccl.gamebox.service.impl.UserServiceImpl; 30 | import top.naccl.gamebox.util.OkHttpUtils; 31 | import top.naccl.gamebox.util.ToastUtils; 32 | 33 | public class RegisterActivity extends AppCompatActivity { 34 | UserService userService = new UserServiceImpl(this); 35 | private EditText username_et; 36 | private EditText password_et; 37 | private Button register_btn; 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_register); 43 | 44 | register_btn = findViewById(R.id.button_register); 45 | username_et = findViewById(R.id.editText_username); 46 | password_et = findViewById(R.id.editText_password); 47 | register_btn.setOnClickListener(registerButtonListener); 48 | } 49 | 50 | View.OnClickListener registerButtonListener = new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | String username = username_et.getText().toString(); 54 | String password = password_et.getText().toString(); 55 | if (checkEditText(username, password)) { 56 | postRegister(username, password); 57 | } 58 | } 59 | }; 60 | 61 | private boolean checkEditText(String username, String password) { 62 | if (username.length() < 3 || username.length() > 10) { 63 | ToastUtils.showToast(RegisterActivity.this, "用户名长度为3-10个字符!"); 64 | return false; 65 | } 66 | if (password.length() < 6 || password.length() > 16) { 67 | ToastUtils.showToast(RegisterActivity.this, "密码长度为6-16个字符!"); 68 | return false; 69 | } 70 | return true; 71 | } 72 | 73 | private void postRegister(String username, String password) { 74 | RequestBody requestBody = new FormBody.Builder() 75 | .add("username", username) 76 | .add("password", password) 77 | .build(); 78 | OkHttpUtils.postRequest(ApiConfig.REGISTER_URL, requestBody, new Callback() { 79 | @Override 80 | public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { 81 | final String result = response.body().string(); 82 | JSONObject jsonResult = JSON.parseObject(result); 83 | int code = jsonResult.getInteger("code"); 84 | String msg = jsonResult.getString("msg"); 85 | JSONObject data = jsonResult.getJSONObject("data"); 86 | ToastUtils.showToast(RegisterActivity.this, msg); 87 | if (code == 200) {//注册成功 88 | SharedPreferences.Editor editor = getSharedPreferences("jwt", MODE_PRIVATE).edit(); 89 | editor.putString("token", data.getString("token")); 90 | editor.commit(); 91 | final User user = JSON.parseObject(data.getString("user"), User.class); 92 | try { 93 | boolean res = userService.saveUser(user); 94 | if (res) { 95 | Intent intent = new Intent(RegisterActivity.this, MainActivity.class); 96 | startActivity(intent); 97 | } else { 98 | userService.deleteUser(); 99 | userService.saveUser(user); 100 | } 101 | } catch (Exception e) { 102 | //已登录状态 主键约束导致存储失败 103 | } 104 | } 105 | } 106 | 107 | @Override 108 | public void onFailure(@NotNull Call call, @NotNull IOException e) { 109 | ToastUtils.showToast(RegisterActivity.this, "请求失败"); 110 | } 111 | }); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/activity/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.activity; 2 | 3 | import android.content.Intent; 4 | import android.graphics.Bitmap; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | 11 | import androidx.appcompat.app.AppCompatActivity; 12 | import androidx.appcompat.widget.Toolbar; 13 | import androidx.constraintlayout.widget.ConstraintLayout; 14 | 15 | import top.naccl.gamebox.R; 16 | import top.naccl.gamebox.bean.User; 17 | import top.naccl.gamebox.service.UserService; 18 | import top.naccl.gamebox.service.impl.UserServiceImpl; 19 | import top.naccl.gamebox.util.Base64Utils; 20 | import top.naccl.gamebox.util.ToastUtils; 21 | 22 | 23 | public class SettingActivity extends AppCompatActivity { 24 | UserService userService = new UserServiceImpl(this); 25 | private ConstraintLayout layout_update; 26 | private ImageView avatar_iv; 27 | private TextView username_tv; 28 | private TextView id_tv; 29 | private Button logout_btn; 30 | private Toolbar toolbar; 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_setting); 36 | 37 | toolbar = findViewById(R.id.toolbar_article); 38 | setSupportActionBar(toolbar); 39 | toolbar.setNavigationOnClickListener(view -> finish()); 40 | 41 | layout_update = findViewById(R.id.layout_update); 42 | avatar_iv = findViewById(R.id.imageView_avatar); 43 | username_tv = findViewById(R.id.textView_username); 44 | id_tv = findViewById(R.id.textView_id); 45 | logout_btn = findViewById(R.id.button_logout); 46 | initUserData(); 47 | } 48 | 49 | private void initUserData() { 50 | User user = userService.getUser(); 51 | if (user != null) { 52 | username_tv.setText(user.getUsername()); 53 | id_tv.setText("ID:" + user.getId()); 54 | if (user.getAvatar() != null) { 55 | Bitmap bitmap = Base64Utils.base64ToBitmap(user.getAvatar()); 56 | if (bitmap != null) { 57 | avatar_iv.setImageBitmap(bitmap); 58 | } else { 59 | avatar_iv.setImageResource(R.drawable.avatar_login_default); 60 | } 61 | } else { 62 | avatar_iv.setImageResource(R.drawable.avatar_login_default); 63 | } 64 | //用户登录状态才能修改资料、退出登录 65 | layout_update.setOnClickListener(updateLayoutListener); 66 | logout_btn.setEnabled(true); 67 | logout_btn.setOnClickListener(logoutButtonListener); 68 | } else { 69 | username_tv.setText("请登录"); 70 | id_tv.setText("ID:00000"); 71 | avatar_iv.setImageResource(R.drawable.avatar_login_default); 72 | } 73 | } 74 | 75 | View.OnClickListener updateLayoutListener = new View.OnClickListener() { 76 | @Override 77 | public void onClick(View v) { 78 | //跳转修改资料页面 79 | Intent intent = new Intent(SettingActivity.this, MeUpdateActivity.class); 80 | startActivity(intent); 81 | } 82 | }; 83 | 84 | View.OnClickListener logoutButtonListener = new View.OnClickListener() { 85 | @Override 86 | public void onClick(View v) { 87 | if (userService.deleteUser()) { 88 | ToastUtils.showToast(SettingActivity.this, "退出成功"); 89 | //跳转 me_logout 页面 90 | Intent intent = new Intent(SettingActivity.this, LoginActivity.class); 91 | startActivity(intent); 92 | } else { 93 | ToastUtils.showToast(SettingActivity.this, "退出失败,请重试"); 94 | } 95 | } 96 | }; 97 | } 98 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/api/ApiConfig.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.api; 2 | 3 | public class ApiConfig { 4 | public static final String SERVER_URL = "http://10.0.2.2:8080/"; 5 | public static final String ARTICLE_LIST_URL = SERVER_URL + "article/list/"; 6 | public static final String ARTICLE_URL = SERVER_URL + "article/"; 7 | public static final String ARTICLE_STAR_URL = SERVER_URL + "article/star/"; 8 | public static final String ARTICLE_UPDATE_VIEW_URL = SERVER_URL + "article/view/"; 9 | public static final String FAVORITE_URL = SERVER_URL + "favorite/"; 10 | public static final String FAVORITE_LIST_URL = SERVER_URL + "favorite/list"; 11 | public static final String FAVORITE_NUM_URL = SERVER_URL + "favorite/num"; 12 | public static final String LOGIN_URL = SERVER_URL + "login"; 13 | public static final String REGISTER_URL = SERVER_URL + "register"; 14 | public static final String UPDATE_USER_URL = SERVER_URL + "user/update"; 15 | public static final String COMMENT_LIST_URL = SERVER_URL + "article/comment/"; 16 | public static final String COMMENT_POST_URL = SERVER_URL + "article/comment/"; 17 | } 18 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/bean/Article.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.bean; 2 | 3 | 4 | public class Article { 5 | private Long id; 6 | private String title; 7 | private String author; 8 | private String date; 9 | private String description; 10 | private String firstPicture; 11 | private String content; 12 | private Integer star; 13 | private Integer views; 14 | 15 | public Article() { 16 | } 17 | 18 | public Long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getTitle() { 27 | return title; 28 | } 29 | 30 | public void setTitle(String title) { 31 | this.title = title; 32 | } 33 | 34 | public String getAuthor() { 35 | return author; 36 | } 37 | 38 | public void setAuthor(String author) { 39 | this.author = author; 40 | } 41 | 42 | public String getDate() { 43 | return date; 44 | } 45 | 46 | public void setDate(String date) { 47 | this.date = date; 48 | } 49 | 50 | public String getDescription() { 51 | return description; 52 | } 53 | 54 | public void setDescription(String description) { 55 | this.description = description; 56 | } 57 | 58 | public String getFirstPicture() { 59 | return firstPicture; 60 | } 61 | 62 | public void setFirstPicture(String firstPicture) { 63 | this.firstPicture = firstPicture; 64 | } 65 | 66 | public String getContent() { 67 | return content; 68 | } 69 | 70 | public void setContent(String content) { 71 | this.content = content; 72 | } 73 | 74 | public Integer getStar() { 75 | return star; 76 | } 77 | 78 | public void setStar(Integer star) { 79 | this.star = star; 80 | } 81 | 82 | public Integer getViews() { 83 | return views; 84 | } 85 | 86 | public void setViews(Integer views) { 87 | this.views = views; 88 | } 89 | 90 | @Override 91 | public String toString() { 92 | return "Article{" + 93 | "id=" + id + 94 | ", title='" + title + '\'' + 95 | ", author='" + author + '\'' + 96 | ", date='" + date + '\'' + 97 | ", description='" + description + '\'' + 98 | ", firstPicture='" + firstPicture + '\'' + 99 | ", content='" + content + '\'' + 100 | ", star=" + star + 101 | ", views=" + views + 102 | '}'; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/bean/Comment.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.bean; 2 | 3 | import java.util.Date; 4 | 5 | public class Comment { 6 | private String username; 7 | private String content; 8 | private Date createTime; 9 | private String avatar; 10 | 11 | public String getUsername() { 12 | return username; 13 | } 14 | 15 | public void setUsername(String username) { 16 | this.username = username; 17 | } 18 | 19 | public String getContent() { 20 | return content; 21 | } 22 | 23 | public void setContent(String content) { 24 | this.content = content; 25 | } 26 | 27 | public Date getCreateTime() { 28 | return createTime; 29 | } 30 | 31 | public void setCreateTime(Date createTime) { 32 | this.createTime = createTime; 33 | } 34 | 35 | public String getAvatar() { 36 | return avatar; 37 | } 38 | 39 | public void setAvatar(String avatar) { 40 | this.avatar = avatar; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Comment{" + 46 | "username='" + username + '\'' + 47 | ", content='" + content + '\'' + 48 | ", createTime='" + createTime + '\'' + 49 | ", avatar='" + avatar + '\'' + 50 | '}'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/bean/Image.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.bean; 2 | 3 | 4 | public class Image { 5 | private String url; 6 | private String base64; 7 | 8 | public Image() { 9 | } 10 | 11 | public String getUrl() { 12 | return url; 13 | } 14 | 15 | public void setUrl(String url) { 16 | this.url = url; 17 | } 18 | 19 | public String getBase64() { 20 | return base64; 21 | } 22 | 23 | public void setBase64(String base64) { 24 | this.base64 = base64; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return "Image{" + 30 | "url='" + url + '\'' + 31 | ", base64='" + base64 + '\'' + 32 | '}'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/bean/User.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.bean; 2 | 3 | public class User { 4 | private Long id; 5 | private String username; 6 | private String password; 7 | private String avatar; 8 | private String introduction; 9 | private String sex; 10 | private String email; 11 | private String education; 12 | private String job; 13 | private String birthday; 14 | 15 | public User() { 16 | } 17 | 18 | public Long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getUsername() { 27 | return username; 28 | } 29 | 30 | public void setUsername(String username) { 31 | this.username = username; 32 | } 33 | 34 | public String getPassword() { 35 | return password; 36 | } 37 | 38 | public void setPassword(String password) { 39 | this.password = password; 40 | } 41 | 42 | public String getAvatar() { 43 | return avatar; 44 | } 45 | 46 | public void setAvatar(String avatar) { 47 | this.avatar = avatar; 48 | } 49 | 50 | public String getIntroduction() { 51 | return introduction; 52 | } 53 | 54 | public void setIntroduction(String introduction) { 55 | this.introduction = introduction; 56 | } 57 | 58 | public String getSex() { 59 | return sex; 60 | } 61 | 62 | public void setSex(String sex) { 63 | this.sex = sex; 64 | } 65 | 66 | public String getEmail() { 67 | return email; 68 | } 69 | 70 | public void setEmail(String email) { 71 | this.email = email; 72 | } 73 | 74 | public String getEducation() { 75 | return education; 76 | } 77 | 78 | public void setEducation(String education) { 79 | this.education = education; 80 | } 81 | 82 | public String getJob() { 83 | return job; 84 | } 85 | 86 | public void setJob(String job) { 87 | this.job = job; 88 | } 89 | 90 | public String getBirthday() { 91 | return birthday; 92 | } 93 | 94 | public void setBirthday(String birthday) { 95 | this.birthday = birthday; 96 | } 97 | 98 | @Override 99 | public String toString() { 100 | return "User{" + 101 | "id=" + id + 102 | ", username='" + username + '\'' + 103 | ", password='" + password + '\'' + 104 | ", avatar='" + avatar + '\'' + 105 | ", introduction='" + introduction + '\'' + 106 | ", sex='" + sex + '\'' + 107 | ", email='" + email + '\'' + 108 | ", education='" + education + '\'' + 109 | ", job='" + job + '\'' + 110 | ", birthday='" + birthday + '\'' + 111 | '}'; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/dao/ArticleDao.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.dao; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | 6 | import top.naccl.gamebox.bean.Article; 7 | import top.naccl.gamebox.util.DBUtils; 8 | 9 | public class ArticleDao extends DBUtils { 10 | private static final String TABLE = "article"; 11 | private static final String TABLE_CREATE = "create table article(_id integer primary key, title text, author text, date text, description text, firstPicture text, content text, star integer, views integer);"; 12 | 13 | public ArticleDao(Context context) { 14 | super(context, TABLE, TABLE_CREATE); 15 | } 16 | 17 | @Override 18 | public Article[] ConvertToObject(Cursor cursor) { 19 | int resultCounts = cursor.getCount(); 20 | if (resultCounts == 0 || !cursor.moveToFirst()) { 21 | return null; 22 | } 23 | Article[] articles = new Article[resultCounts]; 24 | for (int i = 0; i < resultCounts; i++) { 25 | articles[i] = new Article(); 26 | articles[i].setId(cursor.getLong(0)); 27 | articles[i].setTitle(cursor.getString(cursor.getColumnIndex("title"))); 28 | articles[i].setAuthor(cursor.getString(cursor.getColumnIndex("author"))); 29 | articles[i].setDate(cursor.getString(cursor.getColumnIndex("date"))); 30 | articles[i].setDescription(cursor.getString(cursor.getColumnIndex("description"))); 31 | articles[i].setFirstPicture(cursor.getString(cursor.getColumnIndex("firstPicture"))); 32 | articles[i].setContent(cursor.getString(cursor.getColumnIndex("content"))); 33 | articles[i].setStar(cursor.getInt(cursor.getColumnIndex("star"))); 34 | articles[i].setViews(cursor.getInt(cursor.getColumnIndex("views"))); 35 | cursor.moveToNext(); 36 | } 37 | return articles; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/dao/ImageDao.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.dao; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | 6 | import top.naccl.gamebox.bean.Image; 7 | import top.naccl.gamebox.util.DBUtils; 8 | 9 | public class ImageDao extends DBUtils { 10 | private static final String TABLE = "image"; 11 | private static final String TABLE_CREATE = "create table image(url text not null, base64 text not null);"; 12 | 13 | public ImageDao(Context context) { 14 | super(context, TABLE, TABLE_CREATE); 15 | } 16 | 17 | @Override 18 | public Image[] ConvertToObject(Cursor cursor) { 19 | int resultCounts = cursor.getCount(); 20 | if (resultCounts == 0 || !cursor.moveToFirst()) { 21 | return null; 22 | } 23 | Image[] images = new Image[resultCounts]; 24 | for (int i = 0; i < resultCounts; i++) { 25 | images[i] = new Image(); 26 | images[i].setUrl(cursor.getString(cursor.getColumnIndex("url"))); 27 | images[i].setBase64(cursor.getString(cursor.getColumnIndex("base64"))); 28 | cursor.moveToNext(); 29 | } 30 | return images; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.dao; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | 6 | import top.naccl.gamebox.bean.User; 7 | import top.naccl.gamebox.util.DBUtils; 8 | 9 | 10 | public class UserDao extends DBUtils { 11 | private static final String TABLE = "user"; 12 | private static final String TABLE_CREATE = "create table user(_id integer primary key autoincrement, username text not null, password text, avatar text, introduction text, sex text, email text, education text, job text, birthday text);"; 13 | 14 | public UserDao(Context context) { 15 | super(context, TABLE, TABLE_CREATE); 16 | } 17 | 18 | @Override 19 | public User[] ConvertToObject(Cursor cursor) { 20 | int resultCounts = cursor.getCount(); 21 | if (resultCounts == 0 || !cursor.moveToFirst()) { 22 | return null; 23 | } 24 | User[] users = new User[resultCounts]; 25 | for (int i = 0; i < resultCounts; i++) { 26 | users[i] = new User(); 27 | users[i].setId(cursor.getLong(0)); 28 | users[i].setUsername(cursor.getString(cursor.getColumnIndex("username"))); 29 | users[i].setPassword(cursor.getString(cursor.getColumnIndex("password"))); 30 | users[i].setAvatar(cursor.getString(cursor.getColumnIndex("avatar"))); 31 | users[i].setIntroduction(cursor.getString(cursor.getColumnIndex("introduction"))); 32 | users[i].setSex(cursor.getString(cursor.getColumnIndex("sex"))); 33 | users[i].setEmail(cursor.getString(cursor.getColumnIndex("email"))); 34 | users[i].setEducation(cursor.getString(cursor.getColumnIndex("education"))); 35 | users[i].setJob(cursor.getString(cursor.getColumnIndex("job"))); 36 | users[i].setBirthday(cursor.getString(cursor.getColumnIndex("birthday"))); 37 | cursor.moveToNext(); 38 | } 39 | return users; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/dialog/InputTextMsgDialog.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.dialog; 2 | 3 | import android.content.Context; 4 | import android.content.DialogInterface; 5 | import android.graphics.Rect; 6 | import android.text.TextUtils; 7 | import android.view.Gravity; 8 | import android.view.KeyEvent; 9 | import android.view.View; 10 | import android.view.WindowManager; 11 | import android.view.inputmethod.InputMethodManager; 12 | import android.widget.EditText; 13 | import android.widget.LinearLayout; 14 | import android.widget.RelativeLayout; 15 | import android.widget.TextView; 16 | 17 | import androidx.annotation.NonNull; 18 | import androidx.appcompat.app.AppCompatDialog; 19 | 20 | import top.naccl.gamebox.R; 21 | 22 | public class InputTextMsgDialog extends AppCompatDialog { 23 | private Context mContext; 24 | private InputMethodManager imm; 25 | private EditText messageTextView; 26 | private TextView confirmBtn; 27 | private RelativeLayout rlDlg; 28 | private int mLastDiff = 0; 29 | private OnTextSendListener onTextSendListener; 30 | private TextView textView; 31 | 32 | public InputTextMsgDialog(@NonNull Context context, int theme, TextView textView) { 33 | super(context, theme); 34 | this.mContext = context; 35 | this.textView = textView; 36 | init(); 37 | setLayout(); 38 | } 39 | 40 | public interface OnTextSendListener { 41 | void onTextSend(String msg); 42 | } 43 | 44 | public void setOnTextSendListener(OnTextSendListener onTextSendListener) { 45 | this.onTextSendListener = onTextSendListener; 46 | } 47 | 48 | @Override 49 | public void show() { 50 | super.show(); 51 | } 52 | 53 | @Override 54 | public void dismiss() { 55 | super.dismiss(); 56 | textView.setVisibility(View.VISIBLE); 57 | //dismiss之前重置mLastDiff值避免下次无法打开 58 | mLastDiff = 0; 59 | } 60 | 61 | private void init() { 62 | setContentView(R.layout.dialog_input_text_msg); 63 | messageTextView = findViewById(R.id.et_input_message); 64 | final LinearLayout rlDlgView = findViewById(R.id.rl_inputdlg_view); 65 | confirmBtn = findViewById(R.id.confrim_btn); 66 | imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 67 | confirmBtn.setOnClickListener(new View.OnClickListener() { 68 | @Override 69 | public void onClick(View view) { 70 | String msg = messageTextView.getText().toString().trim(); 71 | if (!TextUtils.isEmpty(msg)) { 72 | onTextSendListener.onTextSend(msg); 73 | imm.showSoftInput(messageTextView, InputMethodManager.SHOW_FORCED); 74 | imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0); 75 | messageTextView.setText(""); 76 | dismiss(); 77 | } 78 | messageTextView.setText(null); 79 | } 80 | }); 81 | rlDlg = findViewById(R.id.rl_outside_view); 82 | rlDlg.setOnClickListener(new View.OnClickListener() { 83 | @Override 84 | public void onClick(View v) { 85 | if (v.getId() != R.id.rl_inputdlg_view) 86 | dismiss(); 87 | } 88 | }); 89 | rlDlgView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 90 | @Override 91 | public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) { 92 | Rect r = new Rect(); 93 | //获取当前界面可视部分 94 | getWindow().getDecorView().getWindowVisibleDisplayFrame(r); 95 | //获取屏幕的高度 96 | int screenHeight = getWindow().getDecorView().getRootView().getHeight(); 97 | //此处就是用来获取键盘的高度的, 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数 98 | int heightDifference = screenHeight - r.bottom; 99 | if (heightDifference <= 0 && mLastDiff > 0) { 100 | dismiss(); 101 | } 102 | mLastDiff = heightDifference; 103 | } 104 | }); 105 | rlDlgView.setOnClickListener(new View.OnClickListener() { 106 | @Override 107 | public void onClick(View v) { 108 | imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0); 109 | dismiss(); 110 | } 111 | }); 112 | setOnKeyListener(new OnKeyListener() { 113 | @Override 114 | public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) { 115 | if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.getRepeatCount() == 0) 116 | dismiss(); 117 | return false; 118 | } 119 | }); 120 | } 121 | 122 | private void setLayout() { 123 | getWindow().setGravity(Gravity.BOTTOM); 124 | WindowManager.LayoutParams p = getWindow().getAttributes(); 125 | p.width = WindowManager.LayoutParams.MATCH_PARENT; 126 | p.height = WindowManager.LayoutParams.WRAP_CONTENT; 127 | getWindow().setAttributes(p); 128 | setCancelable(true); 129 | getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 130 | } 131 | } -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/fragment/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.fragment; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | import androidx.fragment.app.Fragment; 7 | 8 | import top.naccl.gamebox.main.MainActivity; 9 | 10 | 11 | public class BaseFragment extends Fragment { 12 | private Activity activity; 13 | 14 | public Context getContext() { 15 | if (activity == null) { 16 | return MainActivity.getInstance(); 17 | } 18 | return activity; 19 | } 20 | 21 | @Override 22 | public void onAttach(Context context) { 23 | super.onAttach(context); 24 | activity = getActivity(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/fragment/CommunityFragment.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | 9 | import androidx.annotation.Nullable; 10 | import androidx.appcompat.widget.Toolbar; 11 | 12 | import top.naccl.gamebox.R; 13 | 14 | public class CommunityFragment extends BaseFragment { 15 | 16 | private View view; 17 | private Toolbar toolbar; 18 | private ImageView messageActionView; 19 | private ImageView scanActionView; 20 | private ImageView settingActionView; 21 | 22 | public CommunityFragment() { 23 | // Required empty public constructor 24 | } 25 | 26 | 27 | @Override 28 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 29 | // Inflate the layout for this fragment 30 | view = inflater.inflate(R.layout.fragment_community, container, false); 31 | return view; 32 | } 33 | 34 | @Override 35 | public void onActivityCreated(@Nullable Bundle savedInstanceState) { 36 | super.onActivityCreated(savedInstanceState); 37 | toolbar = getActivity().findViewById(R.id.toolbar_community); 38 | toolbar.inflateMenu(R.menu.community); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/main/MainActivity.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.main; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.widget.RadioButton; 7 | import android.widget.RadioGroup; 8 | 9 | import androidx.annotation.NonNull; 10 | import androidx.appcompat.app.AppCompatActivity; 11 | import androidx.fragment.app.Fragment; 12 | import androidx.fragment.app.FragmentManager; 13 | import androidx.fragment.app.FragmentPagerAdapter; 14 | import androidx.viewpager.widget.ViewPager; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | import top.naccl.gamebox.R; 20 | import top.naccl.gamebox.fragment.CommunityFragment; 21 | import top.naccl.gamebox.fragment.HomeFragment; 22 | import top.naccl.gamebox.fragment.MeFragment; 23 | 24 | public class MainActivity extends AppCompatActivity { 25 | private ViewPager viewPager; 26 | private List fragments; 27 | private RadioGroup radioGroup; 28 | private RadioButton t1, t2, t3; 29 | 30 | private static MainActivity mInstance; 31 | 32 | public static Context getInstance() { 33 | if (mInstance == null) { 34 | mInstance = new MainActivity(); 35 | } 36 | return mInstance; 37 | } 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_bottom_navigation_bar); 43 | 44 | initRadioButton(); 45 | initViewPager(); 46 | } 47 | 48 | public void initRadioButton() { 49 | radioGroup = findViewById(R.id.radioGroup); 50 | t1 = findViewById(R.id.radioButton1); 51 | t2 = findViewById(R.id.radioButton2); 52 | t3 = findViewById(R.id.radioButton3); 53 | 54 | t1.setOnClickListener(new MyOnClickLister(0)); 55 | t2.setOnClickListener(new MyOnClickLister(1)); 56 | t3.setOnClickListener(new MyOnClickLister(2)); 57 | } 58 | 59 | public class MyOnClickLister implements View.OnClickListener { 60 | private int index = 0; 61 | 62 | MyOnClickLister(int i) { 63 | index = i; 64 | } 65 | 66 | @Override 67 | public void onClick(View v) { 68 | viewPager.setCurrentItem(index); 69 | } 70 | } 71 | 72 | public void initViewPager() { 73 | viewPager = findViewById(R.id.viewpager); 74 | fragments = new ArrayList<>(); 75 | fragments.add(new HomeFragment()); 76 | fragments.add(new CommunityFragment()); 77 | fragments.add(new MeFragment()); 78 | 79 | viewPager.setAdapter(new MyFragmentAdapter(this.getSupportFragmentManager(), fragments)); 80 | radioGroup.check(R.id.radioButton1); 81 | viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 82 | @Override 83 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 84 | 85 | } 86 | 87 | @Override 88 | public void onPageSelected(int position) { 89 | int current = viewPager.getCurrentItem(); 90 | switch (current) { 91 | case 0: 92 | radioGroup.check(R.id.radioButton1); 93 | break; 94 | case 1: 95 | radioGroup.check(R.id.radioButton2); 96 | break; 97 | case 2: 98 | radioGroup.check(R.id.radioButton3); 99 | break; 100 | } 101 | } 102 | 103 | @Override 104 | public void onPageScrollStateChanged(int state) { 105 | 106 | } 107 | }); 108 | } 109 | 110 | public class MyFragmentAdapter extends FragmentPagerAdapter { 111 | List fragments; 112 | 113 | MyFragmentAdapter(FragmentManager fm, List fragments) { 114 | super(fm); 115 | this.fragments = fragments; 116 | } 117 | 118 | @NonNull 119 | @Override 120 | public Fragment getItem(int position) { 121 | return fragments.get(position); 122 | } 123 | 124 | @Override 125 | public int getCount() { 126 | return fragments.size(); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/camera/AutoFocusCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.camera; 18 | 19 | import android.hardware.Camera; 20 | import android.os.Handler; 21 | import android.os.Message; 22 | import android.util.Log; 23 | 24 | final class AutoFocusCallback implements Camera.AutoFocusCallback { 25 | 26 | private static final String TAG = AutoFocusCallback.class.getSimpleName(); 27 | 28 | private static final long AUTOFOCUS_INTERVAL_MS = 1500L; 29 | 30 | private Handler autoFocusHandler; 31 | private int autoFocusMessage; 32 | 33 | void setHandler(Handler autoFocusHandler, int autoFocusMessage) { 34 | this.autoFocusHandler = autoFocusHandler; 35 | this.autoFocusMessage = autoFocusMessage; 36 | } 37 | 38 | public void onAutoFocus(boolean success, Camera camera) { 39 | if (autoFocusHandler != null) { 40 | Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success); 41 | autoFocusHandler.sendMessageDelayed(message, AUTOFOCUS_INTERVAL_MS); 42 | autoFocusHandler = null; 43 | } else { 44 | Log.d(TAG, "Got auto-focus callback, but no handler for it"); 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/camera/PlanarYUVLuminanceSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.camera; 18 | 19 | import android.graphics.Bitmap; 20 | 21 | import com.google.zxing.LuminanceSource; 22 | 23 | /** 24 | * This object extends LuminanceSource around an array of YUV data returned from the camera driver, 25 | * with the option to crop to a rectangle within the full data. This can be used to exclude 26 | * superfluous pixels around the perimeter and speed up decoding. 27 | * 28 | * It works for any pixel format where the Y channel is planar and appears first, including 29 | * YCbCr_420_SP and YCbCr_422_SP. 30 | * 31 | * @author dswitkin@google.com (Daniel Switkin) 32 | */ 33 | public final class PlanarYUVLuminanceSource extends LuminanceSource { 34 | private final byte[] yuvData; 35 | private final int dataWidth; 36 | private final int dataHeight; 37 | private final int left; 38 | private final int top; 39 | 40 | public PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top, 41 | int width, int height) { 42 | super(width, height); 43 | 44 | if (left + width > dataWidth || top + height > dataHeight) { 45 | throw new IllegalArgumentException("Crop rectangle does not fit within image data."); 46 | } 47 | 48 | this.yuvData = yuvData; 49 | this.dataWidth = dataWidth; 50 | this.dataHeight = dataHeight; 51 | this.left = left; 52 | this.top = top; 53 | } 54 | 55 | @Override 56 | public byte[] getRow(int y, byte[] row) { 57 | if (y < 0 || y >= getHeight()) { 58 | throw new IllegalArgumentException("Requested row is outside the image: " + y); 59 | } 60 | int width = getWidth(); 61 | if (row == null || row.length < width) { 62 | row = new byte[width]; 63 | } 64 | int offset = (y + top) * dataWidth + left; 65 | System.arraycopy(yuvData, offset, row, 0, width); 66 | return row; 67 | } 68 | 69 | @Override 70 | public byte[] getMatrix() { 71 | int width = getWidth(); 72 | int height = getHeight(); 73 | 74 | // If the caller asks for the entire underlying image, save the copy and give them the 75 | // original data. The docs specifically warn that result.length must be ignored. 76 | if (width == dataWidth && height == dataHeight) { 77 | return yuvData; 78 | } 79 | 80 | int area = width * height; 81 | byte[] matrix = new byte[area]; 82 | int inputOffset = top * dataWidth + left; 83 | 84 | // If the width matches the full width of the underlying data, perform a single copy. 85 | if (width == dataWidth) { 86 | System.arraycopy(yuvData, inputOffset, matrix, 0, area); 87 | return matrix; 88 | } 89 | 90 | // Otherwise copy one cropped row at a time. 91 | byte[] yuv = yuvData; 92 | for (int y = 0; y < height; y++) { 93 | int outputOffset = y * width; 94 | System.arraycopy(yuv, inputOffset, matrix, outputOffset, width); 95 | inputOffset += dataWidth; 96 | } 97 | return matrix; 98 | } 99 | 100 | @Override 101 | public boolean isCropSupported() { 102 | return true; 103 | } 104 | 105 | public int getDataWidth() { 106 | return dataWidth; 107 | } 108 | 109 | public int getDataHeight() { 110 | return dataHeight; 111 | } 112 | 113 | public Bitmap renderCroppedGreyscaleBitmap() { 114 | int width = getWidth(); 115 | int height = getHeight(); 116 | int[] pixels = new int[width * height]; 117 | byte[] yuv = yuvData; 118 | int inputOffset = top * dataWidth + left; 119 | 120 | for (int y = 0; y < height; y++) { 121 | int outputOffset = y * width; 122 | for (int x = 0; x < width; x++) { 123 | int grey = yuv[inputOffset + x] & 0xff; 124 | pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101); 125 | } 126 | inputOffset += dataWidth; 127 | } 128 | 129 | Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 130 | bitmap.setPixels(pixels, 0, width, 0, 0, width, height); 131 | return bitmap; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/camera/PreviewCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.camera; 18 | 19 | import android.graphics.Point; 20 | import android.hardware.Camera; 21 | import android.os.Handler; 22 | import android.os.Message; 23 | import android.util.Log; 24 | 25 | final class PreviewCallback implements Camera.PreviewCallback { 26 | 27 | private static final String TAG = PreviewCallback.class.getSimpleName(); 28 | 29 | private final CameraConfigurationManager configManager; 30 | private final boolean useOneShotPreviewCallback; 31 | private Handler previewHandler; 32 | private int previewMessage; 33 | 34 | PreviewCallback(CameraConfigurationManager configManager, boolean useOneShotPreviewCallback) { 35 | this.configManager = configManager; 36 | this.useOneShotPreviewCallback = useOneShotPreviewCallback; 37 | } 38 | 39 | void setHandler(Handler previewHandler, int previewMessage) { 40 | this.previewHandler = previewHandler; 41 | this.previewMessage = previewMessage; 42 | } 43 | 44 | public void onPreviewFrame(byte[] data, Camera camera) { 45 | Point cameraResolution = configManager.getCameraResolution(); 46 | if (!useOneShotPreviewCallback) { 47 | camera.setPreviewCallback(null); 48 | } 49 | if (previewHandler != null) { 50 | Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x, 51 | cameraResolution.y, data); 52 | message.sendToTarget(); 53 | previewHandler = null; 54 | } else { 55 | Log.d(TAG, "Got preview callback, but no handler for it"); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/decoding/DecodeFormatManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.decoding; 18 | 19 | import android.content.Intent; 20 | import android.net.Uri; 21 | 22 | import com.google.zxing.BarcodeFormat; 23 | 24 | import java.util.Arrays; 25 | import java.util.List; 26 | import java.util.Vector; 27 | import java.util.regex.Pattern; 28 | 29 | final class DecodeFormatManager { 30 | 31 | private static final Pattern COMMA_PATTERN = Pattern.compile(","); 32 | 33 | static final Vector PRODUCT_FORMATS; 34 | static final Vector ONE_D_FORMATS; 35 | static final Vector QR_CODE_FORMATS; 36 | static final Vector DATA_MATRIX_FORMATS; 37 | static { 38 | PRODUCT_FORMATS = new Vector(5); 39 | PRODUCT_FORMATS.add(BarcodeFormat.UPC_A); 40 | PRODUCT_FORMATS.add(BarcodeFormat.UPC_E); 41 | PRODUCT_FORMATS.add(BarcodeFormat.EAN_13); 42 | PRODUCT_FORMATS.add(BarcodeFormat.EAN_8); 43 | ONE_D_FORMATS = new Vector(PRODUCT_FORMATS.size() + 4); 44 | ONE_D_FORMATS.addAll(PRODUCT_FORMATS); 45 | ONE_D_FORMATS.add(BarcodeFormat.CODE_39); 46 | ONE_D_FORMATS.add(BarcodeFormat.CODE_93); 47 | ONE_D_FORMATS.add(BarcodeFormat.CODE_128); 48 | ONE_D_FORMATS.add(BarcodeFormat.ITF); 49 | QR_CODE_FORMATS = new Vector(1); 50 | QR_CODE_FORMATS.add(BarcodeFormat.QR_CODE); 51 | DATA_MATRIX_FORMATS = new Vector(1); 52 | DATA_MATRIX_FORMATS.add(BarcodeFormat.DATA_MATRIX); 53 | } 54 | 55 | private DecodeFormatManager() {} 56 | 57 | static Vector parseDecodeFormats(Intent intent) { 58 | List scanFormats = null; 59 | String scanFormatsString = intent.getStringExtra(Intents.Scan.SCAN_FORMATS); 60 | if (scanFormatsString != null) { 61 | scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString)); 62 | } 63 | return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE)); 64 | } 65 | 66 | static Vector parseDecodeFormats(Uri inputUri) { 67 | List formats = inputUri.getQueryParameters(Intents.Scan.SCAN_FORMATS); 68 | if (formats != null && formats.size() == 1 && formats.get(0) != null){ 69 | formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0))); 70 | } 71 | return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE)); 72 | } 73 | 74 | private static Vector parseDecodeFormats(Iterable scanFormats, 75 | String decodeMode) { 76 | if (scanFormats != null) { 77 | Vector formats = new Vector(); 78 | try { 79 | for (String format : scanFormats) { 80 | formats.add(BarcodeFormat.valueOf(format)); 81 | } 82 | return formats; 83 | } catch (IllegalArgumentException iae) { 84 | // ignore it then 85 | } 86 | } 87 | if (decodeMode != null) { 88 | if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) { 89 | return PRODUCT_FORMATS; 90 | } 91 | if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) { 92 | return QR_CODE_FORMATS; 93 | } 94 | if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) { 95 | return DATA_MATRIX_FORMATS; 96 | } 97 | if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) { 98 | return ONE_D_FORMATS; 99 | } 100 | } 101 | return null; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/decoding/DecodeHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.decoding; 18 | 19 | import android.os.Bundle; 20 | import android.os.Handler; 21 | import android.os.Looper; 22 | import android.os.Message; 23 | import android.util.Log; 24 | 25 | import com.google.zxing.BinaryBitmap; 26 | import com.google.zxing.DecodeHintType; 27 | import com.google.zxing.MultiFormatReader; 28 | import com.google.zxing.ReaderException; 29 | import com.google.zxing.Result; 30 | import com.google.zxing.common.HybridBinarizer; 31 | 32 | import java.util.Hashtable; 33 | 34 | import top.naccl.gamebox.R; 35 | import top.naccl.gamebox.qrcode.activity.CaptureActivity; 36 | import top.naccl.gamebox.qrcode.camera.CameraManager; 37 | import top.naccl.gamebox.qrcode.camera.PlanarYUVLuminanceSource; 38 | 39 | 40 | final class DecodeHandler extends Handler { 41 | 42 | private static final String TAG = DecodeHandler.class.getSimpleName(); 43 | 44 | private final CaptureActivity activity; 45 | private final MultiFormatReader multiFormatReader; 46 | 47 | DecodeHandler(CaptureActivity activity, Hashtable hints) { 48 | multiFormatReader = new MultiFormatReader(); 49 | multiFormatReader.setHints(hints); 50 | this.activity = activity; 51 | } 52 | 53 | @Override 54 | public void handleMessage(Message message) { 55 | switch (message.what) { 56 | case R.id.decode: 57 | //Log.d(TAG, "Got decode message"); 58 | decode((byte[]) message.obj, message.arg1, message.arg2); 59 | break; 60 | case R.id.quit: 61 | Looper.myLooper().quit(); 62 | break; 63 | } 64 | } 65 | 66 | /** 67 | * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, 68 | * reuse the same reader objects from one decode to the next. 69 | * 70 | * @param data The YUV preview frame. 71 | * @param width The width of the preview frame. 72 | * @param height The height of the preview frame. 73 | */ 74 | private void decode(byte[] data, int width, int height) { 75 | long start = System.currentTimeMillis(); 76 | Result rawResult = null; 77 | 78 | //modify here 79 | byte[] rotatedData = new byte[data.length]; 80 | for (int y = 0; y < height; y++) { 81 | for (int x = 0; x < width; x++) 82 | rotatedData[x * height + height - y - 1] = data[x + y * width]; 83 | } 84 | int tmp = width; // Here we are swapping, that's the difference to #11 85 | width = height; 86 | height = tmp; 87 | 88 | PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height); 89 | BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 90 | try { 91 | rawResult = multiFormatReader.decodeWithState(bitmap); 92 | } catch (ReaderException re) { 93 | // continue 94 | } finally { 95 | multiFormatReader.reset(); 96 | } 97 | 98 | if (rawResult != null) { 99 | long end = System.currentTimeMillis(); 100 | Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString()); 101 | Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult); 102 | Bundle bundle = new Bundle(); 103 | bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap()); 104 | message.setData(bundle); 105 | //Log.d(TAG, "Sending decode succeeded message..."); 106 | message.sendToTarget(); 107 | } else { 108 | Message message = Message.obtain(activity.getHandler(), R.id.decode_failed); 109 | message.sendToTarget(); 110 | } 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/decoding/DecodeThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.decoding; 18 | 19 | import android.os.Handler; 20 | import android.os.Looper; 21 | 22 | import com.google.zxing.BarcodeFormat; 23 | import com.google.zxing.DecodeHintType; 24 | import com.google.zxing.ResultPointCallback; 25 | 26 | import java.util.Hashtable; 27 | import java.util.Vector; 28 | import java.util.concurrent.CountDownLatch; 29 | 30 | import top.naccl.gamebox.qrcode.activity.CaptureActivity; 31 | 32 | /** 33 | * This thread does all the heavy lifting of decoding the images. 34 | * �����߳� 35 | */ 36 | final class DecodeThread extends Thread { 37 | 38 | public static final String BARCODE_BITMAP = "barcode_bitmap"; 39 | private final CaptureActivity activity; 40 | private final Hashtable hints; 41 | private Handler handler; 42 | private final CountDownLatch handlerInitLatch; 43 | 44 | DecodeThread(CaptureActivity activity, 45 | Vector decodeFormats, 46 | String characterSet, 47 | ResultPointCallback resultPointCallback) { 48 | 49 | this.activity = activity; 50 | handlerInitLatch = new CountDownLatch(1); 51 | 52 | hints = new Hashtable(3); 53 | 54 | if (decodeFormats == null || decodeFormats.isEmpty()) { 55 | decodeFormats = new Vector(); 56 | decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS); 57 | decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS); 58 | decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS); 59 | } 60 | 61 | hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats); 62 | 63 | if (characterSet != null) { 64 | hints.put(DecodeHintType.CHARACTER_SET, characterSet); 65 | } 66 | 67 | hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback); 68 | } 69 | 70 | Handler getHandler() { 71 | try { 72 | handlerInitLatch.await(); 73 | } catch (InterruptedException ie) { 74 | // continue? 75 | } 76 | return handler; 77 | } 78 | 79 | @Override 80 | public void run() { 81 | Looper.prepare(); 82 | handler = new DecodeHandler(activity, hints); 83 | handlerInitLatch.countDown(); 84 | Looper.loop(); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/decoding/FinishListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.decoding; 18 | 19 | import android.app.Activity; 20 | import android.content.DialogInterface; 21 | 22 | /** 23 | * Simple listener used to exit the app in a few cases. 24 | * 25 | */ 26 | public final class FinishListener 27 | implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener, Runnable { 28 | 29 | private final Activity activityToFinish; 30 | 31 | public FinishListener(Activity activityToFinish) { 32 | this.activityToFinish = activityToFinish; 33 | } 34 | 35 | public void onCancel(DialogInterface dialogInterface) { 36 | run(); 37 | } 38 | 39 | public void onClick(DialogInterface dialogInterface, int i) { 40 | run(); 41 | } 42 | 43 | public void run() { 44 | activityToFinish.finish(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/decoding/InactivityTimer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.decoding; 18 | 19 | import android.app.Activity; 20 | 21 | import java.util.concurrent.Executors; 22 | import java.util.concurrent.ScheduledExecutorService; 23 | import java.util.concurrent.ScheduledFuture; 24 | import java.util.concurrent.ThreadFactory; 25 | import java.util.concurrent.TimeUnit; 26 | 27 | /** 28 | * Finishes an activity after a period of inactivity. 29 | */ 30 | public final class InactivityTimer { 31 | 32 | private static final int INACTIVITY_DELAY_SECONDS = 5 * 60; 33 | 34 | private final ScheduledExecutorService inactivityTimer = 35 | Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory()); 36 | private final Activity activity; 37 | private ScheduledFuture inactivityFuture = null; 38 | 39 | public InactivityTimer(Activity activity) { 40 | this.activity = activity; 41 | onActivity(); 42 | } 43 | 44 | public void onActivity() { 45 | cancel(); 46 | inactivityFuture = inactivityTimer.schedule(new FinishListener(activity), 47 | INACTIVITY_DELAY_SECONDS, 48 | TimeUnit.SECONDS); 49 | } 50 | 51 | private void cancel() { 52 | if (inactivityFuture != null) { 53 | inactivityFuture.cancel(true); 54 | inactivityFuture = null; 55 | } 56 | } 57 | 58 | public void shutdown() { 59 | cancel(); 60 | inactivityTimer.shutdown(); 61 | } 62 | 63 | private static final class DaemonThreadFactory implements ThreadFactory { 64 | public Thread newThread(Runnable runnable) { 65 | Thread thread = new Thread(runnable); 66 | thread.setDaemon(true); 67 | return thread; 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/decoding/RGBLuminanceSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.decoding; 18 | 19 | import android.graphics.Bitmap; 20 | import android.graphics.BitmapFactory; 21 | 22 | import com.google.zxing.LuminanceSource; 23 | 24 | import java.io.FileNotFoundException; 25 | 26 | /** 27 | * This class is used to help decode images from files which arrive as RGB data 28 | * from Android bitmaps. It does not support cropping or rotation. 29 | * 30 | */ 31 | public final class RGBLuminanceSource extends LuminanceSource { 32 | 33 | private final byte[] luminances; 34 | 35 | public RGBLuminanceSource(String path) throws FileNotFoundException { 36 | this(loadBitmap(path)); 37 | } 38 | 39 | public RGBLuminanceSource(Bitmap bitmap) { 40 | super(bitmap.getWidth(), bitmap.getHeight()); 41 | 42 | int width = bitmap.getWidth(); 43 | int height = bitmap.getHeight(); 44 | 45 | int[] pixels = new int[width * height]; 46 | bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 47 | 48 | // In order to measure pure decoding speed, we convert the entire image 49 | // to a greyscale array 50 | // up front, which is the same as the Y channel of the 51 | // YUVLuminanceSource in the real app. 52 | luminances = new byte[width * height]; 53 | for (int y = 0; y < height; y++) { 54 | int offset = y * width; 55 | for (int x = 0; x < width; x++) { 56 | int pixel = pixels[offset + x]; 57 | int r = (pixel >> 16) & 0xff; 58 | int g = (pixel >> 8) & 0xff; 59 | int b = pixel & 0xff; 60 | if (r == g && g == b) { 61 | // Image is already greyscale, so pick any channel. 62 | luminances[offset + x] = (byte) r; 63 | } else { 64 | // Calculate luminance cheaply, favoring green. 65 | luminances[offset + x] = (byte) ((r + g + g + b) >> 2); 66 | } 67 | } 68 | } 69 | } 70 | 71 | 72 | 73 | 74 | @Override 75 | public byte[] getRow(int y, byte[] row) { 76 | if (y < 0 || y >= getHeight()) { 77 | throw new IllegalArgumentException("Requested row is outside the image: " + y); 78 | } 79 | int width = getWidth(); 80 | if (row == null || row.length < width) { 81 | row = new byte[width]; 82 | } 83 | 84 | System.arraycopy(luminances, y * width, row, 0, width); 85 | return row; 86 | } 87 | 88 | // Since this class does not support cropping, the underlying byte array 89 | // already contains 90 | // exactly what the caller is asking for, so give it to them without a copy. 91 | @Override 92 | public byte[] getMatrix() { 93 | return luminances; 94 | } 95 | 96 | private static Bitmap loadBitmap(String path) throws FileNotFoundException { 97 | Bitmap bitmap = BitmapFactory.decodeFile(path); 98 | if (bitmap == null) { 99 | throw new FileNotFoundException("Couldn't open " + path); 100 | } 101 | return bitmap; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/encoding/EncodingHandler.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.qrcode.encoding; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | 6 | import com.google.zxing.BarcodeFormat; 7 | import com.google.zxing.EncodeHintType; 8 | import com.google.zxing.MultiFormatWriter; 9 | import com.google.zxing.WriterException; 10 | import com.google.zxing.common.BitMatrix; 11 | import com.google.zxing.qrcode.QRCodeWriter; 12 | import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 13 | 14 | import java.util.HashMap; 15 | import java.util.Hashtable; 16 | import java.util.Map; 17 | 18 | /** 19 | * @author Ryan Tang 20 | * 21 | */ 22 | public final class EncodingHandler { 23 | private static final int BLACK = 0xff000000; 24 | 25 | public static Bitmap createQRCode(String str, int widthAndHeight) throws WriterException { 26 | Hashtable hints = new Hashtable(); 27 | hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 28 | BitMatrix matrix = new MultiFormatWriter().encode(str, 29 | BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight); 30 | int width = matrix.getWidth(); 31 | int height = matrix.getHeight(); 32 | int[] pixels = new int[width * height]; 33 | 34 | for (int y = 0; y < height; y++) { 35 | for (int x = 0; x < width; x++) { 36 | if (matrix.get(x, y)) { 37 | pixels[y * width + x] = BLACK; 38 | } 39 | } 40 | } 41 | Bitmap bitmap = Bitmap.createBitmap(width, height, 42 | Bitmap.Config.ARGB_8888); 43 | bitmap.setPixels(pixels, 0, width, 0, 0, width, height); 44 | return bitmap; 45 | } 46 | 47 | /** 48 | * 创建二维码 49 | * 50 | * @param content content 51 | * @param widthPix widthPix 52 | * @param heightPix heightPix 53 | * @param logoBm logoBm 54 | * @return 二维码 55 | */ 56 | public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm) { 57 | try { 58 | if (content == null || "".equals(content)) { 59 | return null; 60 | } 61 | // 配置参数 62 | Map hints = new HashMap<>(); 63 | hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 64 | // 容错级别 65 | hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); 66 | // 图像数据转换,使用了矩阵转换 67 | BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, 68 | heightPix, hints); 69 | int[] pixels = new int[widthPix * heightPix]; 70 | // 下面这里按照二维码的算法,逐个生成二维码的图片, 71 | // 两个for循环是图片横列扫描的结果 72 | for (int y = 0; y < heightPix; y++) { 73 | for (int x = 0; x < widthPix; x++) { 74 | if (bitMatrix.get(x, y)) { 75 | pixels[y * widthPix + x] = 0xff000000; 76 | } else { 77 | pixels[y * widthPix + x] = 0xffffffff; 78 | } 79 | } 80 | } 81 | // 生成二维码图片的格式,使用ARGB_8888 82 | Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888); 83 | bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix); 84 | if (logoBm != null) { 85 | bitmap = addLogo(bitmap, logoBm); 86 | } 87 | //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大! 88 | return bitmap; 89 | } catch (WriterException e) { 90 | e.printStackTrace(); 91 | } 92 | return null; 93 | } 94 | 95 | /** 96 | * 在二维码中间添加Logo图案 97 | */ 98 | private static Bitmap addLogo(Bitmap src, Bitmap logo) { 99 | if (src == null) { 100 | return null; 101 | } 102 | if (logo == null) { 103 | return src; 104 | } 105 | //获取图片的宽高 106 | int srcWidth = src.getWidth(); 107 | int srcHeight = src.getHeight(); 108 | int logoWidth = logo.getWidth(); 109 | int logoHeight = logo.getHeight(); 110 | if (srcWidth == 0 || srcHeight == 0) { 111 | return null; 112 | } 113 | if (logoWidth == 0 || logoHeight == 0) { 114 | return src; 115 | } 116 | //logo大小为二维码整体大小的1/5 117 | float scaleFactor = srcWidth * 1.0f / 5 / logoWidth; 118 | Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888); 119 | try { 120 | Canvas canvas = new Canvas(bitmap); 121 | canvas.drawBitmap(src, 0, 0, null); 122 | canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2); 123 | canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null); 124 | // canvas.save(Canvas.ALL_SAVE_FLAG); 125 | canvas.restore(); 126 | } catch (Exception e) { 127 | bitmap = null; 128 | e.getStackTrace(); 129 | } 130 | return bitmap; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/qrcode/view/ViewfinderResultPointCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package top.naccl.gamebox.qrcode.view; 18 | 19 | import com.google.zxing.ResultPoint; 20 | import com.google.zxing.ResultPointCallback; 21 | 22 | public final class ViewfinderResultPointCallback implements ResultPointCallback { 23 | private final ViewfinderView viewfinderView; 24 | 25 | public ViewfinderResultPointCallback(ViewfinderView viewfinderView) { 26 | this.viewfinderView = viewfinderView; 27 | } 28 | 29 | public void foundPossibleResultPoint(ResultPoint point) { 30 | viewfinderView.addPossibleResultPoint(point); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/service/ArticleService.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.service; 2 | 3 | import top.naccl.gamebox.bean.Article; 4 | 5 | public interface ArticleService { 6 | Article getArticle(Long id); 7 | 8 | boolean deleteArticle(Long id); 9 | 10 | boolean saveArticle(Article article); 11 | 12 | boolean updateViews(Article article); 13 | 14 | boolean updateStar(Article article); 15 | } 16 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/service/ImageService.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.service; 2 | 3 | import top.naccl.gamebox.bean.Image; 4 | 5 | public interface ImageService { 6 | Image getImage(String url); 7 | 8 | boolean saveImage(Image image); 9 | } 10 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/service/UserService.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.service; 2 | 3 | import top.naccl.gamebox.bean.User; 4 | 5 | public interface UserService { 6 | User getUser(); 7 | 8 | boolean saveUser(User user); 9 | 10 | boolean updateUser(User user); 11 | 12 | boolean deleteUser(); 13 | } 14 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/service/impl/ArticleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.service.impl; 2 | 3 | import android.content.Context; 4 | 5 | import top.naccl.gamebox.bean.Article; 6 | import top.naccl.gamebox.dao.ArticleDao; 7 | import top.naccl.gamebox.service.ArticleService; 8 | 9 | public class ArticleServiceImpl implements ArticleService { 10 | private static final String[] allColumns = new String[]{"_id", "title", "author", "date", "description", "firstPicture", "content", "star", "views"}; 11 | ArticleDao articleDao; 12 | 13 | public ArticleServiceImpl(Context context) { 14 | this.articleDao = new ArticleDao(context); 15 | } 16 | 17 | @Override 18 | public Article getArticle(Long id) { 19 | articleDao.open(); 20 | Article[] articles = (Article[]) articleDao.queryOneData(allColumns, "_id", String.valueOf(id)); 21 | articleDao.close(); 22 | if (articles != null && articles.length == 1) { 23 | return articles[0]; 24 | } 25 | return null; 26 | } 27 | 28 | @Override 29 | public boolean deleteArticle(Long id) { 30 | articleDao.open(); 31 | long res = articleDao.deleteOneData("_id", String.valueOf(id)); 32 | articleDao.close(); 33 | if (res == -1) { 34 | return false; 35 | } 36 | return true; 37 | } 38 | 39 | @Override 40 | public boolean saveArticle(Article article) { 41 | articleDao.open(); 42 | long res = articleDao.insert(allColumns, new String[]{String.valueOf(article.getId()), article.getTitle(), article.getAuthor(), article.getDate(), article.getDescription(), article.getFirstPicture(), article.getContent(), String.valueOf(article.getStar()), String.valueOf(article.getViews())}); 43 | articleDao.close(); 44 | if (res == -1) { 45 | return false; 46 | } 47 | return true; 48 | } 49 | 50 | @Override 51 | public boolean updateViews(Article article) { 52 | articleDao.open(); 53 | long res = articleDao.updateOneData(new String[]{"views"}, new String[]{String.valueOf(article.getViews())}, "_id", String.valueOf(article.getId())); 54 | articleDao.close(); 55 | if (res == -1) { 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | @Override 62 | public boolean updateStar(Article article) { 63 | articleDao.open(); 64 | long res = articleDao.updateOneData(new String[]{"star"}, new String[]{String.valueOf(article.getStar())}, "_id", String.valueOf(article.getId())); 65 | articleDao.close(); 66 | if (res == -1) { 67 | return false; 68 | } 69 | return true; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/service/impl/ImageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.service.impl; 2 | 3 | import android.content.Context; 4 | 5 | import top.naccl.gamebox.bean.Image; 6 | import top.naccl.gamebox.dao.ImageDao; 7 | import top.naccl.gamebox.service.ImageService; 8 | 9 | public class ImageServiceImpl implements ImageService { 10 | private static final String[] allColumns = new String[]{"url", "base64"}; 11 | ImageDao imageDao; 12 | 13 | public ImageServiceImpl(Context context) { 14 | this.imageDao = new ImageDao(context); 15 | } 16 | 17 | @Override 18 | public Image getImage(String url) { 19 | imageDao.open(); 20 | Image[] images = (Image[]) imageDao.queryOneData(allColumns, "url", url); 21 | imageDao.close(); 22 | if (images != null && images.length == 1) { 23 | return images[0]; 24 | } 25 | return null; 26 | } 27 | 28 | @Override 29 | public boolean saveImage(Image image) { 30 | imageDao.open(); 31 | long res = imageDao.insert(allColumns, new String[]{image.getUrl(), image.getBase64()}); 32 | imageDao.close(); 33 | if (res == -1) { 34 | return false; 35 | } 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.service.impl; 2 | 3 | import android.content.Context; 4 | 5 | import top.naccl.gamebox.bean.User; 6 | import top.naccl.gamebox.dao.UserDao; 7 | import top.naccl.gamebox.service.UserService; 8 | 9 | public class UserServiceImpl implements UserService { 10 | private static final String[] allColumns = new String[]{"_id", "username", "password", "avatar", "introduction", "sex", "email", "education", "job", "birthday"}; 11 | UserDao userDao; 12 | 13 | public UserServiceImpl(Context context) { 14 | this.userDao = new UserDao(context); 15 | } 16 | 17 | private String[] getAllParams(User user) { 18 | return new String[]{String.valueOf(user.getId()), user.getUsername(), user.getPassword(), user.getAvatar(), user.getIntroduction(), user.getSex(), user.getEmail(), user.getEducation(), user.getJob(), user.getBirthday()}; 19 | } 20 | 21 | @Override 22 | public User getUser() { 23 | userDao.open(); 24 | User[] users = (User[]) userDao.queryAllData(allColumns); 25 | userDao.close(); 26 | if (users != null && users.length == 1) { 27 | return users[0]; 28 | } 29 | return null; 30 | } 31 | 32 | @Override 33 | public boolean saveUser(User user) { 34 | userDao.open(); 35 | long res = userDao.insert(allColumns, getAllParams(user)); 36 | userDao.close(); 37 | if (res == -1) { 38 | return false; 39 | } 40 | return true; 41 | } 42 | 43 | @Override 44 | public boolean updateUser(User user) { 45 | userDao.open(); 46 | //正常情况下,数据库中只存放一条用户记录,直接updateAllData 47 | long res = userDao.updateAllData(allColumns, getAllParams(user)); 48 | userDao.close(); 49 | if (res == -1) { 50 | return false; 51 | } 52 | return true; 53 | } 54 | 55 | @Override 56 | public boolean deleteUser() { 57 | userDao.open(); 58 | long res = userDao.deleteAllData(); 59 | userDao.close(); 60 | if (res == -1) { 61 | return false; 62 | } 63 | return true; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/util/Base64Utils.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.util; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import android.util.Base64; 6 | 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.IOException; 9 | 10 | public class Base64Utils { 11 | public static String bitmapToBase64(Bitmap bitmap) { 12 | String reslut = null; 13 | ByteArrayOutputStream baos = null; 14 | try { 15 | if (bitmap != null) { 16 | baos = new ByteArrayOutputStream(); 17 | //压缩只对保存有效果bitmap还是原来的大小,100不压缩 18 | bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos); 19 | baos.flush(); 20 | baos.close(); 21 | byte[] byteArray = baos.toByteArray(); 22 | reslut = Base64.encodeToString(byteArray, Base64.DEFAULT); 23 | } else { 24 | return null; 25 | } 26 | } catch (IOException e) { 27 | e.printStackTrace(); 28 | } finally { 29 | try { 30 | if (baos != null) { 31 | baos.close(); 32 | } 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | return reslut; 38 | } 39 | 40 | public static Bitmap base64ToBitmap(String base64String) { 41 | byte[] decode = Base64.decode(base64String, Base64.DEFAULT); 42 | Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length); 43 | return bitmap; 44 | } 45 | } -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/util/BitmapUtil.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.util; 2 | 3 | import android.content.ContentResolver; 4 | import android.content.Context; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapFactory; 7 | import android.net.Uri; 8 | import android.util.Log; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | 13 | /** 14 | * Bitmap util. 15 | *

从Uri直接读取图片流,避免路径转换的适配问题

16 | */ 17 | public class BitmapUtil { 18 | /** 19 | * 读取一个缩放后的图片,限定图片大小,避免OOM 20 | * 21 | * @param uri 图片uri,支持“file://”、“content://” 22 | * @param maxWidth 最大允许宽度 23 | * @param maxHeight 最大允许高度 24 | * @return 返回一个缩放后的Bitmap,失败则返回null 25 | */ 26 | public static Bitmap decodeUri(Context context, Uri uri, int maxWidth, int maxHeight) { 27 | BitmapFactory.Options options = new BitmapFactory.Options(); 28 | options.inJustDecodeBounds = true; //只读取图片尺寸 29 | readBitmapScale(context, uri, options); 30 | 31 | //计算实际缩放比例 32 | int scale = 1; 33 | for (int i = 0; i < Integer.MAX_VALUE; i++) { 34 | if ((options.outWidth / scale > maxWidth && 35 | options.outWidth / scale > maxWidth * 1.4) || 36 | (options.outHeight / scale > maxHeight && 37 | options.outHeight / scale > maxHeight * 1.4)) { 38 | scale++; 39 | } else { 40 | break; 41 | } 42 | } 43 | 44 | options.inSampleSize = scale; 45 | options.inJustDecodeBounds = false;//读取图片内容 46 | options.inPreferredConfig = Bitmap.Config.RGB_565; //根据情况进行修改 47 | Bitmap bitmap = null; 48 | try { 49 | bitmap = readBitmapData(context, uri, options); 50 | } catch (Throwable e) { 51 | e.printStackTrace(); 52 | } 53 | return bitmap; 54 | } 55 | 56 | private static void readBitmapScale(Context context, Uri uri, BitmapFactory.Options options) { 57 | if (uri == null) { 58 | return; 59 | } 60 | String scheme = uri.getScheme(); 61 | if (ContentResolver.SCHEME_CONTENT.equals(scheme) || 62 | ContentResolver.SCHEME_FILE.equals(scheme)) { 63 | InputStream stream = null; 64 | try { 65 | stream = context.getContentResolver().openInputStream(uri); 66 | BitmapFactory.decodeStream(stream, null, options); 67 | } catch (Exception e) { 68 | Log.w("readBitmapScale", "Unable to open content: " + uri, e); 69 | } finally { 70 | if (stream != null) { 71 | try { 72 | stream.close(); 73 | } catch (IOException e) { 74 | Log.e("readBitmapScale", "Unable to close content: " + uri, e); 75 | } 76 | } 77 | } 78 | } else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { 79 | Log.e("readBitmapScale", "Unable to close content: " + uri); 80 | } else { 81 | Log.e("readBitmapScale", "Unable to close content: " + uri); 82 | } 83 | } 84 | 85 | private static Bitmap readBitmapData(Context context, Uri uri, BitmapFactory.Options options) { 86 | if (uri == null) { 87 | return null; 88 | } 89 | Bitmap bitmap = null; 90 | String scheme = uri.getScheme(); 91 | if (ContentResolver.SCHEME_CONTENT.equals(scheme) || 92 | ContentResolver.SCHEME_FILE.equals(scheme)) { 93 | InputStream stream = null; 94 | try { 95 | stream = context.getContentResolver().openInputStream(uri); 96 | bitmap = BitmapFactory.decodeStream(stream, null, options); 97 | } catch (Exception e) { 98 | Log.e("readBitmapData", "Unable to open content: " + uri, e); 99 | } finally { 100 | if (stream != null) { 101 | try { 102 | stream.close(); 103 | } catch (IOException e) { 104 | Log.e("readBitmapData", "Unable to close content: " + uri, e); 105 | } 106 | } 107 | } 108 | } else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { 109 | Log.e("readBitmapData", "Unable to close content: " + uri); 110 | } else { 111 | Log.e("readBitmapData", "Unable to close content: " + uri); 112 | } 113 | return bitmap; 114 | } 115 | } -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/util/Constant.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.util; 2 | 3 | /** 4 | * 常量 5 | */ 6 | public class Constant { 7 | // request参数 8 | public static final int REQ_QR_CODE = 11002; // // 打开扫描界面请求码 9 | public static final int REQ_PERM_CAMERA = 11003; // 打开摄像头 10 | public static final int REQ_PERM_EXTERNAL_STORAGE = 11004; // 读写文件 11 | 12 | public static final String INTENT_EXTRA_KEY_QR_SCAN = "qr_scan_result"; 13 | } 14 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/util/DBUtils.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.util; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.database.sqlite.SQLiteDatabase.CursorFactory; 8 | import android.database.sqlite.SQLiteException; 9 | import android.database.sqlite.SQLiteOpenHelper; 10 | 11 | public class DBUtils { 12 | private static final String DB_NAME = "gamebox.db"; 13 | private static final int DB_VERSION = 1; 14 | 15 | private SQLiteDatabase db; 16 | private DBOpenHelper dbOpenHelper; 17 | private Context context; 18 | private String table; 19 | private String table_create; 20 | 21 | public DBUtils(Context context, String table, String table_create) { 22 | this.context = context; 23 | this.table = table; 24 | this.table_create = table_create; 25 | } 26 | 27 | public void close() { 28 | if (db != null) { 29 | db.close(); 30 | db = null; 31 | } 32 | } 33 | 34 | public void open() throws SQLiteException { 35 | dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION, table, table_create); 36 | try { 37 | db = dbOpenHelper.getWritableDatabase();//执行此方法时,会判断数据库是否存在,如果已存在,就不在调用onCreate方法 38 | } catch (SQLiteException ex) { 39 | db = dbOpenHelper.getReadableDatabase(); 40 | } 41 | } 42 | 43 | public long insert(String[] columns, String[] params) { 44 | ContentValues newValues = new ContentValues(); 45 | for (int i = 0; i < columns.length; i++) { 46 | newValues.put(columns[i], params[i]); 47 | } 48 | return db.insert(table, null, newValues); 49 | } 50 | 51 | public long updateOneData(String[] columns, String[] params, String selectColumn, String selectParam) { 52 | ContentValues updateValues = new ContentValues(); 53 | for (int i = 0; i < columns.length; i++) { 54 | updateValues.put(columns[i], params[i]); 55 | } 56 | return db.update(table, updateValues, selectColumn + "=" + selectParam, null); 57 | } 58 | 59 | public long updateAllData(String[] columns, String[] params) { 60 | ContentValues updateValues = new ContentValues(); 61 | for (int i = 0; i < columns.length; i++) { 62 | updateValues.put(columns[i], params[i]); 63 | } 64 | return db.update(table, updateValues, null, null); 65 | } 66 | 67 | public long deleteAllData() { 68 | return db.delete(table, null, null); 69 | } 70 | 71 | public long deleteOneData(String selectColumn, String selectParam) { 72 | return db.delete(table, selectColumn + "=" + selectParam, null); 73 | } 74 | 75 | public Object[] queryAllData(String[] columns) { 76 | Cursor results = db.query(table, columns, null, null, null, null, null); 77 | return ConvertToObject(results); 78 | } 79 | 80 | public Object[] queryOneData(String[] columns, String selectColumn, String selectParam) { 81 | Cursor results = db.query(table, columns, selectColumn + "=" + selectParam, 82 | null, null, null, null); 83 | return ConvertToObject(results); 84 | } 85 | 86 | public Object[] ConvertToObject(Cursor cursor) { 87 | int resultCounts = cursor.getCount(); 88 | if (resultCounts == 0 || !cursor.moveToFirst()) { 89 | return null; 90 | } 91 | Object[] objects = new Object[resultCounts]; 92 | return objects; 93 | } 94 | 95 | private class DBOpenHelper extends SQLiteOpenHelper { 96 | private String table; 97 | private String table_create; 98 | 99 | public DBOpenHelper(Context context, String name, CursorFactory factory, int version, String table, String table_create) { 100 | super(context, name, factory, version); 101 | this.table = table; 102 | this.table_create = table_create; 103 | } 104 | 105 | @Override 106 | public void onCreate(SQLiteDatabase database) { 107 | database.execSQL("create table user(_id integer primary key autoincrement, username text not null, password text, avatar text, introduction text, sex text, email text, education text, job text, birthday text);"); 108 | database.execSQL("create table article(_id integer primary key, title text, author text, date text, description text, firstPicture text, content text, star integer, views integer);"); 109 | database.execSQL("create table image(url text not null, base64 text not null);"); 110 | } 111 | 112 | @Override 113 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { 114 | database.execSQL("DROP TABLE IF EXISTS " + table); 115 | onCreate(database); 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/util/MD5Utils.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.util; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.math.BigInteger; 5 | import java.security.MessageDigest; 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | public class MD5Utils { 9 | public static String getMD5(String str) { 10 | byte[] digest = null; 11 | try { 12 | MessageDigest md5 = MessageDigest.getInstance("md5"); 13 | digest = md5.digest(str.getBytes("utf-8")); 14 | } catch (NoSuchAlgorithmException e) { 15 | e.printStackTrace(); 16 | } catch (UnsupportedEncodingException e) { 17 | e.printStackTrace(); 18 | } 19 | String md5String = new BigInteger(1, digest).toString(16); 20 | return md5String; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/util/OkHttpUtils.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.util; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import okhttp3.FormBody; 6 | import okhttp3.OkHttpClient; 7 | import okhttp3.Request; 8 | import okhttp3.RequestBody; 9 | 10 | public class OkHttpUtils { 11 | private static OkHttpClient okHttpClient = new OkHttpClient.Builder() 12 | .connectTimeout(10, TimeUnit.SECONDS) 13 | .readTimeout(10, TimeUnit.SECONDS) 14 | .writeTimeout(10, TimeUnit.SECONDS) 15 | .build(); 16 | 17 | public static void getRequest(String url, okhttp3.Callback callback) { 18 | Request request = new Request.Builder() 19 | .url(url) 20 | .get() 21 | .build(); 22 | okHttpClient.newCall(request).enqueue(callback); 23 | } 24 | 25 | public static void getRequest(String url, String token, okhttp3.Callback callback) { 26 | Request request = new Request.Builder() 27 | .url(url) 28 | .get() 29 | .addHeader("Authorization", token) 30 | .build(); 31 | okHttpClient.newCall(request).enqueue(callback); 32 | } 33 | 34 | public static void postRequest(String url, String token, okhttp3.Callback callback) { 35 | Request request = new Request.Builder() 36 | .url(url) 37 | .post(new FormBody.Builder().build()) 38 | .addHeader("Authorization", token) 39 | .build(); 40 | okHttpClient.newCall(request).enqueue(callback); 41 | } 42 | 43 | public static void postRequest(String url, RequestBody requestBody, okhttp3.Callback callback) { 44 | Request request = new Request.Builder() 45 | .url(url) 46 | .post(requestBody) 47 | .build(); 48 | okHttpClient.newCall(request).enqueue(callback); 49 | } 50 | 51 | public static void postRequest(String url, String token, RequestBody requestBody, okhttp3.Callback callback) { 52 | Request request = new Request.Builder() 53 | .url(url) 54 | .post(requestBody) 55 | .addHeader("Authorization", token) 56 | .build(); 57 | okHttpClient.newCall(request).enqueue(callback); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /GameBox/app/src/main/java/top/naccl/gamebox/util/ToastUtils.java: -------------------------------------------------------------------------------- 1 | package top.naccl.gamebox.util; 2 | 3 | import android.app.Activity; 4 | import android.widget.Toast; 5 | 6 | public class ToastUtils { 7 | public static void showToast(final Activity activity, final String msg) { 8 | activity.runOnUiThread(new Runnable() { 9 | public void run() { 10 | Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); 11 | } 12 | }); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/abc_ic_menu_moreoverflow_mtrl_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/abc_ic_menu_moreoverflow_mtrl_alpha.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/active_nor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/active_nor.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/arrow_go_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/arrow_go_back.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/arrow_right.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/avatar_login_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/avatar_login_default.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/avatar_logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/avatar_logout.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/btn_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/btn_back.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/chuapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/chuapp.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/community.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/eye.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/flash_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/flash_off.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/flash_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/flash_on.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/home.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/ic_search_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_article_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_add.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_article_favorite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_favorite.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_article_good.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_good.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_article_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_article_message.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_community_find.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_find.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_community_game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_game.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_community_nor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_nor.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_community_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_community_sel.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_home_nor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_home_nor.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_home_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_home_sel.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_information_save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_information_save.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_me_nor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_me_nor.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/icon_me_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/icon_me_sel.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/me.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/message.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/scan.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/scrollimg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/scrollimg1.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/scrollimg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/scrollimg2.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameBox4Fun/GameBox/89494cfd79298663061fe324cf815fc3ecd42e8d/GameBox/app/src/main/res/drawable/setting.png -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/shape_add.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/drawable/textcolor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/layout/activity_bottom_navigation_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 17 | 18 | 25 | 26 | 33 | 34 | 41 | 42 | 49 | 50 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/layout/activity_favorite.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 31 | 32 | 33 | 34 | 38 | 39 | 42 | 43 | 47 | 48 | 51 | 52 | 60 | 61 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /GameBox/app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 22 | 23 | 36 | 37 | 48 | 49 |