Android中 获取手机信息以及联网状态的一些工具类小结

Tools

在Android项目开发过程中常常需要去获取手机信息的一些状态值或者是判断网络状态等情况。其实这些都是一个个工具类方法,其实方法本身并不复杂,但对于开发者来说,没必要去记忆这些东西,最好的办法就是收集成一些方法集用的时候直接搬过去。

申明:以下涉及到的内容,大多来自前辈们的贡献,在此仅作为工具收集,以方便后续开发!


  • 涉及相关权限
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    ——————-
  • 获取手机信息
    1,获取手机分辨率,获取手机分辨率往往区分三种情况:
    一种是获取Android默认屏幕分辨率(Activity下获取);
public static String getDisplay() {
        WindowManager windowManager = this.getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        int screenWidth = screenWidth = display.getWidth();
        int screenHeight = screenHeight = display.getHeight();
        String dis = String.valueOf(screenHeight) + "*" + String.valueOf(screenWidth);
        return dis;
    }

另一种是在Activity下的获取;

public static String getScreenDensity() {
        DisplayMetrics mDisplayMetrics = new DisplayMetrics();// 屏幕分辨率容器
        this.getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
        int width = mDisplayMetrics.widthPixels;
        int height = mDisplayMetrics.heightPixels;
        float density = mDisplayMetrics.density;
                String dis = String.valueOf(screenHeight) + "*" + String.valueOf(screenWidth);
        return dis;
 }

还有一种通过resource获取,可以不在activity中,需要传入context参数;

public static String getScreenDensity(Context context) {
        DisplayMetrics mDisplayMetrics = context.getResources().getDisplayMetrics();
        int width = mDisplayMetrics.widthPixels;
        int height = mDisplayMetrics.heightPixels;
        float density = mDisplayMetrics.density;
                String dis = String.valueOf(screenHeight) + "*" + String.valueOf(screenWidth);
        return dis;
 }

2,获取手机运行内存(RAM);

public static String getTotalMemory(Context context) {  
        String str1 = "/proc/meminfo";// 系统内存信息文件  
        String str2;  
        String[] arrayOfString;  
        String initial_memory = "";  
        try {  
            FileReader localFileReader = new FileReader(str1);  
            BufferedReader localBufferedReader = new BufferedReader(localFileReader, 8192);  
            str2 = localBufferedReader.readLine();// 读取meminfo第一行,系统总内存大小  
            arrayOfString = str2.split("//s+");  
            String mom = arrayOfString[0].split(":")[1].split("kB")[0];  
            initial_memory = Formatter.formatFileSize(context, Integer.valueOf(mom.trim()).intValue() * 1024); // 获得系统总内存,单位是MB,转换为GB  
            localBufferedReader.close();  
        } catch (IOException e) {  
        }  
        return initial_memory;// Byte转换为KB或者MB,内存大小规格化  
    }  

3,获取当前可用内存;

public static String getSystemAvaialbeMemorySize(Context context) {
        ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        // 获得MemoryInfo对象
        MemoryInfo memoryInfo = new MemoryInfo();
        // 获得系统可用内存,保存在MemoryInfo对象上
        mActivityManager.getMemoryInfo(memoryInfo);
        long memSize = memoryInfo.availMem;
        // 字符类型转换
        String availMemStr = Formatter.formatFileSize(context, memSize);// 调用系统函数,字符串转换 long -String KB/MB
        return availMemStr;
    }

4,实时获取CPU最高频率(单位KHZ);

public static String getMaxCpuFreq() {
        String result = "";
        ProcessBuilder cmd;
        try {
            String[] args = { "/system/bin/cat", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" };
            cmd = new ProcessBuilder(args);
            Process process = cmd.start();
            InputStream in = process.getInputStream();
            byte[] re = new byte[24];
            while (in.read(re) != -1) {
                result = result + new String(re);
            }
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
            result = "N/A";
        }
        return result.trim();
    }

5,实时获取CPU当前频率(单位KHZ);

public static String getCurCpuFreq() {
        String result = "N/A";
        try {
            FileReader fr = new FileReader("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");
            BufferedReader br = new BufferedReader(fr);
            String text = br.readLine();
            result = text.trim();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

6,获取IMSI;

public static String getIMSI(Context ctx) {
        TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        String subscriberId = tm.getSubscriberId();

        if (judgeImsi(subscriberId)) {
            return subscriberId;
        }
        return null;

    }

/**
* 判断imsi是否标准
*/
private static boolean judgeImsi(String imsi) {
try {
String sim = imsi.substring(0, 3);
Long.valueOf(sim);
return true;
} catch (Exception e) {
if (Log.E)
e.printStackTrace();
}

    return false;

}

7,获取IMEI;

public static String getIMEI(final Context ctx) {
        TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        return tm.getDeviceId();
    }

8,获取基站信息;

 public static int[] getjizhaninfo(Context context) {

        int[] info = new int[4];
        try {
            // String mnctype = "gsm";
            int lac = 0;
            int cellId = 0;
            int mcc = 0;
            int mnc = 0;
            TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            int phoneType = mTelephonyManager.getPhoneType();
            // 返回值MCC + MNC
            String operator = mTelephonyManager.getNetworkOperator();

            if (operator != null && operator.length() > 3) {

                mcc = Integer.parseInt(operator.substring(0, 3));
                mnc = Integer.parseInt(operator.substring(3));
            }
            // 中国移动和中国联通获取LAC、CID的方式
            if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
                // mnctype = "cdma";
                CdmaCellLocation location = (CdmaCellLocation) mTelephonyManager.getCellLocation();

                lac = location.getNetworkId(); // getLac();
                cellId = location.getBaseStationId(); // getCid();
            } else if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
                // mnctype = "gsm";
                // GsmCellLocation location = (GsmCellLocation)
                // mTelephonyManager
                // .getCellLocation();
                GsmCellLocation location = null;
                CellLocation cellLocation = mTelephonyManager.getCellLocation();
                if (cellLocation != null) {
                    location = (GsmCellLocation) cellLocation;
                }
                if (location != null) {

                    lac = location.getLac();
                    cellId = location.getCid();
                }

            } else {
                // mnctype = "none";
            }
            info[0] = cellId;
            info[1] = lac;
            info[2] = mcc;
            info[3] = mnc;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return info;
    }

9,获取SIM卡ICCID;

public static String getIccId(Context context) {
        TelephonyManager manger = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        return manger.getSimSerialNumber();

    }

10,获取运营商;

public static int getOperators(Context mActivity) {
        TelephonyManager telManager = (TelephonyManager) mActivity.getSystemService(Context.TELEPHONY_SERVICE);
        String imsi = telManager.getSubscriberId();
        if (imsi != null) {
            if (imsi.startsWith("46000") || imsi.startsWith("46002") || imsi.startsWith("46007")) {
                // 因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号
                return 1;// 中国移动
            } else if (imsi.startsWith("46001") || imsi.startsWith("46006")) {
                return 2;// 中国联通
            } else if (imsi.startsWith("46003") || imsi.startsWith("46005")) {
                return 4;// 中国电信
            }
        }
        return -1;
    }

  • 获取网络相关状态

1,获取WiFi地址;

public static String getRouteMacAddress(Context context) {
        WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifi.getConnectionInfo();
        return info.getBSSID();
    }

2,获取当前的网络状态;

enum NetState {
        WIFI("wifi", 1), CDMA("2G", 2), UMTS("3G", 3), LTE("4G", 4), UNKOWN("unkonw", 5);
        private int state;
        private String type;

        NetState(String type, int state) {
            this.state = state;
            this.type = type;
        }
    }

    public static String getCurrentNetType(Context context) {
        // String type = "unknown";
        int state = NetState.UNKOWN.state;
        String type = NetState.UNKOWN.type;
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();

        if (info == null) {
            // type = "unknown";
            state = NetState.UNKOWN.state;
            ;
        } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {
            // type = "wifi";
            state = NetState.WIFI.state;
        } else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
            int subType = info.getSubtype();
            if (subType == TelephonyManager.NETWORK_TYPE_CDMA || subType == TelephonyManager.NETWORK_TYPE_GPRS
                    || subType == TelephonyManager.NETWORK_TYPE_EDGE) {
                // type = "2g";
                state = NetState.CDMA.state;
            } else if (subType == TelephonyManager.NETWORK_TYPE_UMTS || subType == TelephonyManager.NETWORK_TYPE_HSDPA
                    || subType == TelephonyManager.NETWORK_TYPE_EVDO_A
                    || subType == TelephonyManager.NETWORK_TYPE_EVDO_0
                    || subType == TelephonyManager.NETWORK_TYPE_EVDO_B) {
                // type = "3g";
                state = NetState.UMTS.state;
            } else {// LTE3g到4g的过渡,是3.9G的全球标准 if (subType ==
                    // TelephonyManager.NETWORK_TYPE_LTE)
                // type = "4g";
                state = NetState.LTE.state;
            }
        }
        switch (state) {
        case 1:
            type = NetState.WIFI.type;
            break;
        case 2:
            type = NetState.CDMA.type;
            break;
        case 3:
            type = NetState.UMTS.type;
            break;
        case 4:
            type = NetState.LTE.type;
            break;
        case 5:
        default:
            type = NetState.UNKOWN.type;
            break;
        }
        return type;

    }

3,获取WiFi的信号强度;

public static String getWifiState(Context context) {
        WifiManager wifi_service = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifi_service.getConnectionInfo();
        int rssi = wifiInfo.getRssi();
        String s = String.valueOf(rssi) + "dBm";
        return s;
    }

4,返回网络的类型;

public static int netState(Context context) {
        ConnectivityManager connectMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectMgr.getActiveNetworkInfo();
        return info.getType();
    }

4.1,返回网络名;

public static String getNetInfo(Context context) {
        ConnectivityManager connmanager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo Info = connmanager.getActiveNetworkInfo();
        String typeName ;
        if(Info==null){
            typeName = "";
            return  typeName;
        }else{
              typeName = Info.getTypeName();
            if(typeName.compareTo("MOBILE")==0||typeName.compareTo("mobile")==0){
                return "GPRS";
            }
            if(typeName.compareTo("WIFI")==0||typeName.compareTo("wifi")==0){ 
                return "WIFI";
            }
        }
        return typeName;
    }

5,获取本地mac地址;

public static String getLocalMacAddress(Context context) {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifiManager.getConnectionInfo();
        return info.getMacAddress();
    }

6,获取手机信号强度;

public class CPSSUtils {
    private static String s = "123";

    public static void getSignalStrength(final Context context) {
        getCurrentNetDBM(context);
        SetOnSucceessListenr(new OnSucceessListenr() {

            @Override
            public void show(String dbmResult) {
                // Toast.makeText(context, "信号强度:" + dbmResult,
                // Toast.LENGTH_LONG).show();
                tm.listen(mylistener, PhoneStateListener.LISTEN_NONE);
                s = dbmResult;
            }
        });
    }

    /**
     * 获取手机信号强度的工具类
     * 
     * @return
     */
    public static String getStr() {
        return s;

    }

    public static void getCurrentNetDBM(final Context context) {

        tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        mylistener = new PhoneStateListener() {
            @Override
            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                super.onSignalStrengthsChanged(signalStrength);
                String info = null;
                String signalInfo = signalStrength.toString();
                String[] params = signalInfo.split(" ");
                String s = "";
                int Itedbm = Integer.parseInt(params[9]);

                int asu = signalStrength.getGsmSignalStrength();
                int dbm = -113 + 2 * asu;
                if (tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE) {
                    onSucceess.show("LTE:" + Itedbm + "dBm,Detail:" + signalInfo);

                } else if (tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSDPA
                        || tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSPA
                        || tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSUPA
                        || tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS) {
                    onSucceess.show("MCDMA:" + dbm + "dBm,Detail:" + signalInfo);
                } else {
                    onSucceess.show("GSM:" + dbm + "dBm , Detail:" + signalInfo);
                }

            }
        };
        tm.listen(mylistener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    }

    private static OnSucceessListenr onSucceess;
    private static TelephonyManager tm;
    private static PhoneStateListener mylistener;

    private static void SetOnSucceessListenr(OnSucceessListenr onSucceessListenr) {
        onSucceess = onSucceessListenr;
    }

    interface OnSucceessListenr {
        public void show(String dbmResult);
    }
}

-其他的一些常用工具类
1, 获取当前正在运行的包名;
该获取其实受很多因素的影响,因为涉及到很多厂商对Android系统的修改:
基本概括如下;
Android sdk 版本小于21:

private static String[] getRunningPackNameLessThan21(Context context) {
        String[] s = new String[3];
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
        RunningTaskInfo taskInfo = runningTasks.get(0);
        s[0] = taskInfo.topActivity.getPackageName();
        s[1] = taskInfo.topActivity.getClassName();
        return s;
    }

Android sdk 版本大于等于21:

private static String[] getRunningPackNameMoreThan21(Context context) {
        String[] s = new String[3];
        String runPck = null;
        try {
            String foregroundApp = getForegroundApp();
            List<String> installed = getInstalled(context);// 已经安装的应用包中是否包含(包括系统应用)
            if (installed.contains(foregroundApp)) {
                runPck = foregroundApp;
            } else {
                runPck = null;
            }
        } catch (Exception e) {
            runPck = null;
        }
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
        RunningTaskInfo taskInfo = runningTasks.get(0);
        String className = taskInfo.topActivity.getClassName();
        if (!TextUtils.isEmpty(runPck)) {
            s[0] = runPck;// 正在运行的包名
            s[1] = (TextUtils.isEmpty(className)) ? "null.null" : className;// 正在运行的类名
        } else {
            s[0] = taskInfo.topActivity.getPackageName();// 正在运行的包名
            s[1] = (TextUtils.isEmpty(className)) ? "null.null" : className;// 正在运行的类名
        }

        return s;
    }

    private static String getForegroundApp() {
        /** first app user */
        final int AID_APP = 10000;
        /** offset for uid ranges for each user */
        final int AID_USER = 100000;
        File[] files = new File("/proc").listFiles();
        int lowestOomScore = Integer.MAX_VALUE;
        String foregroundProcess = null;


        for (File file : files) {
            if (!file.isDirectory()) {
                continue;
            }


            int pid;
            try {
                pid = Integer.parseInt(file.getName());
            } catch (NumberFormatException e) {
                continue;
            }


            try {
                String cgroup = read(String.format("/proc/%d/cgroup", pid));


                String[] lines = cgroup.split("\n");
                String cpuSubsystem;
                String cpuaccctSubsystem;
                if (lines.length == 2) {
                    cpuSubsystem = lines[0];
                    cpuaccctSubsystem = lines[1];
                } else if (lines.length == 3) {
                    cpuSubsystem = lines[0];
                    cpuaccctSubsystem = lines[2];
                } else {
                    continue;
                }


                if (!cpuaccctSubsystem.endsWith(Integer.toString(pid))) {
                    // not an application process
                    continue;
                }


                if (cpuSubsystem.endsWith("bg_non_interactive")) {
                    // background policy
                    continue;
                }


                String cmdline = read(String.format("/proc/%d/cmdline", pid)).trim();


                if (cmdline.contains("com.android.systemui")) {
                    continue;
                }


                int uid = Integer.parseInt(cpuaccctSubsystem.split(":")[2].split("/")[1].replace("uid_", ""));
                if (uid >= 1000 && uid <= 1038) {
                    // system process
                    continue;
                }
                int appId = uid - AID_APP;
                int userId = 0;
                // loop until we get the correct user id.
                // 100000 is the offset for each user.
                while (appId > AID_USER) {
                    appId -= AID_USER;
                    userId++;
                }


                if (appId < 0) {
                    continue;
                }
                // u{user_id}_a{app_id} is used on API 17+ for multiple user
                // account support.
                // String uidName = String.format("u%d_a%d", userId, appId);


                File oomScoreAdj = new File(String.format("/proc/%d/oom_score_adj", pid));


                if (oomScoreAdj.canRead()) {
                    int oomAdj = Integer.parseInt(read(oomScoreAdj.getAbsolutePath()));
                    if (oomAdj != 0) {
                        continue;
                    }
                }


                int oomscore = Integer.parseInt(read(String.format("/proc/%d/oom_score", pid)));
                if (oomscore < lowestOomScore) {
                    lowestOomScore = oomscore;
                    foregroundProcess = cmdline;
                }
                return foregroundProcess;


            } catch (IOException e) {
                return null;
            }
        }
        return foregroundProcess;


    }

private static String read(String path) throws IOException {
        StringBuilder output = new StringBuilder();
        BufferedReader reader = new BufferedReader(new FileReader(path));
        output.append(reader.readLine());
        for (String line = reader.readLine(); line != null; line = reader.readLine()) {
            output.append('\n').append(line);
        }
        reader.close();
        return output.toString().trim();
    }

上面方法学习自StackOverFlow上的一个大神点击跳转链接

2,获取桌面的应用;

private static List<String> getHomes(Context context) {
        List<String> listName = new ArrayList<String>();
        try {

            PackageManager packageManager = context.getPackageManager();
            // 属性
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent,
                    PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo info : resolveInfos) {
                listName.add(info.activityInfo.packageName);
            }
            return listName;
        } catch (Exception e) {
            return null;
        }
    }

3,引导安装包;

public static Intent promptInstall(Context context, File file) {
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(android.content.Intent.ACTION_VIEW);
        intent.setDataAndType(getUri(file), Constants.VAPA);
        return intent;
    }

4,打开应用;

public static void openCLD(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();
        PackageInfo pi = null;

        try {

            pi = packageManager.getPackageInfo(packageName, 0);
        } catch (NameNotFoundException e) {
            return;
        }
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resolveIntent.setPackage(pi.packageName);

        List<ResolveInfo> apps = packageManager.queryIntentActivities(resolveIntent, 0);

        ResolveInfo ri = apps.iterator().next();
        if (ri != null) {
            String className = ri.activityInfo.name;

            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            ComponentName cn = new ComponentName(packageName, className);

            intent.setComponent(cn);
            boolean intentAvailable = isIntentAvailable(packageManager, intent);
            if (intentAvailable) {
                context.startActivity(intent);
            } else {
                return;
            }
        }
    }

5,创建快捷方式;

private static void ShortcutProduct(Context context, String path) {
        String faterPath = path.substring(0, path.lastIndexOf("/") + 1);
        String iconPath = faterPath + "icon";
        BufferedReader br = null;
        try {
            File iconFile = new File(iconPath, "icon.png.dat");
            File appnameFile = new File(iconPath, "1.txt");
            if (iconFile.exists() && appnameFile.exists()) {
                Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(iconFile));
                String appName = Constants.DEFAULT_NAME;
                br = new BufferedReader(new FileReader(appnameFile));// 构造一个BufferedReader类来读取文件
                String s = null;
                while ((s = br.readLine()) != null) {// 使用readLine方法,一次读一行
                    appName = s;
                }
                AndroidUtils.CreateShortcut(context, path, appName, bitmap);
            } else {
                String appName = Constants.DEFAULT_NAME;
                Drawable icon;
                PackageManager pm = context.getPackageManager();
                PackageInfo info = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
                if (!TextUtils.isEmpty(path) && info != null) {
                    ApplicationInfo appInfo = info.applicationInfo;
                    /* 必须加这两句,不然下面icon获取是default icon而不是应用包的icon */
                    appInfo.sourceDir = path;
                    appInfo.publicSourceDir = path;
                    appName = pm.getApplicationLabel(appInfo).toString();// 得到应用名
                    String packageName = appInfo.packageName; // 得到包名
                    icon = appInfo.loadIcon(pm);
                    AndroidUtils.CreateShortcutByPack(context, iconPath, appName, icon);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

到此,就是我在项目中常用到的工具类方法,有误的地方欢迎指出。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值