18 files added
3 files renamed
3 files deleted
9 files modified
| | |
| | | //// 注意:分包之后不会有默认的Header和Footer需要手动添加!还是原来的三种方法! |
| | | implementation 'com.scwang.smart:refresh-layout-kernel:2.0.1' //核心必须依赖 |
| | | implementation 'com.scwang.smart:refresh-header-classics:2.0.1' //经典刷新头 |
| | | implementation 'com.github.d-max:spots-dialog:1.1@aar'//loading view |
| | | implementation 'com.google.code.gson:gson:2.8.6' |
| | | implementation 'com.ansen.http:okhttpencapsulation:1.0.1'//版本更新下载 |
| | | implementation 'com.squareup.okhttp3:okhttp:3.12.1' |
| | | implementation 'com.squareup.retrofit2:retrofit:2.3.0' |
| | | //RXjava和retrofit结合 |
| | | implementation 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' |
| | | implementation 'com.google.android.material:material:1.4.0' |
| | | implementation 'com.github.bumptech.glide:glide:4.12.0' |
| | | implementation 'com.permissionx.guolindev:permissionx:1.2.2' //权限依赖 |
| | | } |
| | |
| | | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| | | package="com.duqing.missions" > |
| | | |
| | | <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> |
| | | <application |
| | | android:allowBackup="true" |
| | | android:icon="@mipmap/ic_launcher" |
| | |
| | | |
| | | import com.duqing.missions.base.BaseActivity; |
| | | import com.duqing.missions.databinding.ActivityMainBinding; |
| | | import com.google.android.material.bottomnavigation.BottomNavigationView; |
| | | |
| | | public class MainActivity extends BaseActivity<ActivityMainBinding> { |
| | | |
| | |
| | | protected void onCreate(Bundle savedInstanceState) { |
| | | super.onCreate(savedInstanceState); |
| | | |
| | | BottomNavigationView navView = binding.navView; |
| | | // Passing each menu ID as a set of Ids because each |
| | | // menu should be considered as top level destinations. |
| | | AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( |
New file |
| | |
| | | package com.duqing.missions; |
| | | |
| | | import android.app.Activity; |
| | | import android.app.Application; |
| | | import android.content.Context; |
| | | import android.os.Bundle; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | |
| | | import com.duqing.missions.util.MyLog; |
| | | import com.scwang.smart.refresh.footer.ClassicsFooter; |
| | | import com.scwang.smart.refresh.header.ClassicsHeader; |
| | | import com.scwang.smart.refresh.layout.SmartRefreshLayout; |
| | | import com.scwang.smart.refresh.layout.api.RefreshFooter; |
| | | import com.scwang.smart.refresh.layout.api.RefreshHeader; |
| | | import com.scwang.smart.refresh.layout.api.RefreshLayout; |
| | | import com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator; |
| | | import com.scwang.smart.refresh.layout.listener.DefaultRefreshHeaderCreator; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class MyApplication extends Application { |
| | | |
| | | final String TAG = "MyApplication"; |
| | | List<Activity> activities = new ArrayList<>(); |
| | | private Activity currentActivity;//当前activity |
| | | private boolean isInfront; //是否前台运行 |
| | | private static MyApplication application; |
| | | public static MyApplication getApplication() { |
| | | return application; |
| | | } |
| | | |
| | | public Activity getCurrentActivity() { |
| | | return currentActivity; |
| | | } |
| | | |
| | | @Override |
| | | public void onCreate() { |
| | | super.onCreate(); |
| | | application = this; |
| | | //CrashReport.initCrashReport(getApplicationContext(), "8d88679ae9", false);//注册bugly |
| | | //设置全局的Header构建器 |
| | | SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { |
| | | @Override |
| | | public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { |
| | | //layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色 |
| | | return new ClassicsHeader(context);//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header,默认是 贝塞尔雷达Header |
| | | } |
| | | }); |
| | | //设置全局的Footer构建器 |
| | | SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() { |
| | | @Override |
| | | public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { |
| | | //指定为经典Footer,默认是 BallPulseFooter |
| | | return new ClassicsFooter(context).setDrawableSize(20); |
| | | } |
| | | }); |
| | | registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { |
| | | @Override |
| | | public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { |
| | | MyLog.d(TAG,"onActivityCreated "+activity.getClass().getSimpleName()); |
| | | if(!activities.contains(activity)){ |
| | | activities.add(activity); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void onActivityStarted(@NonNull Activity activity) { |
| | | MyLog.d(TAG,"onActivityStarted "+activity.getClass().getSimpleName()); |
| | | currentActivity = activity; |
| | | } |
| | | |
| | | @Override |
| | | public void onActivityResumed(@NonNull Activity activity) { |
| | | MyLog.d(TAG,"onActivityResumed "+activity.getClass().getSimpleName()); |
| | | currentActivity = activity; |
| | | isInfront = true; |
| | | } |
| | | |
| | | @Override |
| | | public void onActivityPaused(@NonNull Activity activity) { |
| | | MyLog.d(TAG,"onActivityPaused "+activity.getClass().getSimpleName()); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onActivityStopped(@NonNull Activity activity) { |
| | | MyLog.d(TAG,"onActivityStopped "+activity.getClass().getSimpleName()); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) { |
| | | MyLog.d(TAG,"onActivitySaveInstanceState "+activity.getClass().getSimpleName()); |
| | | isInfront = false; |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void onActivityDestroyed(@NonNull Activity activity) { |
| | | MyLog.d(TAG,"onActivityDestroyed "+activity.getClass().getSimpleName()); |
| | | if(activities.contains(activity)){ |
| | | activities.remove(activity); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 退出程序 |
| | | */ |
| | | public void quitApp(){ |
| | | for(Activity activity:activities){ |
| | | activity.finish(); |
| | | } |
| | | System.exit(0); |
| | | } |
| | | |
| | | public void clearActivities(){ |
| | | for(Activity activity:activities){ |
| | | /*if(activity instanceof LoginActivity){ |
| | | continue; |
| | | }*/ |
| | | activity.finish(); |
| | | } |
| | | } |
| | | |
| | | public boolean isInfront(){ |
| | | return isInfront; |
| | | } |
| | | } |
| | |
| | | package com.duqing.missions.base; |
| | | |
| | | import android.Manifest; |
| | | import android.app.AlertDialog; |
| | | import android.app.ProgressDialog; |
| | | import android.content.Context; |
| | | import android.content.DialogInterface; |
| | | import android.content.Intent; |
| | | import android.content.pm.ActivityInfo; |
| | | import android.net.Uri; |
| | | import android.os.Build; |
| | | import android.os.Bundle; |
| | | import android.os.Environment; |
| | | import android.provider.Settings; |
| | | import android.util.Log; |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | import android.view.WindowManager; |
| | | import android.widget.Toast; |
| | | |
| | | import androidx.annotation.ColorRes; |
| | | import androidx.annotation.Nullable; |
| | | import androidx.appcompat.app.AppCompatActivity; |
| | | import androidx.core.content.FileProvider; |
| | | import androidx.viewbinding.ViewBinding; |
| | | |
| | | import com.duqing.missions.MyApplication; |
| | | import com.duqing.missions.data.ApkUpGradeResult; |
| | | import com.duqing.missions.util.MyLog; |
| | | import com.duqing.missions.util.ResPonse; |
| | | import com.duqing.missions.util.SpUtils; |
| | | import com.permissionx.guolindev.PermissionX; |
| | | import com.permissionx.guolindev.callback.ExplainReasonCallbackWithBeforeParam; |
| | | import com.permissionx.guolindev.callback.ForwardToSettingsCallback; |
| | | import com.permissionx.guolindev.callback.RequestCallback; |
| | | import com.permissionx.guolindev.request.ExplainScope; |
| | | import com.permissionx.guolindev.request.ForwardScope; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.lang.reflect.Method; |
| | | import java.lang.reflect.ParameterizedType; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | import okhttp3.Call; |
| | | import okhttp3.Callback; |
| | | import okhttp3.OkHttpClient; |
| | | import okhttp3.Request; |
| | | import okhttp3.Response; |
| | | import okhttp3.ResponseBody; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/27 0027. |
| | |
| | | public abstract class BaseActivity<B extends ViewBinding> extends AppCompatActivity { |
| | | |
| | | protected B binding; |
| | | protected String TAG ; |
| | | public final String[] FILE_PERMISSIONS = new String []{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}; |
| | | public final String[] LOCATION_PERMISSIONS = new String []{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}; |
| | | public final String[] CAMERA_PERMISSIONS = new String[]{ FILE_PERMISSIONS[0],FILE_PERMISSIONS[1], Manifest.permission.CAMERA}; |
| | | public final String[] CAMERA_RECORD_PERMISSIONS = new String[]{ FILE_PERMISSIONS[0],FILE_PERMISSIONS[1], Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO}; |
| | | |
| | | public static final int RESULT_LOGIN = 100,RESULT_LOGIN_RECREATE = 103,RESULT_BIND = 101,RESULT_SENDEDFILES = 105,RESULT_DISSCONNECT = 104, |
| | | RESULT_UPDATEUSER = 115,RESULT_LOGOUT = 113, REQUEST_CODE_ACTIVITY = 333; |
| | | public static final int REQUEST_CODE_LOGOUT = 20009,/*退出*/ |
| | | REQUEST_CODE_ORDER = 10010,/*订单详情*/ |
| | | REQUEST_CODE_LOGIN = 20010,/*登录*/ |
| | | REQUEST_CODE_SCAN = 20011/*扫描请求*/, |
| | | REQUEST_CODE_PIC = 20012,/*选择图片*/ |
| | | REQUEST_CODE_PAYPASS = 20112,/*支付验证*/ |
| | | REQUEST_CODE_PAYPASS_FOR_ALIPAY = 20110,/*支付宝修改支付验证*/ |
| | | REQUEST_CODE_PAYPASS_FOR_REALNAME = 20111,/*支付宝修改支付验证*/ |
| | | REQUEST_CODE_PERMISSION = 20013,/*请求权限*/ |
| | | REQUEST_VERSION_PERMISSION = 20013,/*检查更新*/ |
| | | REQUEST_INSTALL_PERMISSION = 20014,/*请求安装权限*/ |
| | | REQUEST_CODE_MANAGE_GROUP = 20015,/*选择分组*/ |
| | | REQUEST_CODE_MANAGE_DEL = 20016,/*选择删除*/ |
| | | REQUEST_CODE_MANAGE_EDIT = 20017,/*选择编辑*/ |
| | | REQUEST_CODE_MANAGE_ADD = 20018,/*选择添加*/ |
| | | REQUEST_CODE_MANAGE_DRAFT = 20019,/*选择草稿编辑*/ |
| | | REQUEST_CODE_WEPAY = 20020,/*微信支付*/ |
| | | REQUEST_CODE_ALIPAY = 20021,/*支付宝*/ |
| | | REQUEST_CODE_PINKAGE = 20022,/*包邮设置*/ |
| | | REQUEST_INSTALL_APK = 20200,/*请求安装权限*/ |
| | | REQUEST_CODE_COMMENT_REFRESH = 20222,/*请求安装权限*/ |
| | | RESULT_CODE_DRAFT = 4041/*草稿*/, |
| | | RESULT_CODE_UPDATED = 4042/*更新*/, |
| | | RESULT_CODE_FAILD = 4044/*失败*/, |
| | | RESULT_CODE_SUCESS = 4046/*成功*/, |
| | | RESULT_CODE_CANCEL = 4043/*取消*/; |
| | | protected Context mContext; |
| | | |
| | | |
| | | @Override |
| | |
| | | e.printStackTrace(); |
| | | } |
| | | setContentView(binding.getRoot()); |
| | | mContext = this; |
| | | try { |
| | | //设置坚屏 一定要放到try catch里面,否则会崩溃 |
| | | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); |
| | | } catch (Exception e) { |
| | | } |
| | | TAG = this.getClass().getSimpleName(); |
| | | } |
| | | |
| | | |
| | | public void setStatusBarTransparent(boolean isBlack){ |
| | | //透明状态栏 |
| | | getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); |
| | | //透明导航栏 |
| | | getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); |
| | | } |
| | | |
| | | /** |
| | | * 修改状态栏颜色,支持4.4以上版本 |
| | | * @param colorId |
| | | */ |
| | | public void setStatusBarBgColor(@ColorRes int colorId) { |
| | | getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); |
| | | getWindow().setStatusBarColor(getResources().getColor(colorId)); |
| | | } |
| | | |
| | | /** |
| | | * 修改状态栏文本颜色 |
| | | * @param isBlack |
| | | */ |
| | | public void setStatusBarTextColor(boolean isBlack){ |
| | | View decor = getWindow().getDecorView(); |
| | | if (isBlack) { |
| | | decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); |
| | | } else { |
| | | decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 隐藏虚拟按键 |
| | | */ |
| | | public void hideBottomUIMenu() { |
| | | //隐藏虚拟按键 |
| | | if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api |
| | | View v = getWindow().getDecorView(); |
| | | v.setSystemUiVisibility(View.GONE); |
| | | } else if (Build.VERSION.SDK_INT >= 19) { |
| | | //for new api versions. |
| | | View decorView = getWindow().getDecorView(); |
| | | int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
| | | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY ; |
| | | decorView.setSystemUiVisibility(uiOptions); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 状态栏高度 |
| | | * @return |
| | | */ |
| | | public int getStatusBarHeight() { |
| | | int result = 0; |
| | | int resId = getResources().getIdentifier("status_bar_height", "dimen", "android"); |
| | | if (resId > 0) { |
| | | result = getResources().getDimensionPixelOffset(resId); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | long mExitTime= 0 ; |
| | | /** |
| | | * 返回键退出程序 |
| | | */ |
| | | public void backExit() { |
| | | if ((System.currentTimeMillis() - mExitTime) > 2000) { |
| | | Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show(); |
| | | mExitTime = System.currentTimeMillis(); |
| | | } else { |
| | | //此方法导致app关闭后重启 |
| | | MyApplication.getApplication().quitApp(); |
| | | System.exit(0); |
| | | //quitApp(); |
| | | } |
| | | } |
| | | ApkUpGradeResult.AppInfo apkUpGrade; |
| | | ProgressDialog progressDialog ; |
| | | |
| | | public void showUpdateDialog(){ |
| | | if(apkUpGrade == null){ |
| | | return; |
| | | } |
| | | AlertDialog.Builder builder = new AlertDialog.Builder(this); |
| | | builder.setTitle("新版本").setMessage("有新版更新\n"+apkUpGrade.content) |
| | | .setPositiveButton("", new DialogInterface.OnClickListener() { |
| | | @Override |
| | | public void onClick(DialogInterface dialog, int which) { |
| | | dialog.dismiss(); |
| | | okHttpDownload(apkUpGrade.url, new ResPonse<String>() { |
| | | @Override |
| | | public void doSuccess(String path) { |
| | | apkUpGrade.remark = path; |
| | | openAPK(new File(path)); |
| | | } |
| | | |
| | | @Override |
| | | public void doError(String path) { |
| | | if(apkUpGrade.isImportant==1){ |
| | | showUpdateDialog(); |
| | | }else { |
| | | if(path != null) { |
| | | apkUpGrade.remark = path; |
| | | openAPK(new File(path)); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }) |
| | | .setNegativeButton(apkUpGrade.isImportant==1?"退出":"取消", new DialogInterface.OnClickListener() { |
| | | @Override |
| | | public void onClick(DialogInterface dialog, int which) { |
| | | if(apkUpGrade.isImportant==1){ |
| | | MyApplication.getApplication().quitApp(); |
| | | }else { |
| | | SpUtils.getInstance().putLongValOfProject(mContext,"version", new Date().getTime());//记录今天已经请求过更新 不在自动请求 |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * okhttp下载文件 |
| | | * @param downloadUrl |
| | | * @param resPonse |
| | | */ |
| | | protected void okHttpDownload(final String downloadUrl, final ResPonse<String> resPonse){ |
| | | PermissionX.init(this).permissions(FILE_PERMISSIONS).onExplainRequestReason(new ExplainReasonCallbackWithBeforeParam() { |
| | | @Override |
| | | public void onExplainReason(ExplainScope scope, List<String> deniedList, boolean beforeRequest) { |
| | | scope.showRequestReasonDialog(deniedList, "即将申请的权限是程序必须依赖的权限", "继续申请","我已明白"); |
| | | } |
| | | }).onForwardToSettings(new ForwardToSettingsCallback() { |
| | | @Override |
| | | public void onForwardToSettings(ForwardScope scope, List<String> deniedList) { |
| | | scope.showForwardToSettingsDialog(deniedList, "您需要去应用程序设置当中手动开启权限", "去设置","我已明白"); |
| | | } |
| | | }).request(new RequestCallback() { |
| | | @Override |
| | | public void onResult(boolean allGranted, List<String> grantedList, List<String> deniedList) { |
| | | if(allGranted){ |
| | | |
| | | OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); |
| | | |
| | | Request request = new Request.Builder() |
| | | .url(downloadUrl) |
| | | .get() |
| | | .build(); |
| | | |
| | | okHttpClient.newCall(request).enqueue(new Callback() { |
| | | @Override |
| | | public void onFailure(Call call, IOException e) { |
| | | Log.e("tag", "onFailure: " + e.getMessage()); |
| | | } |
| | | |
| | | @Override |
| | | public void onResponse(Call call, Response response) throws IOException { |
| | | ResponseBody body = response.body(); // 获取到请求体 |
| | | InputStream inputStream = body.byteStream(); // 转换成字节流 |
| | | progressDialog = new ProgressDialog(mContext); |
| | | progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); |
| | | progressDialog.setTitle("正在下载..."); |
| | | progressDialog.setCancelable(false); |
| | | progressDialog.show(); |
| | | saveFile(inputStream, getSaveFilePath(downloadUrl), body.contentLength(),resPonse); |
| | | } |
| | | }); |
| | | } else { |
| | | Toast.makeText(mContext, "您拒绝了权限申请!", Toast.LENGTH_SHORT).show(); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * @param inputStream |
| | | * @param filePath 存放的地址 |
| | | * @param l 文件的长度 |
| | | */ |
| | | private void saveFile(InputStream inputStream, final String filePath, final long l, final ResPonse<String> resPonse) { |
| | | runOnUiThread(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | progressDialog.setMax((int)l);// 设置进度条最大值 |
| | | } |
| | | }); |
| | | long count = 0; |
| | | try { |
| | | File file = new File(filePath); |
| | | Log.i(TAG, "文件保存路径:" + filePath+" 文件是否存在:"+file.exists()); |
| | | if (!file.exists()) {//文件不存在 |
| | | file.createNewFile(); |
| | | }else{ |
| | | file.delete(); |
| | | } |
| | | // 获取到输出流,写入到的地址 |
| | | FileOutputStream outputStream = new FileOutputStream(file); |
| | | int length = -1; |
| | | byte[] bytes = new byte[1024 * 10]; |
| | | while ((length = inputStream.read(bytes)) != -1) { |
| | | // 写入文件 |
| | | outputStream.write(bytes, 0, length); |
| | | count += length; |
| | | |
| | | final long finalCount = count; |
| | | final int finalLenght = length; |
| | | runOnUiThread(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | progressDialog.setProgress((int) finalCount); // 设置进度 |
| | | } |
| | | }); |
| | | } |
| | | inputStream.close(); // 关闭输入流 |
| | | outputStream.close(); // 关闭输出流 |
| | | runOnUiThread(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | // 如果写入的进度值完毕,Toast |
| | | progressDialog.dismiss(); |
| | | resPonse.doSuccess(filePath); |
| | | } |
| | | }); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取文件保存路径 sdcard根目录/download/文件名称 |
| | | * @param fileUrl |
| | | * @return |
| | | */ |
| | | public static String getSaveFilePath(String fileUrl){ |
| | | String fileName=fileUrl.substring(fileUrl.lastIndexOf("/")+1,fileUrl.length());//获取文件名称 |
| | | String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Download"; |
| | | File appDir = new File(storePath); |
| | | if (!appDir.exists()) { |
| | | appDir.mkdirs(); |
| | | } |
| | | return storePath + File.separator +fileName; |
| | | } |
| | | |
| | | /** |
| | | * 打开apk文件 |
| | | * @param file |
| | | */ |
| | | public void openAPK(final File file){ |
| | | |
| | | //android 8及以上需要设置权限 |
| | | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !getPackageManager().canRequestPackageInstalls()) { |
| | | // 申请安装权限。 |
| | | final AlertDialog.Builder builder = new AlertDialog.Builder(this); |
| | | builder.setTitle("需要允许安装权限").setMessage("应用需要手动设置,才能打开安装包升级应用").setCancelable(false) |
| | | .setNegativeButton("", new DialogInterface.OnClickListener() { |
| | | @Override |
| | | public void onClick(DialogInterface dialog, int which) { |
| | | Uri packageUri = Uri.parse("package:" + getPackageName()); |
| | | Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageUri); |
| | | startActivityForResult(intent, REQUEST_INSTALL_PERMISSION); |
| | | dialog.dismiss(); |
| | | } |
| | | }) |
| | | .setPositiveButton(apkUpGrade.isImportant==1?"退出":"取消", new DialogInterface.OnClickListener() { |
| | | @Override |
| | | public void onClick(DialogInterface dialog, int which) { |
| | | if(apkUpGrade.isImportant==1){ |
| | | MyApplication.getApplication().quitApp(); |
| | | } |
| | | } |
| | | }).create().show(); |
| | | return; |
| | | } |
| | | |
| | | Intent intent = new Intent(); |
| | | intent.setAction(Intent.ACTION_VIEW); |
| | | Uri photoURI = null ; |
| | | if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) { //判读版本是否在7.0以上 |
| | | intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
| | | photoURI = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", file);//添加这一句表示对目标应用临时授权该Uri所代表的文件 |
| | | |
| | | }else{ |
| | | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| | | photoURI = Uri.fromFile(file); |
| | | } |
| | | intent.setDataAndType(photoURI,"application/vnd.android.package-archive"); |
| | | startActivityForResult(intent,REQUEST_INSTALL_APK); |
| | | } |
| | | |
| | | @Override |
| | | protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { |
| | | super.onActivityResult(requestCode, resultCode, data); |
| | | MyLog.i(TAG,String.format("onActivityResult requestCode:%s, resultCode:%s, data:%s",requestCode, resultCode, data)); |
| | | if(requestCode == REQUEST_INSTALL_PERMISSION){ |
| | | openAPK(new File(apkUpGrade.remark)); |
| | | }else if(requestCode == REQUEST_INSTALL_APK && apkUpGrade.isImportant==1){ |
| | | /*showDialog("强制更新", "需要安装新版本才能继续使用","安装","退出", new ResPonse() { |
| | | @Override |
| | | public void doSuccess(Object obj) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void doError(Object obj) { |
| | | super.doError(obj); |
| | | } |
| | | });*/ |
| | | } |
| | | } |
| | | |
| | | |
| | | protected boolean onBackKeyDown() { |
| | | onBackPressed(); |
| | | return false; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.base; |
| | | |
| | | import android.graphics.drawable.Drawable; |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | |
| | | import androidx.annotation.LayoutRes; |
| | | import androidx.annotation.NonNull; |
| | | import androidx.recyclerview.widget.RecyclerView; |
| | | import androidx.viewbinding.ViewBinding; |
| | | |
| | | import com.duqing.missions.R; |
| | | import com.duqing.missions.common.NullViewHolder; |
| | | import com.duqing.missions.databinding.LayoutNullBinding; |
| | | import com.duqing.missions.util.DeviceUtil; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.lang.reflect.ParameterizedType; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/27 0027. |
| | | * T 数据类型 |
| | | * V 适配器视图 |
| | | */ |
| | | public abstract class BaseAdapter<B extends ViewBinding,A extends BaseActivity,T> extends RecyclerView.Adapter { |
| | | |
| | | protected List<T> mData = new ArrayList<>(); |
| | | |
| | | protected Drawable nullDrawable; |
| | | protected String nullTxt="暂无数据"; |
| | | protected String TAG = "BaseAdapter"; |
| | | protected A activity; |
| | | protected LayoutNullBinding nullBinding; |
| | | |
| | | public BaseAdapter(){ |
| | | } |
| | | |
| | | public BaseAdapter(@NonNull List<T> data){ |
| | | mData = data; |
| | | } |
| | | |
| | | public List<T> getData() { |
| | | return mData; |
| | | } |
| | | |
| | | public void setData(@NonNull List<T> data){ |
| | | mData = data; |
| | | notifyDataSetChanged(); |
| | | } |
| | | |
| | | @NonNull |
| | | @Override |
| | | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { |
| | | // get genericity "B" |
| | | Class<B> entityClass = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; |
| | | try { |
| | | /* for(Method method: entityClass.getMethods()){ |
| | | StringBuilder sb = new StringBuilder(); |
| | | for(Class type : method.getParameterTypes()){ |
| | | sb.append(type.getSimpleName()+","); |
| | | } |
| | | Log.e(TAG,String.format("method:%s,return:%s,param:%s",method.getName(),method.getReturnType().getSimpleName(),sb.toString())); |
| | | }*/ |
| | | Method method = entityClass.getMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);//get method from name "inflate"; |
| | | B vBind = (B) method.invoke(entityClass,LayoutInflater.from(parent.getContext()),parent,false);//execute method to create a objct of viewbind; |
| | | return new ViewBindHolder(vBind); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return new NullViewHolder( LayoutNullBinding.inflate(LayoutInflater.from(parent.getContext()))); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * 创建视图 |
| | | * @param parent |
| | | * @param layout 视图文件 |
| | | * @param viewType 视图类型 1 加载正常视图 其他则加载空数据 |
| | | * @return |
| | | */ |
| | | protected View getRootView(@NonNull ViewGroup parent, @LayoutRes int layout,int viewType ){ |
| | | //MyLog.i(TAG,"getRootView viewType:"+viewType); |
| | | return LayoutInflater.from(parent.getContext()).inflate(viewType==1?layout: R.layout.layout_null,parent,false); |
| | | } |
| | | |
| | | @Override |
| | | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { |
| | | //MyLog.i(TAG,"onBindViewHolder position:"+position+" "+mData.size()+" "+getItemViewType(position)); |
| | | if(getItemViewType(position)==0){ |
| | | return; |
| | | } |
| | | try { |
| | | activity = (A) holder.itemView.getContext(); |
| | | }catch (Exception e){} |
| | | bindView((ViewBindHolder) holder,mData.size()==0?null:mData.get(position),position); |
| | | } |
| | | |
| | | /** |
| | | * 设置最后一个底部间隔 |
| | | * @param holder |
| | | * @param position |
| | | */ |
| | | protected void setBottomMargin(ViewBindHolder holder, int position){ |
| | | setBottomMargin(holder,position,23); |
| | | } |
| | | |
| | | /** |
| | | * 设置最后一个底部间隔 |
| | | * @param holder |
| | | * @param position 位置 |
| | | * @param dp 间距 |
| | | */ |
| | | protected void setBottomMargin(RecyclerView.ViewHolder holder, int position,int dp){ |
| | | setBottomMargin(holder,position,dp,0); |
| | | } |
| | | protected void setBottomMargin(RecyclerView.ViewHolder holder, int position, int dp, int defaultDp){ |
| | | ViewGroup.MarginLayoutParams params1 = (ViewGroup.MarginLayoutParams) holder.itemView.getLayoutParams(); |
| | | if(position == mData.size() -1){ |
| | | params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, DeviceUtil.convertDpToPixel(dp,holder.itemView.getContext())); |
| | | }else{ |
| | | params1.setMargins(params1.leftMargin, params1.topMargin, params1.rightMargin, DeviceUtil.convertDpToPixel(defaultDp,holder.itemView.getContext())); |
| | | } |
| | | } |
| | | protected abstract void bindView(ViewBindHolder holder,T data,int position); |
| | | |
| | | |
| | | @Override |
| | | public int getItemCount() { |
| | | //默认显示空视图,若不显示空视图则重写该方法,返回mData.size() |
| | | return mData == null || mData.size() == 0 ?1:mData.size(); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public int getItemViewType(int position) { |
| | | //当下标为0,数据集合为0 返回0(意味当前应显示空数据视图)) |
| | | //MyLog.i(TAG,"getItemViewType position:"+position+" mdata:"+mData.size()+" "+(position ==0 && mData.size()==0)); |
| | | return position ==0 && mData.size()==0?0:1; |
| | | } |
| | | |
| | | public class ViewBindHolder extends RecyclerView.ViewHolder{ |
| | | |
| | | B binding; |
| | | |
| | | public ViewBindHolder( B binding) { |
| | | super(binding.getRoot()); |
| | | this.binding = binding; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.base; |
| | | |
| | | import android.os.Bundle; |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | |
| | | import androidx.annotation.Nullable; |
| | | import androidx.fragment.app.Fragment; |
| | | import androidx.viewbinding.ViewBinding; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.lang.reflect.ParameterizedType; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public abstract class BaseFragment<A extends BaseActivity,B extends ViewBinding> extends Fragment { |
| | | |
| | | protected A activity; |
| | | protected B binding; |
| | | |
| | | @Nullable |
| | | @Override |
| | | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { |
| | | // get genericity "B" |
| | | Class<B> entityClass = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1]; |
| | | try { |
| | | Method method = entityClass.getMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);//get method from name "inflate"; |
| | | binding = (B) method.invoke(entityClass,inflater,container,false);//execute method to create a objct of viewbind; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return binding.getRoot(); |
| | | } |
| | | |
| | | @Override |
| | | public void onActivityCreated(@Nullable Bundle savedInstanceState) { |
| | | super.onActivityCreated(savedInstanceState); |
| | | activity = (A) getActivity(); |
| | | initViews(); |
| | | } |
| | | |
| | | public abstract void initViews(); |
| | | |
| | | @Override |
| | | public void onDestroyView() { |
| | | super.onDestroyView(); |
| | | binding = null; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.common; |
| | | |
| | | import androidx.recyclerview.widget.RecyclerView; |
| | | |
| | | import com.duqing.missions.databinding.LayoutNullBinding; |
| | | |
| | | /** |
| | | * 空数据显示 |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class NullViewHolder extends RecyclerView.ViewHolder { |
| | | LayoutNullBinding binding; |
| | | |
| | | public NullViewHolder(LayoutNullBinding binding) { |
| | | super(binding.getRoot()); |
| | | this.binding = binding; |
| | | } |
| | | } |
New file |
| | |
| | | package com.duqing.missions.data; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class ApkUpGradeResult extends BaseApiResult<ApkUpGradeResult.AppInfo> { |
| | | |
| | | public class AppInfo { |
| | | //以下为声明的参数 |
| | | public int type, isEnable, isImportant, id, code; |
| | | public String url,version, content, udate, remark; |
| | | |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "ApkUpGrade{" + |
| | | "type=" + type + "," + |
| | | "isEnable=" + isEnable + "," + |
| | | "isImportant=" + isImportant + "," + |
| | | "id=" + id + "," + |
| | | "url=" + url + "," + |
| | | "version=" + version + "," + |
| | | "content=" + content + "," + |
| | | "udate=" + udate + "," + |
| | | '}'; |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.duqing.missions.data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class BaseApiResult<D extends Object> implements Serializable { |
| | | public String msg; |
| | | public int code = 200; |
| | | public D data; |
| | | |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "BaseApiData{" + |
| | | "msg='" + msg + '\'' + |
| | | ", code=" + code + |
| | | ", data=" + data + |
| | | '}'; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.data; |
| | | |
| | | import java.util.ArrayList; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class BasePageResult<T> extends BaseApiResult<String>{ |
| | | public int pages; |
| | | public int total; |
| | | public int pageNum; |
| | | public ArrayList<T> rows; |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "PageBean{" + |
| | | ", total=" + total + |
| | | ", rows=" + rows + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | package com.duqing.missions.source; |
| | | |
| | | import com.duqing.missions.data.BasePageResult; |
| | | |
| | | import java.util.Observable; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public interface HttpPageSource<T extends BasePageResult> { |
| | | |
| | | Observable refresh(); |
| | | |
| | | Observable loadMore(int page,int size); |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.ui.main; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class Text { |
| | | } |
File was renamed from app/src/main/java/com/duqing/missions/ui/dashboard/DashboardFragment.java |
| | |
| | | package com.duqing.missions.ui.dashboard; |
| | | package com.duqing.missions.ui.main.dashboard; |
| | | |
| | | import android.os.Bundle; |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.widget.TextView; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | |
| | | import androidx.lifecycle.Observer; |
| | | import androidx.lifecycle.ViewModelProvider; |
| | | |
| | | import com.duqing.missions.R; |
| | | import com.duqing.missions.databinding.FragmentDashboardBinding; |
| | | |
| | | public class DashboardFragment extends Fragment { |
New file |
| | |
| | | package com.duqing.missions.ui.main.home; |
| | | |
| | | import android.os.Bundle; |
| | | import android.util.Log; |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.widget.ImageView; |
| | | import android.widget.TextView; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | import androidx.lifecycle.Observer; |
| | | import androidx.lifecycle.ViewModelProvider; |
| | | import androidx.recyclerview.widget.GridLayoutManager; |
| | | import androidx.recyclerview.widget.LinearLayoutManager; |
| | | import androidx.recyclerview.widget.RecyclerView; |
| | | |
| | | import com.duqing.missions.MainActivity; |
| | | import com.duqing.missions.base.BaseFragment; |
| | | import com.duqing.missions.databinding.FragmentHomeBinding; |
| | | import com.duqing.missions.ui.main.home.adapter.MissiontTopAdapter; |
| | | import com.duqing.missions.ui.main.home.model.MissionDesc; |
| | | import com.scwang.smart.refresh.footer.ClassicsFooter; |
| | | import com.scwang.smart.refresh.header.ClassicsHeader; |
| | | import com.scwang.smart.refresh.layout.SmartRefreshLayout; |
| | | import com.scwang.smart.refresh.layout.api.RefreshLayout; |
| | | import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; |
| | | |
| | | import java.util.List; |
| | | |
| | | public class HomeFragment extends BaseFragment<MainActivity,FragmentHomeBinding> { |
| | | |
| | | private HomeViewModel homeViewModel; |
| | | final String TAG = "HomeFragment"; |
| | | |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class); |
| | | final SmartRefreshLayout smartRefresh = binding.smartRefresh; |
| | | smartRefresh.setRefreshHeader(new ClassicsHeader(getContext())); |
| | | smartRefresh.setRefreshFooter(new ClassicsFooter(getContext())); |
| | | final TextView textView = binding.textRecommend; |
| | | final ImageView imgSearch = binding.imgSearch; |
| | | RecyclerView recyclerClassify = binding.recyclerClassify; |
| | | RecyclerView recyclerTop = binding.recyclerTop; |
| | | final RecyclerView recyclerRecommend = binding.recyclerRecommend; |
| | | recyclerRecommend.setLayoutManager(new LinearLayoutManager(getContext())); |
| | | LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); |
| | | layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); |
| | | recyclerClassify.setLayoutManager(layoutManager); |
| | | recyclerTop.setLayoutManager(new GridLayoutManager(getContext(),3)); |
| | | smartRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { |
| | | @Override |
| | | public void onLoadMore(@NonNull RefreshLayout refreshLayout) { |
| | | homeViewModel.onLoadMore(); |
| | | } |
| | | |
| | | @Override |
| | | public void onRefresh(@NonNull RefreshLayout refreshLayout) { |
| | | homeViewModel.onRefresh(); |
| | | } |
| | | }); |
| | | final MissiontTopAdapter topAdapter = new MissiontTopAdapter(); |
| | | recyclerTop.setAdapter(topAdapter); |
| | | homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { |
| | | @Override |
| | | public void onChanged(@Nullable String s) { |
| | | textView.setText(s); |
| | | } |
| | | }); |
| | | homeViewModel.getMissions().observe(getViewLifecycleOwner(), new Observer<List<MissionDesc>>() { |
| | | @Override |
| | | public void onChanged(List<MissionDesc> missionDescs) { |
| | | smartRefresh.finishRefresh(); |
| | | smartRefresh.finishLoadMore(); |
| | | topAdapter.setData(missionDescs); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | @Nullable |
| | | @Override |
| | | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { |
| | | Log.e(TAG,"onCreateView"); |
| | | return super.onCreateView(inflater, container, savedInstanceState); |
| | | } |
| | | |
| | | @Override |
| | | public void onResume() { |
| | | super.onResume(); |
| | | Log.e(TAG,"onResume"); |
| | | } |
| | | |
| | | @Override |
| | | public void onPause() { |
| | | super.onPause(); |
| | | Log.e(TAG,"onPause"); |
| | | } |
| | | |
| | | @Override |
| | | public void onStop() { |
| | | super.onStop(); |
| | | Log.e(TAG,"onStop"); |
| | | } |
| | | |
| | | @Override |
| | | public void onDestroyView() { |
| | | super.onDestroyView(); |
| | | Log.e(TAG,"onDestroyView"); |
| | | } |
| | | } |
New file |
| | |
| | | package com.duqing.missions.ui.main.home; |
| | | |
| | | import androidx.lifecycle.LiveData; |
| | | import androidx.lifecycle.MutableLiveData; |
| | | import androidx.lifecycle.ViewModel; |
| | | |
| | | import com.duqing.missions.ui.main.home.model.MissionDesc; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | public class HomeViewModel extends ViewModel { |
| | | |
| | | private MutableLiveData<String> mText; |
| | | private MutableLiveData<List<MissionDesc>> missions = new MutableLiveData<>(); |
| | | |
| | | public HomeViewModel() { |
| | | mText = new MutableLiveData<>(); |
| | | mText.setValue("This is home fragment"); |
| | | } |
| | | |
| | | public LiveData<String> getText() { |
| | | return mText; |
| | | } |
| | | |
| | | public MutableLiveData<List<MissionDesc>> getMissions() { |
| | | return missions; |
| | | } |
| | | |
| | | public void onRefresh(){ |
| | | List<MissionDesc> list = new ArrayList<>(); |
| | | list.add(new MissionDesc()); |
| | | list.add(new MissionDesc()); |
| | | list.add(new MissionDesc()); |
| | | list.add(new MissionDesc()); |
| | | missions.setValue(list); |
| | | } |
| | | |
| | | public void onLoadMore(){ |
| | | List<MissionDesc> list = missions.getValue(); |
| | | list.add(new MissionDesc()); |
| | | list.add(new MissionDesc()); |
| | | list.add(new MissionDesc()); |
| | | list.add(new MissionDesc()); |
| | | missions.postValue(list); |
| | | } |
| | | } |
New file |
| | |
| | | package com.duqing.missions.ui.main.home.adapter; |
| | | |
| | | import com.duqing.missions.MainActivity; |
| | | import com.duqing.missions.base.BaseAdapter; |
| | | import com.duqing.missions.databinding.HomeItemTopBinding; |
| | | import com.duqing.missions.ui.main.home.model.MissionDesc; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class MissiontTopAdapter extends BaseAdapter<HomeItemTopBinding, MainActivity, MissionDesc> { |
| | | |
| | | |
| | | @Override |
| | | protected void bindView(ViewBindHolder holder, MissionDesc data, int position) { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.duqing.missions.ui.main.home.model; |
| | | |
| | | /** |
| | | * 任务列表数据数据 |
| | | * Created by Administrator on 2021/10/27 0027. |
| | | */ |
| | | public class MissionDesc { |
| | | public String title,type,label; |
| | | public double price; |
| | | public int participants,remaining,total; |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.ui.main.home.model; |
| | | |
| | | import androidx.lifecycle.ViewModel; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class TopItemViewModel extends ViewModel { |
| | | |
| | | |
| | | } |
File was renamed from app/src/main/java/com/duqing/missions/ui/notifications/NotificationsFragment.java |
| | |
| | | package com.duqing.missions.ui.notifications; |
| | | package com.duqing.missions.ui.main.notifications; |
| | | |
| | | import android.os.Bundle; |
| | | import android.view.LayoutInflater; |
File was renamed from app/src/main/java/com/duqing/missions/ui/notifications/NotificationsViewModel.java |
| | |
| | | package com.duqing.missions.ui.notifications; |
| | | package com.duqing.missions.ui.main.notifications; |
| | | |
| | | import androidx.lifecycle.LiveData; |
| | | import androidx.lifecycle.MutableLiveData; |
New file |
| | |
| | | package com.duqing.missions.util; |
| | | |
| | | import android.Manifest; |
| | | import android.annotation.SuppressLint; |
| | | import android.app.Activity; |
| | | import android.content.Context; |
| | | import android.content.pm.PackageManager; |
| | | import android.graphics.Point; |
| | | import android.os.Build; |
| | | import android.provider.Settings; |
| | | import android.telephony.TelephonyManager; |
| | | import android.text.TextUtils; |
| | | import android.util.DisplayMetrics; |
| | | import android.util.Log; |
| | | import android.view.Display; |
| | | import android.view.WindowManager; |
| | | |
| | | import androidx.core.app.ActivityCompat; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.lang.reflect.Method; |
| | | import java.math.BigDecimal; |
| | | |
| | | |
| | | /** |
| | | * Created by EDZ on 2018/1/30. |
| | | */ |
| | | public class DeviceUtil { |
| | | public static final String TAG = "DeviceUtil"; |
| | | |
| | | /** |
| | | * 设备信息 |
| | | * |
| | | * @param context |
| | | */ |
| | | public static void getDisplay(Context context) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("Version code is \n"); |
| | | sb.append("设备的Android版本号:");//设备的Android版本号 |
| | | sb.append(getSDKInt() + " " + getSDKVersion() + "\t");//设备的Android版本号 |
| | | sb.append("设备型号:");//设备型号 |
| | | sb.append(getDeviceModel() + "\t");//设备型号 |
| | | sb.append("设备厂商:");//设备型号 |
| | | sb.append(getDeviceBrand() + "\t");//设备型号 |
| | | sb.append("程序版本号:" + getAppVersionCode(context) + " " + getAppVersionName(context) + "\t");//程序版本号 |
| | | sb.append("设备唯一标识符:" + getSerialNumber(context)); |
| | | sb.append("\n设备imei:" + getIMEI(context)); |
| | | String str = sb.toString() + " \n"; |
| | | str += getDisplayInfomation(context) + " \n"; |
| | | str += getDensity(context) + " \n"; |
| | | str += "屏幕大小:" + getScreenInch(context) + "英寸 \n"; |
| | | str += getAndroiodScreenProperty(context) + "\n"; |
| | | Log.i(TAG, str); |
| | | } |
| | | |
| | | /** |
| | | * Double类型保留指定位数的小数,返回double类型(四舍五入) |
| | | * newScale 为指定的位数 |
| | | */ |
| | | private static double formatDouble(double d, int newScale) { |
| | | BigDecimal bd = new BigDecimal(d); |
| | | return bd.setScale(newScale, BigDecimal.ROUND_HALF_UP).doubleValue(); |
| | | } |
| | | |
| | | /** |
| | | * 设备型号 |
| | | * @return |
| | | */ |
| | | public static String getDeviceModel() { |
| | | return Build.MODEL; |
| | | } |
| | | |
| | | /** |
| | | * 设备厂商 |
| | | * @return |
| | | */ |
| | | public static String getDeviceBrand() { |
| | | return Build.BRAND; |
| | | } |
| | | |
| | | /** |
| | | * 设备的Android版本号 |
| | | * @return |
| | | */ |
| | | public static int getSDKInt() { |
| | | return Build.VERSION.SDK_INT; |
| | | } |
| | | |
| | | /** |
| | | * 设备的Android版本号 |
| | | * @return |
| | | */ |
| | | public static String getSDKVersion() { |
| | | return Build.VERSION.RELEASE; |
| | | } |
| | | |
| | | /** |
| | | * 程序版本号 |
| | | * @param context |
| | | * @return |
| | | */ |
| | | public static int getAppVersionCode(Context context) { |
| | | try { |
| | | return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode; |
| | | } catch (PackageManager.NameNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return 1; |
| | | } |
| | | |
| | | /** |
| | | * 程序版本号 |
| | | * |
| | | * @param context |
| | | * @return |
| | | */ |
| | | public static String getAppVersionName(Context context) { |
| | | try { |
| | | return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; |
| | | } catch (PackageManager.NameNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | /** |
| | | * 屏幕像素px |
| | | */ |
| | | @SuppressLint("NewApi") |
| | | public static String getDisplayInfomation(Context context) { |
| | | Point point = new Point(); |
| | | ((Activity) context).getWindowManager().getDefaultDisplay().getSize(point); |
| | | Log.d(TAG, "the screen size is " + point.toString()); |
| | | ((Activity) context).getWindowManager().getDefaultDisplay().getRealSize(point); |
| | | Log.d(TAG, "the screen real size is " + point.toString()); |
| | | return point.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 屏幕信息 |
| | | * @param context |
| | | * @return |
| | | */ |
| | | public static String getAndroiodScreenProperty(Context context) { |
| | | int width = getScreenPixel(context).widthPixels; // 屏幕宽度(像素) |
| | | int height = getScreenPixel(context).heightPixels; // 屏幕高度(像素) |
| | | float density = getDensity(getScreenPixel(context)); // 屏幕密度(0.75 / 1.0 / 1.5) |
| | | int densityDpi = getDpi(context); // 屏幕密度dpi(120 / 160 / 240) |
| | | // 屏幕宽度算法:屏幕宽度(像素)/屏幕密度 |
| | | int screenWidth = getDp(context)[0]; // 屏幕宽度(dp) |
| | | int screenHeight = getDp(context)[1];// 屏幕高度(dp) |
| | | |
| | | |
| | | Log.d("h_bl", "屏幕宽度(像素):" + width); |
| | | Log.d("h_bl", "屏幕高度(像素):" + height); |
| | | Log.d("h_bl", "屏幕密度(0.75 / 1.0 / 1.5):" + density); |
| | | Log.d("h_bl", "屏幕密度dpi(120 / 160 / 240):" + densityDpi); |
| | | Log.d("h_bl", "屏幕宽度(dp):" + screenWidth); // 屏幕适配文件夹(例:layout-sw300dp),是以该属性为准则 |
| | | Log.d("h_bl", "屏幕高度(dp):" + screenHeight); |
| | | |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("屏幕宽度(像素):" + width + "\n"); |
| | | sb.append("屏幕高度(像素):" + height + "\n"); |
| | | sb.append("屏幕密度(0.75 / 1.0 / 1.5):" + density + "\n"); |
| | | sb.append("屏幕密度dpi(120 / 160 / 240):" + densityDpi + "\n"); |
| | | sb.append("屏幕宽度(dp):" + screenWidth + "\n"); |
| | | sb.append("屏幕高度(dp):" + screenHeight + "\n"); |
| | | return sb.toString(); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 通知栏高度 |
| | | * @param context |
| | | * @return |
| | | */ |
| | | public static int getStatusBarHeight(Context context) { |
| | | Class<?> c = null; |
| | | Object obj = null; |
| | | Field field = null; |
| | | int x = 0, statusBarHeight = 0; |
| | | try { |
| | | c = Class.forName("com.android.internal.R$dimen"); |
| | | obj = c.newInstance(); |
| | | field = c.getField("status_bar_height"); |
| | | x = Integer.parseInt(field.get(obj).toString()); |
| | | statusBarHeight = context.getResources().getDimensionPixelSize(x); |
| | | } catch (Exception e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | return statusBarHeight; |
| | | } |
| | | |
| | | /** |
| | | * 屏幕密度dpi |
| | | */ |
| | | public static int getDpi(Context context) { |
| | | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); |
| | | DisplayMetrics dm = new DisplayMetrics(); |
| | | wm.getDefaultDisplay().getMetrics(dm); |
| | | return dm.densityDpi; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 屏幕像素px |
| | | */ |
| | | @SuppressLint("NewApi") |
| | | public static Point getDisplayPixel(Context context) { |
| | | Point point = new Point(); |
| | | ((Activity) context).getWindowManager().getDefaultDisplay().getSize(point); |
| | | Log.d(TAG, "the screen size is " + point.toString()); |
| | | ((Activity) context).getWindowManager().getDefaultDisplay().getRealSize(point); |
| | | Log.d(TAG, "the screen real size is " + point.toString()); |
| | | return point; |
| | | } |
| | | |
| | | /** |
| | | * 屏幕像素px |
| | | */ |
| | | public static DisplayMetrics getScreenPixel(Context context) { |
| | | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); |
| | | DisplayMetrics dm = new DisplayMetrics(); |
| | | wm.getDefaultDisplay().getMetrics(dm); |
| | | return dm; |
| | | } |
| | | |
| | | /** |
| | | * 屏幕dp |
| | | */ |
| | | public static int[] getDp(Context context) { |
| | | int width = getScreenPixel(context).widthPixels; // 屏幕宽度(像素) |
| | | int height = getScreenPixel(context).heightPixels; // 屏幕高度(像素) |
| | | float density = getDensity(getScreenPixel(context)); // 屏幕密度(0.75 / 1.0 / 1.5) |
| | | // 屏幕宽度算法:屏幕宽度(像素)/屏幕密度 |
| | | int screenWidth = (int) (width / density); // 屏幕宽度(dp) |
| | | int screenHeight = (int) (height / density);// 屏幕高度(dp) |
| | | return new int[]{screenWidth, screenHeight}; |
| | | } |
| | | |
| | | /** |
| | | * 屏幕密度 |
| | | */ |
| | | public static float getDensity(DisplayMetrics dm) { |
| | | return dm.density; // 屏幕密度(0.75 / 1.0 / 1.5); |
| | | } |
| | | |
| | | /** |
| | | * 屏幕密度dpi |
| | | */ |
| | | public static String getDensity(Context context) { |
| | | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); |
| | | Log.d(TAG, "Density is " + displayMetrics.density + " densityDpi is " + displayMetrics.densityDpi + " height: " + displayMetrics.heightPixels + |
| | | " width: " + displayMetrics.widthPixels); |
| | | return "Density is " + displayMetrics.density + " densityDpi is " + displayMetrics.densityDpi + " height: " + displayMetrics.heightPixels + |
| | | " width: " + displayMetrics.widthPixels; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 屏幕尺寸inch |
| | | */ |
| | | public static double getScreenInch(Context context) { |
| | | |
| | | try { |
| | | int realWidth = 0, realHeight = 0; |
| | | Display display = ((Activity) context).getWindowManager().getDefaultDisplay(); |
| | | DisplayMetrics metrics = new DisplayMetrics(); |
| | | display.getMetrics(metrics); |
| | | if (Build.VERSION.SDK_INT >= 17) { |
| | | Point size = new Point(); |
| | | display.getRealSize(size); |
| | | realWidth = size.x; |
| | | realHeight = size.y; |
| | | } else if (Build.VERSION.SDK_INT < 17 |
| | | && Build.VERSION.SDK_INT >= 14) { |
| | | Method mGetRawH = Display.class.getMethod("getRawHeight"); |
| | | Method mGetRawW = Display.class.getMethod("getRawWidth"); |
| | | realWidth = (Integer) mGetRawW.invoke(display); |
| | | realHeight = (Integer) mGetRawH.invoke(display); |
| | | } else { |
| | | realWidth = metrics.widthPixels; |
| | | realHeight = metrics.heightPixels; |
| | | } |
| | | |
| | | return formatDouble(Math.sqrt((realWidth / metrics.xdpi) * (realWidth / metrics.xdpi) + (realHeight / metrics.ydpi) * (realHeight / metrics.ydpi)), 1); |
| | | |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * dp获取dip |
| | | * @param dp |
| | | * @return |
| | | */ |
| | | public static int convertDpToPixel(float dp, Context context) { |
| | | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); |
| | | return (int) (dp * displayMetrics.density); |
| | | } |
| | | |
| | | /*** |
| | | * px获取dip |
| | | * @param pixel |
| | | * @return |
| | | */ |
| | | public static int convertPixelToDp(int pixel, Context context) { |
| | | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); |
| | | return (int) (pixel / displayMetrics.density); |
| | | } |
| | | |
| | | public static String getSerialNumber(Context context) { |
| | | String serial = ""; |
| | | try { |
| | | if (Build.VERSION.SDK_INT >= 28) {//9.0+ |
| | | if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { |
| | | Log.i(TAG, "getMEID meid: READ_PHONE_STATE" ); |
| | | ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_PHONE_STATE}, 1567); |
| | | } else { |
| | | serial = Build.getSerial(); |
| | | } |
| | | } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+ |
| | | serial = Build.SERIAL; |
| | | } else {//8.0- |
| | | Class<?> c = Class.forName("android.os.SystemProperties"); |
| | | Method get = c.getMethod("get", String.class); |
| | | serial = (String) get.invoke(c, "ro.serialno"); |
| | | } |
| | | } catch (Exception e) { |
| | | Log.e("e", "读取设备序列号异常:" + e.toString()); |
| | | } |
| | | return serial; |
| | | } |
| | | |
| | | public static String getIMEI(Context context) { |
| | | String deviceId = ""; |
| | | TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); |
| | | if (null != tm) { |
| | | if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { |
| | | Log.i(TAG, "getMEID meid: READ_PHONE_STATE" ); |
| | | ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_PHONE_STATE}, 1567); |
| | | } else { |
| | | if (tm.getDeviceId() != null) { |
| | | deviceId = tm.getDeviceId(); |
| | | } else { |
| | | deviceId = Settings.Secure.getString(context.getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID); |
| | | } |
| | | } |
| | | Log.d("deviceId--->", deviceId); |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | public static String getMEID() { |
| | | try { |
| | | Class clazz = Class.forName("android.os.SystemProperties"); |
| | | Method method = clazz.getMethod("get", String.class, String.class); |
| | | |
| | | String meid = (String) method.invoke(null, "ril.cdma.meid", ""); |
| | | if (!TextUtils.isEmpty(meid)) { |
| | | Log.d(TAG, "getMEID meid: " + meid); |
| | | return meid; |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | Log.w(TAG, "getMEID error : " + e.getMessage()); |
| | | } |
| | | return ""; |
| | | } |
| | | } |
New file |
| | |
| | | package com.duqing.missions.util; |
| | | |
| | | import android.util.Log; |
| | | |
| | | import com.duqing.missions.BuildConfig; |
| | | |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-4-5. |
| | | */ |
| | | public class MyLog { |
| | | |
| | | |
| | | public static void i(String tag,String msg){ |
| | | if(BuildConfig.DEBUG) { |
| | | Log.i(tag, BuildConfig.BUILD_TYPE +" "+ msg); |
| | | } |
| | | } |
| | | |
| | | public static void e(String tag,String msg){ |
| | | if(BuildConfig.DEBUG) { |
| | | Log.e(tag, msg); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void d(String tag,String msg){ |
| | | if(BuildConfig.DEBUG) { |
| | | Log.d(tag, msg); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static void v(String tag,String msg){ |
| | | if(BuildConfig.DEBUG) { |
| | | Log.v(tag, msg); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.util; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by Administrator on 2018/5/25. |
| | | */ |
| | | |
| | | public abstract class ResPonse<T> implements Serializable { |
| | | |
| | | public abstract void doSuccess(T obj); |
| | | |
| | | public void doError(T obj){}; |
| | | |
| | | } |
New file |
| | |
| | | package com.duqing.missions.util; |
| | | |
| | | import android.content.Context; |
| | | import android.content.SharedPreferences; |
| | | |
| | | import androidx.collection.ArraySet; |
| | | |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Created by Administrator on 2021/10/28 0028. |
| | | */ |
| | | public class SpUtils { |
| | | |
| | | static SpUtils instance; |
| | | |
| | | /** |
| | | * 获取SP实例 |
| | | * |
| | | * @return {@link SpUtils} |
| | | */ |
| | | public static SpUtils getInstance() { |
| | | if(instance == null){ |
| | | instance = new SpUtils(); |
| | | } |
| | | return instance; |
| | | } |
| | | |
| | | |
| | | public final String PROJECT = "project"; |
| | | public final String USER = "user"; |
| | | |
| | | |
| | | public boolean clearData(Context context, String keyShared){ |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | return settings.edit().clear().commit(); |
| | | } |
| | | |
| | | |
| | | public boolean clearData(Context context, String key, String keyShared){ |
| | | putString(context,key,null,keyShared); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * remove key preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public void removeKey(Context context, String key, String keyShared){ |
| | | |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.remove(key); |
| | | } |
| | | |
| | | /** |
| | | * remove value preferences |
| | | * |
| | | * @param context |
| | | * @param value The name of the preference to modify |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public void removeValue(Context context, String value, String keyShared){ |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.remove(value); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * put string preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public boolean putString(Context context, String key, String value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putString(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get string preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or null. Throws ClassCastException if there is a preference with this |
| | | * name that is not a string |
| | | * @see #getString(Context, String, String) |
| | | */ |
| | | public String getString(Context context, String key, String keyShared) { |
| | | return getString(context, key, null,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get string preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a string |
| | | */ |
| | | public String getString(Context context, String key, String defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | return settings.getString(key, defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * put int preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public boolean putInt(Context context, String key, int value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putInt(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get int preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this |
| | | * name that is not a int |
| | | */ |
| | | public int getInt(Context context, String key, String keyShared) { |
| | | return getInt(context, key, -1,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get int preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a int |
| | | */ |
| | | public int getInt(Context context, String key, int defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getInt(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Integer.parseInt(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put long preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public boolean putLong(Context context, String key, long value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putLong(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get long preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this |
| | | * name that is not a long |
| | | */ |
| | | public long getLong(Context context, String key, String keyShared) { |
| | | return getLong(context, key, -1,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get long preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a long |
| | | */ |
| | | public long getLong(Context context, String key, long defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getLong(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Long.parseLong(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put float preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public boolean putFloat(Context context, String key, float value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putFloat(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get float preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this |
| | | * name that is not a float |
| | | */ |
| | | public float getFloat(Context context, String key, String keyShared) { |
| | | return getFloat(context, key, -1,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get float preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a float |
| | | */ |
| | | public float getFloat(Context context, String key, float defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getFloat(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Float.parseFloat(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public boolean putBoolean(Context context, String key, boolean value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putBoolean(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences, default is false |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or false. Throws ClassCastException if there is a preference with this |
| | | * name that is not a boolean |
| | | */ |
| | | public boolean getBoolean(Context context, String key, String keyShared) { |
| | | return getBoolean(context, key, false,keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a boolean |
| | | */ |
| | | public boolean getBoolean(Context context, String key, boolean defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | try { |
| | | return settings.getBoolean(key, defaultValue); |
| | | }catch (ClassCastException e){ |
| | | try { |
| | | return Boolean.parseBoolean(settings.getString(key,defaultValue+"")); |
| | | }catch (NumberFormatException en){ |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * put boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to modify |
| | | * @param value The new value for the preference , the value of set ,canot be the other class out of java collection |
| | | * @return True if the new values were successfully written to persistent storage. |
| | | */ |
| | | public boolean putStringSet(Context context, String key, Set value, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | SharedPreferences.Editor editor = settings.edit(); |
| | | editor.putStringSet(key, value); |
| | | return editor.commit(); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences, default is false |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @return The preference value if it exists, or false. Throws ClassCastException if there is a preference with this |
| | | * name that is not a boolean 获取出来的值最终被转换为hashset类型 |
| | | */ |
| | | public Set getStringSet(Context context, String key, String keyShared) { |
| | | return getStringSet(context, key,new ArraySet(),keyShared); |
| | | } |
| | | |
| | | /** |
| | | * get boolean preferences |
| | | * |
| | | * @param context |
| | | * @param key The name of the preference to retrieve |
| | | * @param defaultValue Value to return if this preference does not exist |
| | | * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with |
| | | * this name that is not a boolean 获取出来的值最终被转换为hashset类型 |
| | | */ |
| | | public Set getStringSet(Context context, String key, Set defaultValue, String keyShared) { |
| | | SharedPreferences settings = context.getSharedPreferences(keyShared, Context.MODE_PRIVATE); |
| | | return settings.getStringSet(key, defaultValue); |
| | | } |
| | | |
| | | public boolean getBooleanValOfUser(Context context, String key){ |
| | | return getBoolean(context,key,false,USER); |
| | | } |
| | | |
| | | public boolean getBooleanValOfProject(Context context, String key){ |
| | | return getBoolean(context,key,false,PROJECT); |
| | | } |
| | | |
| | | public String getStringValOfUser(Context context, String key){ |
| | | return getString(context,key,"",USER); |
| | | } |
| | | |
| | | public String getStringValOfProject(Context context, String key){ |
| | | return getString(context,key,"",PROJECT); |
| | | } |
| | | |
| | | public int getIntValOfProject(Context context, String key){ |
| | | return getInt(context,key,0,PROJECT); |
| | | } |
| | | |
| | | public Long getLongValOfProject(Context context, String key){ |
| | | return getLong(context,key,0,PROJECT); |
| | | } |
| | | |
| | | public float getFloatValOfProject(Context context, String key){ |
| | | return getFloat(context,key,0,PROJECT); |
| | | } |
| | | |
| | | public Set getStringSetValOfProject(Context context, String key){ |
| | | return getStringSet(context,key,PROJECT); |
| | | } |
| | | |
| | | public int getIntValOfUser(Context context, String key){ |
| | | return getInt(context,key,0,USER); |
| | | } |
| | | |
| | | public Long getLongValOfUser(Context context, String key){ |
| | | return getLong(context,key,0,USER); |
| | | } |
| | | |
| | | public float getFloatValOfUser(Context context, String key){ |
| | | return getFloat(context,key,0,USER); |
| | | } |
| | | |
| | | public Set getStringSetValOfUser(Context context, String key){ |
| | | return getStringSet(context,key,USER); |
| | | } |
| | | |
| | | |
| | | public void putBooleanValOfUser(Context context, String key ,Boolean value){ |
| | | putBoolean(context,key,value,USER); |
| | | } |
| | | |
| | | public void putBooleanValOfProject(Context context, String key,Boolean value){ |
| | | putBoolean(context,key,value,PROJECT); |
| | | } |
| | | |
| | | public void putStringValOfUser(Context context,String key,String value){ |
| | | putString(context,key,value,USER); |
| | | } |
| | | |
| | | public void putStringValOfProject(Context context,String key,String value){ |
| | | putString(context,key,value,PROJECT); |
| | | } |
| | | |
| | | public void putIntValOfProject(Context context,String key,int value){ |
| | | putInt(context,key,value,PROJECT); |
| | | } |
| | | |
| | | public void putLongValOfProject(Context context,String key,long value){ |
| | | putLong(context,key,value,PROJECT); |
| | | } |
| | | |
| | | public void putFloatValOfProject(Context context,String key,float value){ |
| | | putFloat(context,key,value,PROJECT); |
| | | } |
| | | |
| | | public void putStringSetValOfProject(Context context,String key,Set value){ |
| | | putStringSet(context,key,value,PROJECT); |
| | | } |
| | | |
| | | public void putIntValOfUser(Context context,String key,int value){ |
| | | putInt(context,key,value,USER); |
| | | } |
| | | |
| | | public void putLongValOfUser(Context context,String key,long value){ |
| | | putLong(context,key,value,USER); |
| | | } |
| | | |
| | | public void putFloatValOfUser(Context context,String key,float value){ |
| | | putFloat(context,key,value,USER); |
| | | } |
| | | |
| | | public void putStringSetValOfUser(Context context,String key, Set value){ |
| | | putStringSet(context,key,value,USER); |
| | | } |
| | | |
| | | |
| | | public void removeUserKey(Context context, String key){ |
| | | removeKey(context,key,USER); |
| | | } |
| | | |
| | | public void removeProjectKey(Context context, String key){ |
| | | removeKey(context,key,PROJECT); |
| | | } |
| | | |
| | | public void removeUserValue(Context context, String Value){ |
| | | removeValue(context,Value,USER); |
| | | } |
| | | |
| | | public void removeProjectValue(Context context, String Value){ |
| | | removeValue(context,Value,PROJECT); |
| | | } |
| | | |
| | | |
| | | public void clearProjectData(Context context){ |
| | | clearData(context,PROJECT); |
| | | } |
| | | public void clearUserData(Context context){ |
| | | clearData(context,USER); |
| | | } |
| | | |
| | | } |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <androidx.constraintlayout.widget.ConstraintLayout |
| | | <LinearLayout |
| | | xmlns:android="http://schemas.android.com/apk/res/android" |
| | | xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | android:id="@+id/container" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" > |
| | | |
| | | <com.google.android.material.bottomnavigation.BottomNavigationView |
| | | android:id="@+id/nav_view" |
| | | android:layout_width="0dp" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginStart="0dp" |
| | | android:layout_marginEnd="0dp" |
| | | android:background="?android:attr/windowBackground" |
| | | app:layout_constraintBottom_toBottomOf="parent" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | app:menu="@menu/bottom_nav_menu"/> |
| | | android:layout_height="match_parent" |
| | | android:orientation="vertical"> |
| | | |
| | | <fragment |
| | | android:id="@+id/nav_host_fragment_activity_main" |
| | | android:name="androidx.navigation.fragment.NavHostFragment" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:layout_weight="1" |
| | | app:defaultNavHost="true" |
| | | app:layout_constraintBottom_toTopOf="@id/nav_view" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" |
| | | app:layout_constraintTop_toTopOf="parent" |
| | | app:navGraph="@navigation/mobile_navigation" |
| | | /> |
| | | |
| | | </androidx.constraintlayout.widget.ConstraintLayout> |
| | | <com.google.android.material.bottomnavigation.BottomNavigationView |
| | | android:id="@+id/nav_view" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:background="?android:attr/windowBackground" |
| | | app:menu="@menu/bottom_nav_menu"/> |
| | | |
| | | </LinearLayout> |
| | |
| | | xmlns:tools="http://schemas.android.com/tools" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | tools:context=".ui.dashboard.DashboardFragment" > |
| | | tools:context=".ui.main.dashboard.DashboardFragment" > |
| | | |
| | | <com.google.android.material.tabs.TabLayout |
| | | android:id="@+id/tablayout" |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <LinearLayout |
| | | <androidx.constraintlayout.widget.ConstraintLayout |
| | | xmlns:android="http://schemas.android.com/apk/res/android" |
| | | xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | xmlns:tools="http://schemas.android.com/tools" |
| | | tools:ignore="MissingConstraints" |
| | | tools:context=".ui.home.HomeFragment" |
| | | tools:context=".ui.main.home.HomeFragment" |
| | | android:layout_width="match_parent" |
| | | android:orientation="vertical" |
| | | android:layout_height="match_parent"> |
| | |
| | | android:id="@+id/img_search" |
| | | android:layout_width="39dp" |
| | | android:layout_height="35dp" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintTop_toTopOf="parent" |
| | | app:layout_constraintBottom_toTopOf="@id/smart_refresh" |
| | | android:src="@android:drawable/ic_search_category_default"/> |
| | | <com.scwang.smart.refresh.layout.SmartRefreshLayout |
| | | android:id="@+id/smart_refresh" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:layout_height="0dp" |
| | | app:layout_constraintTop_toBottomOf="@id/img_search" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintBottom_toBottomOf="parent" |
| | | > |
| | | |
| | | <androidx.constraintlayout.widget.ConstraintLayout |
| | |
| | | android:id="@+id/recycler_top" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:overScrollMode="never" |
| | | app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" |
| | | app:spanCount="3" |
| | | tools:itemCount="3" |
| | |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginTop="10dp" |
| | | android:overScrollMode="never" |
| | | tools:listitem="@layout/home_item_classify" |
| | | app:layout_constraintTop_toBottomOf="@id/recycler_top" |
| | | app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" |
| | |
| | | android:id="@+id/recycler_recommend" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:overScrollMode="never" |
| | | tools:listitem="@layout/homt_item_recommend" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintTop_toBottomOf="@id/text_recommend" |
| | |
| | | </androidx.constraintlayout.widget.ConstraintLayout> |
| | | </com.scwang.smart.refresh.layout.SmartRefreshLayout> |
| | | |
| | | </LinearLayout> |
| | | </androidx.constraintlayout.widget.ConstraintLayout> |
| | |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:background="@color/white_2" |
| | | tools:context=".ui.notifications.NotificationsFragment"> |
| | | tools:context=".ui.main.notifications.NotificationsFragment"> |
| | | |
| | | <androidx.constraintlayout.widget.ConstraintLayout |
| | | android:layout_width="match_parent" |
| | |
| | | |
| | | <fragment |
| | | android:id="@+id/navigation_home" |
| | | android:name="com.duqing.missions.ui.home.HomeFragment" |
| | | android:name="com.duqing.missions.ui.main.home.HomeFragment" |
| | | android:label="@string/title_home" |
| | | tools:layout="@layout/fragment_home" /> |
| | | |
| | | <fragment |
| | | android:id="@+id/navigation_dashboard" |
| | | android:name="com.duqing.missions.ui.dashboard.DashboardFragment" |
| | | android:name="com.duqing.missions.ui.main.dashboard.DashboardFragment" |
| | | android:label="@string/title_dashboard" |
| | | tools:layout="@layout/fragment_dashboard" /> |
| | | |
| | | <fragment |
| | | android:id="@+id/navigation_notifications" |
| | | android:name="com.duqing.missions.ui.notifications.NotificationsFragment" |
| | | android:name="com.duqing.missions.ui.main.notifications.NotificationsFragment" |
| | | android:label="@string/title_notifications" |
| | | tools:layout="@layout/fragment_notifications" /> |
| | | </navigation> |