4 Komitmen 7548ad0749 ... d28e17bc58

Pembuat SHA1 Pesan Tanggal
  huwanxiao d28e17bc58 update: 打印格式中新增工艺(待测试) 1 tahun lalu
  huwanxiao ca218af0c7 add: 大小版本更新 1 tahun lalu
  huwanxiao febe55521d 1 1 tahun lalu
  huwanxiao a726afbd9d add: 全局异常上传、切换网络 1 tahun lalu

+ 78 - 56
app/src/main/AndroidManifest.xml

@@ -5,7 +5,7 @@
     <!-- 应用使用蓝牙的权限 -->
     <uses-permission android:name="android.permission.BLUETOOTH" /> <!-- 在android 6.0之后要用蓝牙还需要添加一个模糊定位的权限 -->
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 扫描蓝牙设备或者操作蓝牙设置 -->
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@@ -14,6 +14,11 @@
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
     <uses-feature android:name="android.hardware.camera.any" />
 
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+
     <application
         android:largeHeap="true"
         android:name=".BaseApplication"
@@ -26,84 +31,101 @@
         android:usesCleartextTraffic="true"
         android:theme="@style/AppTheme"
         tools:ignore="GoogleAppIndexingWarning">
-
-        <activity android:name=".MainActivity"
-            android:screenOrientation="portrait"
+        <activity
+            android:name=".MainActivity"
             android:hardwareAccelerated="true"
-            android:windowSoftInputMode="adjustPan" >
+            android:screenOrientation="portrait"
+            android:windowSoftInputMode="adjustPan">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <activity
             android:name=".activity.CaremaActivity"
             android:screenOrientation="portrait"
-            android:windowSoftInputMode="adjustPan" >
-        </activity>
-
+            android:windowSoftInputMode="adjustPan"></activity>
         <activity
             android:name=".NewMainActivity"
             android:screenOrientation="portrait"
-            android:windowSoftInputMode="adjustPan" >
-        </activity>
+            android:windowSoftInputMode="adjustPan"></activity>
         <activity
             android:name=".activity.SettingActivity"
             android:screenOrientation="portrait"
-            android:windowSoftInputMode="adjustPan" >
-        </activity>
-        <activity android:name=".activity.WaitActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.SaveTrademarkActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.UpTrademarkActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.StockSearchActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.UpTrademarkScanActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.ApplyTrademarkActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.ApplyTrademarkSelectActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.RepairTrademarkSelectActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.RepairTrademarkCompleteActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.FullApplyTrademarkActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.FullApplyTrademarkSelectActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.VerifyTrademarkActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.RepairTrademarkActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.RecycleTrademarkActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.ApplyTrademarkCompleteActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.RecycleTrademarkSelectActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.LoginActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.WaitCloseDoorActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.FullApplyTrademarkScanActivity"
-            android:screenOrientation="portrait"/>
-        <activity android:name=".activity.AdActivity"
-            android:screenOrientation="portrait"/>
+            android:windowSoftInputMode="adjustPan"></activity>
+        <activity
+            android:name=".activity.WaitActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.SaveTrademarkActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.UpTrademarkActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.StockSearchActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.UpTrademarkScanActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.ApplyTrademarkActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.ApplyTrademarkSelectActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.RepairTrademarkSelectActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.RepairTrademarkCompleteActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.FullApplyTrademarkActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.FullApplyTrademarkSelectActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.VerifyTrademarkActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.RepairTrademarkActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.RecycleTrademarkActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.ApplyTrademarkCompleteActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.RecycleTrademarkSelectActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.LoginActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.WaitCloseDoorActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.FullApplyTrademarkScanActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".activity.AdActivity"
+            android:screenOrientation="portrait" />
 
         <provider
             android:name="androidx.core.content.FileProvider"
             android:authorities="${applicationId}.fileprovider"
             android:exported="false"
-            tools:replace="android:authorities"
-            android:grantUriPermissions="true">
+            android:grantUriPermissions="true"
+            tools:replace="android:authorities">
             <meta-data
                 android:name="android.support.FILE_PROVIDER_PATHS"
                 android:resource="@xml/provider_paths"
-                tools:replace="android:resource"
-                />
+                tools:replace="android:resource" />
         </provider>
     </application>
+
 </manifest>

+ 7 - 0
app/src/main/java/com/naz/sdkdemo/AppConfig.java

@@ -9,6 +9,13 @@ import com.naz.sdkdemo.utils.SPUtils;
  */
 public class AppConfig {
     public static final boolean IS_DEBUG =true;//true打印数据
+
+    public static final String APP_VERSION_CODE = "2.24.0918";//true打印数据
+    public static final String APP_VERSION = "正式包-" + APP_VERSION_CODE;//true打印数据
+    public static final String REMARK = "1. 新增: 大小版本更新\n" +
+            "2.新增: 添加全局日志的捕获\n" +
+            "3.更新: 打印格式的调整";
+
     // public  static String INTERFACE_URL = "http://121.37.173.82:82/";//线上
 //    public  static String INTERFACE_URL = "http://121.41.102.225:82/";//测试
     // public static String INTERFACE_URL = "";//正式

+ 4 - 3
app/src/main/java/com/naz/sdkdemo/BaseApplication.java

@@ -89,6 +89,7 @@ public class BaseApplication extends Application {
         MultiDex.install(this);
         BleManager.getInstance().init(getApplication());
         BleManager.getInstance()
+                .setReConnectCount(1, 5000)
                 .enableLog(true)
                 .setSplitWriteNum(20)
                 .setConnectOverTime(15000)
@@ -138,17 +139,17 @@ public class BaseApplication extends Application {
                 e.printStackTrace();
             }
         }
-
+        String formatData = formattedTime + " " + AppConfig.APP_VERSION + "------>>" + data;
         try (BufferedWriter writer = new BufferedWriter(new FileWriter(logFile.getAbsoluteFile(), true))) {
             // 使用true作为FileWriter构造函数的第二个参数,以启用追加模式
-            writer.write(formattedTime + " " + data);
+            writer.write(formatData);
             writer.newLine();  // 如果你想在数据后添加换行符
             Log.e("--------->>>", "--------->>>数据已成功追加到文件中");
         } catch (IOException e) {
             Log.e("--------->>>", "--------->>>追加日志发生错误");
         }
 
-        return formattedTime + " " + data;
+        return formatData;
     }
 
     public static String readDataFromLogFile() {

File diff ditekan karena terlalu besar
+ 533 - 187
app/src/main/java/com/naz/sdkdemo/MainActivity.java


+ 16 - 2
app/src/main/java/com/naz/sdkdemo/base/BaseActivity.java

@@ -5,6 +5,7 @@ import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.view.View;
 
 import com.kaopiz.kprogresshud.KProgressHUD;
@@ -26,6 +27,8 @@ import butterknife.ButterKnife;
 public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener {
     protected TitleBar titleBar;
     private KProgressHUD hud;
+    public String loadingLabel = "";
+    public String loadingDetailLabel = "";
    /* public static RFIDWithUHFUART mReader;*/
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -83,8 +86,19 @@ public abstract class BaseActivity extends AppCompatActivity implements View.OnC
     }
 
     public void showLoading() {
-        if (hud == null) {
-            hud = KProgressHUD.create(this).setStyle(KProgressHUD.Style.SPIN_INDETERMINATE);
+        if(hud == null) {
+            hud = KProgressHUD.create(this)
+                    .setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
+                    .setAnimationSpeed(1)
+                    .setDimAmount(0.5f);
+        }
+        if(!TextUtils.isEmpty(loadingLabel)) {
+            hud.setLabel(loadingLabel);
+            loadingLabel = "";
+        }
+        if(!TextUtils.isEmpty(loadingDetailLabel)) {
+            hud.setDetailsLabel(loadingDetailLabel);
+            loadingDetailLabel = "";
         }
         hud.show();
     }

+ 28 - 0
app/src/main/java/com/naz/sdkdemo/bean/VersionBean.java

@@ -0,0 +1,28 @@
+package com.naz.sdkdemo.bean;
+
+import android.text.TextUtils;
+
+public class VersionBean {
+    public String version;
+    public String load;
+    public String remark;
+    public String type;
+    // 以下的字段为扩展字段
+    public String versionName = "";
+    public String bigVersion = "";
+    public String middleVersion = "";
+    public String smallVersion = "";
+    public String versionCode = "";
+
+    public void clearExtraFields() {
+        versionName = "";
+        bigVersion = "";
+        middleVersion = "";
+        smallVersion = "";
+        versionCode = "";
+    }
+
+    public boolean checkExtraFields() {
+        return !TextUtils.isEmpty(versionName) && !TextUtils.isEmpty(bigVersion) && !TextUtils.isEmpty(middleVersion) && !TextUtils.isEmpty(smallVersion) && !TextUtils.isEmpty(versionCode);
+    }
+}

+ 2 - 0
app/src/main/java/com/naz/sdkdemo/comm/Constants.java

@@ -57,6 +57,8 @@ public class Constants {
     public static final String SERIAL_RATE = "SERIAL_RATE";
     public static final String BLE_LOG_FILE_NAME = "BLE_LOG_FILE_NAME";
     public static final String EXCEPTION_LOG_FILE_NAME = "EXCEPTION_LOG_FILE_NAME";
+    public static final String NETWORK_TYPE = "NETWORK_TYPE";
+    public static final String IS_SHOW_VERSION_UPDATE_DIALOG = "IS_SHOW_VERSION_UPDATE_DIALOG";
 
     public static String mark_speed = "01f4";//500转十进制,高低位
     public static String mark_num = "0001";//1

+ 108 - 0
app/src/main/java/com/naz/sdkdemo/dialog/VersionUpdateDialog.java

@@ -0,0 +1,108 @@
+package com.naz.sdkdemo.dialog;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.naz.sdkdemo.R;
+
+
+public class VersionUpdateDialog extends Dialog implements View.OnClickListener {
+
+
+    private final boolean canCancel;
+    private String btnText;
+    private String str;
+    private OnBtnClickListener onBtnClickListener;
+    private Context context;
+    private Button btn_update;
+    private Button btn_close;
+    private Button btn_no_longer;
+    private TextView tv_content;
+
+
+
+    public VersionUpdateDialog(Context context, OnBtnClickListener onBtnClickListener, String str, boolean canCancel, String btnText) {
+        super(context, R.style.bottom_select_dialog);
+        this.context = context;
+        this.onBtnClickListener = onBtnClickListener;
+        this.str = str;
+        this.canCancel = canCancel;
+        this.btnText = btnText;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Window window = getWindow();
+        window.setGravity(Gravity.CENTER);
+        LayoutInflater inflater = (LayoutInflater) getContext()
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View view = inflater.inflate(R.layout.dialog_version_update, null);
+        // 文本提示
+        tv_content = view.findViewById(R.id.tv_content);
+        tv_content.setText(str);
+        // 不再提示按钮
+        btn_no_longer = view.findViewById(R.id.btn_no_longer);
+        btn_no_longer.setOnClickListener(this);
+        btn_close = view.findViewById(R.id.btn_close);
+        btn_close.setOnClickListener(this);
+        // 立即更新按钮
+        btn_update = view.findViewById(R.id.btn_update);
+        btn_update.setText(btnText);
+        btn_update.setOnClickListener(this);
+        // 弹框大小
+        setContentView(view);
+        FullScreen((Activity) context, this, 0.85);
+        setCanceledOnTouchOutside(canCancel);
+    }
+
+
+    /**
+     * 自定义dialog全屏展示
+     *
+     * @param activity
+     * @param dialog
+     */
+    public static void FullScreen(Activity activity, Dialog dialog, double scale) {
+        WindowManager m = activity.getWindowManager();
+        Display d = m.getDefaultDisplay();  //为获取屏幕宽、高
+        WindowManager.LayoutParams p = dialog.getWindow().getAttributes();  //获取对话框当前的参数值
+        p.height = (int) (d.getHeight() * 0.55);   //高度设置为屏幕的0.3
+        p.width = (int) (d.getWidth() * scale);    //宽度设置为全屏
+        dialog.getWindow().setAttributes(p);     //设置生效
+    }
+
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.btn_update:    // 立即更新
+                onBtnClickListener.OnCommitClickListener(this, view);
+                break;
+            case R.id.btn_close:     // 关闭
+                onBtnClickListener.OnCloseListener(this, view);
+                break;
+            case R.id.btn_no_longer: // 不再提醒
+                onBtnClickListener.OnNoLongerListener(this, view);
+                break;
+
+        }
+    }
+
+    public interface OnBtnClickListener {
+        void OnCommitClickListener(VersionUpdateDialog dialog, View clickView);
+        void OnCloseListener(VersionUpdateDialog dialog, View clickView);
+        void OnNoLongerListener(VersionUpdateDialog dialog, View clickView);
+    }
+}
+

+ 8 - 0
app/src/main/java/com/naz/sdkdemo/http/Api.java

@@ -250,4 +250,12 @@ public class Api {
     public static String UPLOAD_EXCEPTION_LOG(){
         return "https://clouddevice.qingyaokeji.com/api/andriodLog";
     }
+
+    public static String VERSION_INFO_LIST() {
+        return "https://clouddevice.qingyaokeji.com/api/andriodDownload";
+    }
+
+    public static String STABLE_VERSION_INFO() {
+        return "https://clouddevice.qingyaokeji.com/api/androidVersion";
+    }
 }

+ 42 - 0
app/src/main/java/com/naz/sdkdemo/http/ApiHelper.java

@@ -20,6 +20,7 @@ import com.naz.sdkdemo.bean.ScanRecycleInfo;
 import com.naz.sdkdemo.bean.StatusInfo;
 import com.naz.sdkdemo.bean.StockInfo;
 import com.naz.sdkdemo.bean.TrademarkInfo;
+import com.naz.sdkdemo.bean.VersionBean;
 import com.naz.sdkdemo.okgo.callback.DialogCallback;
 import com.naz.sdkdemo.okgo.module.BaseResponse;
 import com.naz.sdkdemo.okgo.module.BaseResponse2;
@@ -162,6 +163,47 @@ public class ApiHelper {
     }
 
 
+    public static void versionInfoList(Activity activity, int type, String packageName, Callback callback) {
+        JSONObject raw = new JSONObject();
+        try {
+            raw.put("type", String.valueOf(type));
+            raw.put("package", packageName);
+        } catch (JSONException e) {
+
+        }
+        OkGo.<BaseResponse2<List<VersionBean>>>post(Api.VERSION_INFO_LIST())
+                .upJson(raw)
+                .tag(activity)
+                .execute(new DialogCallback<BaseResponse2<List<VersionBean>>>(activity, false) {
+                    @Override
+                    public void onSuccess(Response<BaseResponse2<List<VersionBean>>> response) {
+                        if ("200".equals(response.body().status)){
+                            callback.onSuccess(Callback.SUCCESS, null, response.body().data);
+                        }
+                    }
+                });
+    }
+
+    public static void stableVersionInfo(Activity activity, String type, Callback callback) {
+        JSONObject raw = new JSONObject();
+        try {
+            raw.put("type", type);
+        } catch (JSONException e) {
+
+        }
+        OkGo.<BaseResponse2<VersionBean>>post(Api.STABLE_VERSION_INFO())
+                .upJson(raw)
+                .tag(activity)
+                .execute(new DialogCallback<BaseResponse2<VersionBean>>(activity, false) {
+                    @Override
+                    public void onSuccess(Response<BaseResponse2<VersionBean>> response) {
+                        if ("200".equals(response.body().status)){
+                            callback.onSuccess(Callback.SUCCESS, null, response.body().data);
+                        }
+                    }
+                });
+    }
+
     public static void operateRecord(Activity activity, int type, CallbackNew<OperateResult> callback) {
         JSONObject body = new JSONObject();
         try {

+ 133 - 0
app/src/main/java/com/naz/sdkdemo/utils/DownloadService.java

@@ -0,0 +1,133 @@
+package com.naz.sdkdemo.utils;
+
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.naz.sdkdemo.base.BaseActivity;
+import com.naz.sdkdemo.weight.XToast;
+
+import java.io.File;
+import java.io.IOException;
+
+public class DownloadService {  
+  
+    private DownloadManager downloadManager;  
+    private long downloadID;
+    private BaseActivity mActivity;
+    private String TAG = "DownloadService";
+    private String apkName;
+
+    public void downloadApk(Context context, String url) {
+        // 初始化参数
+        mActivity = (BaseActivity) context;
+        String[] split = url.split("/");
+        apkName = split[split.length - 1];
+        downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);  
+        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
+
+        // 设置APK存储位置(注意:Android 10及以上应使用MediaStore或分区存储)
+        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName);
+
+        // apk如果已存在则先删除
+        File apkfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(), apkName);
+        if (apkfile.exists()) {
+            apkfile.delete();
+        }
+
+        // 可选:设置通知可见性、网络类型等  
+        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);  
+  
+        // 将下载请求加入队列  
+        downloadID = downloadManager.enqueue(request);  
+  
+        // 注册广播接收器监听下载状态(可选)  
+        context.registerReceiver(downloadReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));  
+    }  
+  
+    private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {  
+        @Override  
+        public void onReceive(Context context, Intent intent) {  
+            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);  
+            if (id == downloadID) {
+                mActivity.hideLoading();
+                // 下载完成,可以处理APK文件了  
+                // 检查大王椰更新器是否存在
+                boolean isInstalled = isAppInstalled(mActivity, "com.dawangye.booter");
+                if (isInstalled) {
+                    // 应用已安装
+                    Log.d(TAG, "应用已安装");
+                    if(!TextUtils.isEmpty(apkName)) {
+                        installApkSilently();
+                    }
+                } else {
+                    // 应用未安装
+                    Log.d(TAG, "应用未安装");
+                    Uri uri = downloadManager.getUriForDownloadedFile(downloadID);
+                    // 使用uri进行后续操作,如安装APK
+                    installApk(context, uri);
+                }
+                apkName = "";
+                // 别忘了注销广播接收器  
+                context.unregisterReceiver(this);  
+            }  
+        }  
+    };  
+  
+    // 后续你需要实现installApk方法来安装APK
+    public void installApk(Context context, Uri apkUri) {
+        try {
+            // 对于Android N(7.0)及以上版本,使用FileProvider
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                // 这里需要替换为你的FileProvider的authority
+                Intent intent = new Intent(Intent.ACTION_VIEW);
+                intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
+                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivity(intent);
+            }
+        }catch (Exception e) {
+            Log.i(TAG, "installApk: " + e.getMessage());
+            XToast.showToast("安装包下载失败, 请重试");
+        }
+    }
+
+    private void installApkSilently() {
+        try {
+            // 启动启动器
+            Intent launchIntent = mActivity.getPackageManager().getLaunchIntentForPackage("com.dawangye.booter");
+            mActivity.startActivity(launchIntent);
+            // 执行重装命令
+            String cmd = "pm install -r " + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + apkName;
+            ProcessBuilder pb = new ProcessBuilder("su", "-c", cmd);
+            // 启动进程
+            Process process = pb.start();
+            // 等待命令执行完成
+            int exitCode = process.waitFor();
+            if (exitCode == 0) {
+                Log.i(TAG, "重装成功");
+            } else {
+                Log.i(TAG, "重装失败");
+            }
+        } catch (IOException | InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private boolean isAppInstalled(Context context, String packageName) {
+        try {
+            context.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA);
+            return true;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+    }
+}

+ 32 - 0
app/src/main/java/com/naz/sdkdemo/utils/NetworkSpeedTest.java

@@ -0,0 +1,32 @@
+package com.naz.sdkdemo.utils;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class NetworkSpeedTest {
+
+    public interface SpeedTestListener {
+        void onSpeedTestComplete(long netSpeed);
+    }
+
+    public static void testNetSpeed(String url, final SpeedTestListener listener) {
+        new Thread(() -> {
+            try {
+                long startTime = System.currentTimeMillis();
+                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+                connection.setRequestMethod("GET");
+                connection.connect();
+
+                long endTime = System.currentTimeMillis();
+                long duration = endTime - startTime;
+
+                listener.onSpeedTestComplete(duration);
+
+                connection.disconnect();
+            } catch (Exception e) {
+                listener.onSpeedTestComplete(0);
+                e.printStackTrace();
+            }
+        }).start();
+    }
+}

+ 131 - 0
app/src/main/java/com/naz/sdkdemo/utils/NetworkUtil.java

@@ -0,0 +1,131 @@
+package com.naz.sdkdemo.utils;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
+import android.util.Log;
+
+import java.io.IOException;
+
+public class NetworkUtil {
+
+    private Context context;
+    private WifiManager wifiManager;
+    public NetworkUtil(Context context) {
+        wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        this.context = context;
+    }
+
+    // 判断Wi-Fi是否开启
+    public boolean isWifiEnabled() {
+        return wifiManager.isWifiEnabled();
+    }
+
+    // 打开Wi-Fi
+    public void enableWifi() {
+        if (!isWifiEnabled()) {
+            wifiManager.setWifiEnabled(true);
+        }
+    }
+
+    // 关闭Wi-Fi
+    public void disableWifi() {
+        if (isWifiEnabled()) {
+            wifiManager.setWifiEnabled(false);
+        }
+    }
+
+    // 判断Wi-Fi是否连接: 注意开启了但是没有连接的情况
+    public boolean isWifiConnected() {
+        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        return networkInfo != null && networkInfo.isConnected();
+    }
+
+    // 判断移动数据是否开启
+    public boolean isMobileDataConnected(Context context) {
+        ConnectivityManager connectivityManager = (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
+        if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
+            // 旧版本的 API 不区分有线和无线网络
+            // 可以尝试根据连接类型进行判断
+            if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // 设置网络的优先级
+    public void setNetworkPriority(Context context, int type) {
+        if(isEthernetConnected()) {
+            // 设置以太网络优先
+            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+            connectivityManager.setNetworkPreference(type);
+        } else if(isWifiConnected()){
+            // 设置wifi优先
+            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+            connectivityManager.setNetworkPreference(type);
+        } else if (isMobileDataConnected(context)) {
+            // 设置移动网络优先
+            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+            connectivityManager.setNetworkPreference(type);
+        }
+    }
+
+    /**
+     * 检查设备是否连接到了有线网络
+     *
+     * @return 如果连接到了有线网络返回 true,否则返回 false
+     */
+    public boolean isEthernetConnected() {
+        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
+        if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
+            // 旧版本的 API 不区分有线和无线网络
+            // 可以尝试根据连接类型进行判断
+            if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public void enableEthernet() {
+        try {
+            // 创建ProcessBuilder实例,准备执行命令
+            ProcessBuilder pb = new ProcessBuilder("su", "-c", "ifconfig eth0 up");
+            // 启动进程
+            Process process = pb.start();
+            // 等待命令执行完成
+            int exitCode = process.waitFor();
+            if (exitCode == 0) {
+                Log.i("NetworkUtil",  "以太网打开成功");
+            } else {
+                Log.i("NetworkUtil", "以太网打开失败");
+            }
+        } catch (IOException | InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void disableEthernet() {
+        try {
+            // 创建ProcessBuilder实例,准备执行命令
+            ProcessBuilder pb = new ProcessBuilder("su", "-c", "ifconfig eth0 down");
+            // 启动进程
+            Process process = pb.start();
+            // 等待命令执行完成
+            int exitCode = process.waitFor();
+            if (exitCode == 0) {
+                Log.i("NetworkUtil",  "以太网关闭成功");
+            } else {
+                Log.i("NetworkUtil", "以太网关闭并失败");
+            }
+        } catch (IOException | InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 8 - 0
app/src/main/res/drawable/bg_grey_round_20_top_left_top_right.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+  <solid android:color="#f7f7f7" />
+  <corners
+      android:topLeftRadius="33px"
+      android:topRightRadius="33px"
+  />
+</shape>

+ 6 - 0
app/src/main/res/drawable/bg_white_round_20.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+  <solid android:color="#ffffff" />
+  <corners
+      android:radius="33px" />
+</shape>

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

@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:background="@drawable/bg_white_round_20"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:background="@drawable/bg_grey_round_20_top_left_top_right">
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@mipmap/top_logo"
+                android:layout_centerHorizontal="true"/>
+        </RelativeLayout>
+<!--        密码输入框-->
+        <LinearLayout
+            android:layout_gravity="center"
+            android:layout_marginHorizontal="15dp"
+            android:layout_width="match_parent"
+            android:orientation="vertical"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+        >
+            <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+                <TextView
+                    android:id="@+id/tv_content"
+                    style="@style/wrap_style"
+                    android:layout_gravity="left"
+                    android:layout_marginBottom="9dp"
+                    android:text=""
+                    android:textColor="@color/grey_66"
+                    android:textSize="22sp" />
+            </ScrollView>
+        </LinearLayout>
+        <LinearLayout
+            android:layout_marginVertical="28dp"
+            android:layout_marginHorizontal="15dp"
+            android:layout_width="match_parent"
+            android:orientation="vertical"
+            android:layout_height="wrap_content">
+            <Button
+                android:layout_weight="1"
+                android:id="@+id/btn_update"
+                android:layout_width="match_parent"
+                android:layout_height="54dp"
+                android:background="@drawable/shape_e6212a_4dp"
+                android:gravity="center"
+                android:text="立即更新"
+                android:textColor="@color/white"
+                android:layout_marginBottom="10dp"
+                android:textSize="18sp" />
+<!--                <View-->
+<!--                    android:layout_height="match_parent"-->
+<!--                    android:layout_width="10dp"-->
+<!--                    />-->
+            <Button
+                android:layout_weight="1"
+                android:id="@+id/btn_no_longer"
+                android:layout_width="match_parent"
+                android:layout_height="54dp"
+                android:background="@drawable/shape_e6212a_4dp"
+                android:gravity="center"
+                android:text="不再提醒"
+                android:textColor="@color/white"
+                android:layout_marginBottom="10dp"
+                android:textSize="18sp" />
+
+            <Button
+                android:layout_weight="1"
+                android:id="@+id/btn_close"
+                android:layout_width="match_parent"
+                android:layout_height="54dp"
+                android:background="@drawable/shape_e6212a_4dp"
+                android:gravity="center"
+                android:text="关闭"
+                android:visibility="visible"
+                android:textColor="@color/white"
+                android:textSize="18sp" />
+        </LinearLayout>
+    </LinearLayout>
+
+</RelativeLayout>

+ 3 - 3
app/src/main/res/values/strings.xml

@@ -3,10 +3,10 @@
 
     <string-array name="nav_tab_list">
         <item>首页</item>
-<!--        <item>发/收货</item>-->
+        <!--        <item>发/收货</item>-->
         <item>扫描</item>
-<!--        <item>安装</item>-->
-<!--        <item>验收</item>-->
+        <!--        <item>安装</item>-->
+        <!--        <item>验收</item>-->
         <item>我的</item>
     </string-array>
     <string name="none_paired">没有配对</string>

+ 7 - 1
app/src/main/res/values/styles.xml

@@ -1,5 +1,11 @@
 <resources>
-
+    <!--dialog-->
+    <style name="bottom_select_dialog" parent="@android:style/Theme.Dialog">
+        <item name="android:windowIsFloating">true</item><!-- 是否漂现在activity上 -->
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:backgroundDimEnabled">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
     <!-- Base application theme. -->
     <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
         <!-- Customize your theme here. -->

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini