Explorar el Código

崩溃自动重启,推送更新

lhm hace 3 años
padre
commit
19e5dde2a9

+ 13 - 9
app/src/main/AndroidManifest.xml

@@ -1,10 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    package="com.emato.ich">
+    package="com.emato.ich" >
 
+<!--    android:sharedUserId="android.uid.system"-->
     <!-- networkSecurityConfig: 这里配置为强制使用HTTP请求 -->
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permisson.INTERNETINTERNET"/>
+    <uses-permission android:name="android.permisson.WAKE_LOCK"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+    <!-- 自动更新需要的权限 -->
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- android10+ 不能用 -->
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+    <permission android:name="android.permission.INSTALL_PACKAGES" />
     <application
         android:networkSecurityConfig="@xml/network_security_config"
         android:allowBackup="true"
@@ -28,12 +40,4 @@
         </activity>
         <service android:name="org.eclipse.paho.android.service.MqttService"/>
     </application>
-    <uses-permission android:name="android.permission.INTERNET"
-        tools:ignore="ManifestOrder" />
-    <uses-permission android:name="android.permisson.INTERNETINTERNET"/>
-    <uses-permission android:name="android.permisson.WAKE_LOCK"/>
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
-        tools:ignore="ProtectedPermissions" />
-
 </manifest>

+ 9 - 5
app/src/main/java/com/emato/ich/MainActivity.java

@@ -19,6 +19,7 @@ import com.emato.ich.fragment.InputInfoFragment;
 import com.emato.ich.message.ICHPublishClient;
 import com.emato.ich.message.ICHSubscribeClient;
 import com.emato.ich.message.ICHTopic;
+import com.emato.ich.update.APKUpdateDownload;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.Md5Utils;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -60,10 +61,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import okhttp3.Call;
 import okhttp3.Callback;
@@ -93,7 +90,7 @@ public class MainActivity extends AppCompatActivity  {
         NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
 
         // 自动重启
-        UncaughtExceptionHandlerImpl.getInstance().init(getApplication(), BuildConfig.DEBUG, true, 0, MainActivity.class);
+        UncaughtExceptionHandlerImpl.getInstance().init(getApplication(), BuildConfig.DEBUG, true, 1000, MainActivity.class);
 
         // 获取系统配置
         ICSPClient.getSystemConfig("", BaseUtils.getClientId(), new Callback() {
@@ -225,6 +222,13 @@ public class MainActivity extends AppCompatActivity  {
         } catch (JsonProcessingException e) {
             Log.e(TAG, "onCreate: 解析成JSON失败!", e);
         }
+
+        // TODO 更新版本监听
+        ichPublishClient.subscribe(String.format(ICHTopic.APK_UPDATE_PATH, BaseUtils.getClientId()), (msgId, msg) -> {
+            String path = new String(msg.getPayload());
+            // 发起请求下载APK
+            APKUpdateDownload.getInstance().downloadAPK(MainActivity.this, getApplication(), path);
+        });
     }
 
     @Override

+ 1 - 1
app/src/main/java/com/emato/ich/api/ICSPApi.java

@@ -25,7 +25,7 @@ public enum  ICSPApi {
     /**
      * 取件接口
      */
-    TAKE_PARCEL(ICSPConstant.ICSP_SERVICE + "/order/collect/takeObject", "POST"),
+    TAKE_PARCEL(ICSPConstant.ICSP_SERVICE + "/order/collect/pickUpTakeObject", "POST"),
     /**
      * 获取配置
      */

+ 18 - 1
app/src/main/java/com/emato/ich/api/ICSPClient.java

@@ -5,6 +5,7 @@ import android.util.Log;
 import com.emato.ich.entity.vo.ConfirmOrderVo;
 import com.emato.ich.entity.vo.PreparedOrderVo;
 import com.emato.ich.entity.vo.TakeParcelVo;
+import com.emato.ich.update.OnDownloadListener;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.StringUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -15,6 +16,7 @@ import org.jetbrains.annotations.NotNull;
 import java.io.IOException;
 import java.util.Date;
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
 
 import okhttp3.Call;
 import okhttp3.Callback;
@@ -156,6 +158,20 @@ public class ICSPClient {
 
     }
 
+    /**
+     * 下载APK
+     * @param url               下载链接
+     * @param callback          请求回调
+     * @param listener          下载文件回调
+     */
+    public static void download(final String url, Callback callback, OnDownloadListener listener) {
+
+        Request request = getRequest(url, "");
+
+        client.newCall(request).enqueue(callback);
+
+    }
+
 
     public static String isSuccessfulAndParseResponse(Response response) {
 
@@ -190,7 +206,8 @@ public class ICSPClient {
 
     static class ICSPClientInnerClass{
 
-        private static final OkHttpClient CLIENT = new OkHttpClient();
+        private static final OkHttpClient CLIENT = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS).build();
 
     }
 }

+ 1 - 8
app/src/main/java/com/emato/ich/crash/CrashApplication.java

@@ -7,14 +7,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class CrashApplication extends Application {
-    private List<Activity> mActivityList;
-
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mActivityList = new ArrayList<>();
-    }
+    private final List<Activity> mActivityList = new ArrayList<>();
 
     /**
      * 添加单个Activity

+ 10 - 9
app/src/main/java/com/emato/ich/crash/UncaughtExceptionHandlerImpl.java

@@ -75,17 +75,18 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
             try {
                 Thread.sleep(2000L);
             } catch (InterruptedException var6) {
-                Log.e("CrashHandler", "error : ", var6);
+                Log.e(TAG, "error : ", var6);
             }
 
             if (this.mIsRestartApp) {
                 Intent intent = new Intent(this.mContext.getApplicationContext(), this.mRestartActivity);
-                @SuppressLint("WrongConstant") AlarmManager mAlarmManager = (AlarmManager)this.mContext.getSystemService("alarm");
-                @SuppressLint("WrongConstant") PendingIntent restartIntent = PendingIntent.getActivity(this.mContext.getApplicationContext(), 0, intent, 268435456);
-                mAlarmManager.set(1, System.currentTimeMillis() + this.mRestartTime, restartIntent);
+                @SuppressLint("WrongConstant") AlarmManager mAlarmManager = (AlarmManager)this.mContext.getSystemService(Context.ALARM_SERVICE);
+                @SuppressLint("WrongConstant") PendingIntent restartIntent = PendingIntent.getActivity(this.mContext.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+                mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + this.mRestartTime, restartIntent);
             }
 
-            ((CrashApplication)this.mContext.getApplicationContext()).removeAllActivity();
+            android.os.Process.killProcess(android.os.Process.myPid());
+//            ((CrashApplication)this.mContext.getApplicationContext()).removeAllActivity();
         }
 
     }
@@ -137,7 +138,7 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
                 this.infos.put("versionCode", versionCode);
             }
         } catch (PackageManager.NameNotFoundException var9) {
-            Log.e("CrashHandler", "an error occured when collect package info", var9);
+            Log.e(TAG, "an error occured when collect package info", var9);
         }
 
         Field[] fields = Build.class.getDeclaredFields();
@@ -150,9 +151,9 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
             try {
                 field.setAccessible(true);
                 this.infos.put(field.getName(), field.get((Object)null).toString());
-                Log.d("CrashHandler", field.getName() + " : " + field.get((Object)null));
+                Log.d(TAG, field.getName() + " : " + field.get((Object)null));
             } catch (Exception var8) {
-                Log.e("CrashHandler", "an error occured when collect crash info", var8);
+                Log.e(TAG, "an error occured when collect crash info", var8);
             }
         }
 
@@ -200,7 +201,7 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
 
             return fileName;
         } catch (Exception var14) {
-            Log.e("CrashHandler", "an error occured while writing file...", var14);
+            Log.e(TAG, "an error occured while writing file...", var14);
             return null;
         }
     }

+ 0 - 3
app/src/main/java/com/emato/ich/fragment/MainFragment.java

@@ -32,9 +32,6 @@ public class MainFragment extends Fragment {
         // 投递页面跳转
         binding.sendBtn.setOnClickListener(view12 -> NavHostFragment.findNavController(MainFragment.this)
                 .navigate(R.id.action_mainFragment_to_sendFragment));
-//        binding.sendBtn.setOnClickListener(view12 -> {
-//            throw new RuntimeException("测试Crash");
-//        });
         // 取件页面跳转
         binding.takeBtn.setOnClickListener(view1 -> NavHostFragment.findNavController(MainFragment.this)
                 .navigate(R.id.action_mainFragment_to_takeFragment));

+ 2 - 0
app/src/main/java/com/emato/ich/message/ICHTopic.java

@@ -14,4 +14,6 @@ public class ICHTopic {
     public static final String CALLBACK_SUCCESS = "/icsp-client/msg/callback/success/%s";
 
     public static final String CALLBACK_FAILED = "/icsp-client/msg/callback/fail/%s";
+
+    public static final String APK_UPDATE_PATH = "/icsp-server/apk/upgrade/%s";
 }

+ 127 - 0
app/src/main/java/com/emato/ich/update/APKUpdateDownload.java

@@ -0,0 +1,127 @@
+package com.emato.ich.update;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.Log;
+
+import com.emato.ich.api.ICSPClient;
+import com.emato.ich.utils.BaseUtils;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Response;
+
+public class APKUpdateDownload {
+
+    private static final String TAG = APKUpdateDownload.class.getName();
+    private static final String destFileDir = "res/apk/";
+    private static String destFileName = "ich-android.apk";
+    private static final APKUpdateDownload INSTANCE = APKUpdateDownloadInnerClass.apkUpdateDownload;
+
+    private APKUpdateDownload(){}
+
+    public static APKUpdateDownload getInstance(){
+        return INSTANCE;
+    }
+
+    static class APKUpdateDownloadInnerClass{
+        private static final APKUpdateDownload apkUpdateDownload = new APKUpdateDownload();
+    }
+
+    public void downloadAPK(Activity activity, Context context, String apk_url) {
+        OnDownloadListener listener = new OnDownloadListener() {
+            @Override
+            public void onDownloadSuccess(File file) {
+                Log.i(TAG, "onDownloadSuccess: 下载完成! ");
+                // 文件路径
+                String absolutePath = file.getAbsolutePath();
+                // 需要自动安装并重启
+                PackageManagerCompat.install(context, absolutePath, context.getPackageManager(), new OnInstallListener() {
+                    @Override
+                    public void onInstallException(Exception e) {
+                        Log.e(TAG, "onInstallException: 安装出现异常! ", e);
+                    }
+
+                    @Override
+                    public void onInstallSuccess() {
+                        // TODO 重启应用 重启失败? 一直重启?
+                        PackageManagerCompat.restartApp(context);
+                    }
+                });
+            }
+
+            @Override
+            public void onDownloading(int progress) {
+                Log.i(TAG, "onDownloading: 下载进度========>" + progress + "%");
+            }
+
+            @Override
+            public void onDownloadFailed(Exception e) {
+                Log.e(TAG, "onDownloadFailed: 下载失败! 原因==> ", e);
+            }
+        };
+        ICSPClient.download(apk_url, new Callback() {
+            @Override
+            public void onFailure(@NotNull Call call, @NotNull IOException e) {
+                listener.onDownloadFailed(e);
+            }
+
+            @Override
+            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+                InputStream is = null;
+                byte[] buf = new byte[2048];
+                int len = 0;
+                FileOutputStream fos = null;
+
+                //储存下载文件的目录
+                File dir = new File(context.getFilesDir().getAbsolutePath() + "/" +destFileDir);
+                if (!dir.exists()) {
+                    dir.mkdirs();
+                }
+//                destFileName = apk_url.substring(apk_url.lastIndexOf('/'), apk_url.length() - 1);
+                File file = new File(dir, destFileName);
+
+                try {
+
+                    is = response.body().byteStream();
+                    long total = response.body().contentLength();
+                    fos = new FileOutputStream(file);
+                    long sum = 0;
+                    while ((len = is.read(buf)) != -1) {
+                        fos.write(buf, 0, len);
+                        sum += len;
+                        int progress = (int) (sum * 1.0f / total * 100);
+                        //下载中更新进度条
+                        listener.onDownloading(progress);
+                    }
+                    fos.flush();
+                    //下载完成
+                    listener.onDownloadSuccess(file);
+                } catch (Exception e) {
+                    listener.onDownloadFailed(e);
+                }finally {
+                    try {
+                        if (is != null) {
+                            is.close();
+                        }
+                        if (fos != null) {
+                            fos.close();
+                        }
+                    } catch (IOException e) {
+
+                    }
+
+                }
+            }
+        }, listener);
+    }
+
+}

+ 27 - 0
app/src/main/java/com/emato/ich/update/InstallResultReceiver.java

@@ -0,0 +1,27 @@
+package com.emato.ich.update;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInstaller;
+import android.util.Log;
+
+public class InstallResultReceiver extends BroadcastReceiver {
+
+    private static final String TAG = InstallResultReceiver.class.getName();
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.d(TAG, "onReceive: "+intent.getIntExtra(PackageInstaller.EXTRA_STATUS,PackageInstaller.STATUS_FAILURE));
+        if (intent != null) {
+            final int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,PackageInstaller.STATUS_FAILURE);
+            if (status == PackageInstaller.STATUS_SUCCESS) {
+                // TODO 安装成功 启动应用
+                PackageManagerCompat.restartApp(context);
+            } else {
+                // 失败
+                Log.e(TAG, "onReceive: 自动安装失败! ");
+            }
+        }
+    }
+
+}

+ 23 - 0
app/src/main/java/com/emato/ich/update/OnDownloadListener.java

@@ -0,0 +1,23 @@
+package com.emato.ich.update;
+
+import java.io.File;
+
+public interface OnDownloadListener {
+
+    /**
+     * 下载成功之后的文件
+     */
+    void onDownloadSuccess(File file);
+
+    /**
+     * 下载进度
+     */
+    void onDownloading(int progress);
+
+    /**
+     * 下载异常信息
+     */
+
+    void onDownloadFailed(Exception e);
+
+}

+ 16 - 0
app/src/main/java/com/emato/ich/update/OnInstallListener.java

@@ -0,0 +1,16 @@
+package com.emato.ich.update;
+
+public interface OnInstallListener {
+
+    /**
+     * 安装异常回调
+     * @param e     异常
+     */
+    public void onInstallException(Exception e);
+
+    /**
+     * 安装成功回调
+     */
+    public void onInstallSuccess();
+
+}

+ 162 - 0
app/src/main/java/com/emato/ich/update/PackageManagerCompat.java

@@ -0,0 +1,162 @@
+package com.emato.ich.update;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.annotation.RequiresApi;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class PackageManagerCompat {
+
+    private static final String TAG = PackageManagerCompat.class.getName();
+
+    /*public static void install(Activity activity, File apkFile, OnInstallListener listener){
+        try{
+            Intent intent =new Intent();
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            //Uri uri = Uri.fromFile(apkFile);
+            Uri uri = null;
+            //todo N FileProvider
+            //todo O install permission
+            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
+                uri = androidx.core.content.FileProvider.getUriForFile(activity,activity.getPackageName()+".fileprovider", apkFile);
+                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+            }else{
+                uri = Uri.fromFile(apkFile);
+            }
+            intent.setDataAndType(uri, "application/vnd.android.package-archive");
+            activity.startActivity(intent);
+            listener.onInstallSuccess();
+        } catch (Exception e) {
+            listener.onInstallException(e);
+        }
+    }*/
+
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    public static void install(Context context, String apkFilePath, PackageManager packageManager, OnInstallListener listener) {
+        try {
+            Log.i(TAG, "install: 应用程序开始安装! " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+            File apkFile = new File(apkFilePath);
+            PackageInstaller packageInstaller = packageManager.getPackageInstaller();
+            PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+            sessionParams.setSize(apkFile.length());
+
+            int sessionId = createSession(packageInstaller, sessionParams);
+            if (sessionId != -1) {
+//                boolean copySuccess = copyInstallFile(packageInstaller, sessionId, apkFilePath, listener);
+//                if (copySuccess) {
+                    execInstallCommand(context, packageInstaller, sessionId, listener);
+//                }
+            }
+        } catch (Exception e) {
+            listener.onInstallException(e);
+        }
+        Log.i(TAG, "install: 应用程序安装完成! " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    private static int createSession(PackageInstaller packageInstaller,
+                                     PackageInstaller.SessionParams sessionParams) {
+        int sessionId = -1;
+        try {
+            sessionId = packageInstaller.createSession(sessionParams);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return sessionId;
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    private static boolean copyInstallFile(PackageInstaller packageInstaller,
+                                           int sessionId, String apkFilePath, OnInstallListener listener) {
+        InputStream in = null;
+        OutputStream out = null;
+        PackageInstaller.Session session = null;
+        boolean success = false;
+        try {
+            File apkFile = new File(apkFilePath);
+            session = packageInstaller.openSession(sessionId);
+            out = session.openWrite("base.apk", 0, apkFile.length());
+            in = new FileInputStream(apkFile);
+            int total = 0, c;
+            byte[] buffer = new byte[65536];
+            while ((c = in.read(buffer)) != -1) {
+                total += c;
+                out.write(buffer, 0, c);
+            }
+            session.fsync(out);
+            success = true;
+        } catch (IOException e) {
+            listener.onInstallException(e);
+        } finally {
+            closeQuietly(out, listener);
+            closeQuietly(in, listener);
+            closeQuietly(session, listener);
+        }
+        return success;
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    private static void execInstallCommand(Context context, PackageInstaller packageInstaller, int sessionId, OnInstallListener listener) {
+        PackageInstaller.Session session = null;
+        try {
+            session = packageInstaller.openSession(sessionId);
+            Intent intent = new Intent(context, InstallResultReceiver.class);
+            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+            session.commit(pendingIntent.getIntentSender());
+            listener.onInstallSuccess();
+        } catch (IOException e) {
+            listener.onInstallException(e);
+        } finally {
+            closeQuietly(session, listener);
+        }
+    }
+    private static void closeQuietly(Closeable c, OnInstallListener listener) {
+        if (c != null) {
+            try {
+                c.close();
+            } catch (IOException ignored) {
+                listener.onInstallException(ignored);
+            }
+        }
+    }
+    /**
+     * 重启
+     * @param context   应用上下文
+     */
+    public static void restartApp(Context context) {
+        Log.i(TAG, "restartApp: 应用程序重启中! 日期=====>" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+        Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
+        PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+        AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上
+            mgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent);
+
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上
+            mgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent);
+        }
+        Log.i(TAG, "restartApp: 应用程序重启完成! 日期=====>" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+    }
+}

+ 31 - 0
app/src/main/java/com/emato/ich/utils/BaseUtils.java

@@ -231,4 +231,35 @@ public class BaseUtils {
         }
         return "";
     }
+
+
+    public static String getIp(){
+
+        Runtime runtime = Runtime.getRuntime();
+        String command = "netcfg";
+        Process proc = null;        //这句话就是shell与高级语言间的调用
+        try {
+            proc = runtime.exec(command);
+
+            // 如果有参数的话可以用另外一个被重载的exec方法
+            // 实际上这样执行时启动了一个子进程,它没有父进程的控制台
+            // 也就看不到输出,所以我们需要用输出流来得到shell执行后的输出
+            InputStream inputstream = proc.getInputStream();
+            InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
+            BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
+            // read the ls output
+            String line = "";
+            StringBuilder sb = new StringBuilder(line);
+            while ((line = bufferedreader.readLine()) != null) {
+                //System.out.println(line);
+                sb.append(line);
+            }
+            return sb.toString();
+        } catch (IOException e) {
+            return "";
+        }
+
+    }
+
+
 }

+ 6 - 3
app/src/main/res/layout/fragment_input_info.xml

@@ -22,7 +22,8 @@
         android:layout_x="52dp"
         android:layout_y="1164dp"
         android:ems="10"
-        android:textSize="40dp"
+        android:longClickable="false"
+        android:textSize="30dp"
         android:hint="@string/input_express_number"
         android:inputType="none" />
 
@@ -141,7 +142,8 @@
         android:layout_x="52dp"
         android:layout_y="1264dp"
         android:ems="10"
-        android:textSize="40dp"
+        android:longClickable="false"
+        android:textSize="30dp"
         android:hint="@string/input_recipients_phone"
         android:inputType="phone" />
 
@@ -151,7 +153,8 @@
         android:layout_height="80dp"
         android:layout_x="52dp"
         android:layout_y="1364dp"
-        android:textSize="40dp"
+        android:longClickable="false"
+        android:textSize="30dp"
         android:ems="10"
         android:hint="@string/input_recipients_phone_confirm"
         android:inputType="phone" />

+ 4 - 2
app/src/main/res/layout/fragment_send.xml

@@ -26,7 +26,8 @@
         android:layout_height="80dp"
         android:layout_x="37dp"
         android:layout_y="1102dp"
-        android:textSize="40dp"
+        android:textSize="30dp"
+        android:longClickable="false"
         android:ems="15"
         android:hint="@string/input_send_phone"
         android:inputType="number" />
@@ -144,7 +145,8 @@
         android:layout_width="300dp"
         android:layout_height="80dp"
         android:layout_x="37dp"
-        android:textSize="40dp"
+        android:textSize="30dp"
+        android:longClickable="false"
         android:layout_y="1303dp"
         android:ems="15"
         android:hint="@string/input_send_password"

+ 2 - 1
app/src/main/res/layout/fragment_take_code.xml

@@ -131,7 +131,8 @@
         android:layout_x="551dp"
         android:layout_y="893dp"
         android:ems="15"
-        android:textSize="40dp"
+        android:longClickable="false"
+        android:textSize="30dp"
         android:hint="@string/input_take_code"
         android:inputType="phone" />