安卓 流量相关功能实现记录

1. 静态声明权限,在AndroidManifest.xml中申明

    <uses-permission xmlns:tools="http://schemas.android.com/tools"
        android:name="android.permission.PACKAGE_USAGE_STATS"
        tools:ignore="ProtectedPermissions" />

2.判断并动态申请 [使用情况] 权限

//是否拥有权限    
private fun hasPermission(): Boolean {
        return XXPermissions.isGranted(requireContext(), Manifest.permission.PACKAGE_USAGE_STATS)
    }

//申请权限的方法
private fun startSettings() {
        val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
        if (intent.resolveActivity(requireContext().packageManager) != null) {
            requireActivity().startActivity(intent)
        } else {
            //应用无权限打开这个设置界面,一般都有
        }
    }

3.相关的Bean对象

/*
* name : 应用名称
* packageName:包名
* icon:应用图标
* dataUsage:使用的流量字节数
* openCount:打开次数
* useTime:使用时间
* packageSize:包大小
* */

data class AppBean(
    val name: String,
    val packageName: String,
    val icon: Drawable?,
    var dataUsage: Long,
    val openCount : Int,
    val useTime : Long,
    val packageSize : Long = 0L
)

/**
* indexTime : 第i周、第i天、第i月
* timeRegion 时间的区间
* data : 显示的数据 ,如:1.2GB、1.2MB
 * progress : 这个Flow占所有的流量的百分比 
* */
data class Flow(var indexTime:String,var timeRegion : String ,val data:String, var progress:Int = 0)

4.统一的工具类

自己的包名

import android.app.DatePickerDialog
import android.app.usage.NetworkStats
import android.app.usage.NetworkStatsManager
import android.app.usage.StorageStats
import android.app.usage.StorageStatsManager
import android.app.usage.UsageEvents
import android.app.usage.UsageStatsManager
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.os.storage.StorageManager
import android.util.Log
import com.kodami.metoru.libui.bean.AppBean
import com.kodami.metoru.libui.bean.Flow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.IOException
import java.net.InetSocketAddress
import java.net.Socket
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.TimeZone
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.random.Random


object FlowUtils {

    //获取所有应用的信息(包括icon,名称,流量使用量,打开次数,使用时间,包体大小)
    fun getAllInstalledAppsInfo(context: Context, startTime: Long, endTime: Long): List<AppBean> {
        val packageManager = context.packageManager
        val packageInfoList = packageManager.getInstalledPackages(0)
        val appBeans = mutableListOf<AppBean>()

        for (packageInfo in packageInfoList) {
            if (!isSystemApp(packageInfo)) {  //排除掉系统级应用
                val appName = packageInfo.applicationInfo.loadLabel(packageManager).toString()
                val packageName = packageInfo.packageName
                val icon = packageInfo.applicationInfo.loadIcon(packageManager)
                val dataUsage = getAppDataUsage(context, packageName, startTime, endTime)
                val pakageSize = getAppPackageSize(context, packageName)
                if (dataUsage > 1024) {
                    appBeans.add(
                        AppBean(
                            appName,
                            packageName,
                            icon,
                            dataUsage,
                            geAppTodayOpenCount(context, packageName),
                            getAppUseNetworkTime(context, packageName, startTime),
                            pakageSize
                        )
                    )
                }
            }
        }
        // 按数据使用情况降序对列表进行排序
        appBeans.sortByDescending { it.dataUsage }

        return appBeans
    }

    //获取今天所有应用的信息,通过使用流量排序

    fun getAllInstalledAppsInfo(context: Context): List<AppBean> {
        val packageManager = context.packageManager
        val packageInfoList = packageManager.getInstalledPackages(0)
        val appBeans = mutableListOf<AppBean>()
        val startTime = getTodayTimeInMillis()

        for (packageInfo in packageInfoList) {
            if (!isSystemApp(packageInfo)) {  //排除掉系统级应用
                val appName = packageInfo.applicationInfo.loadLabel(packageManager).toString()
                val packageName = packageInfo.packageName
                val icon = packageInfo.applicationInfo.loadIcon(packageManager)
                val dataUsage =
                    getAppDataUsage(context, packageName, startTime, getEndTimeInMillis(startTime))
                val pakageSize = getAppPackageSize(context, packageName)

                if (dataUsage > 1024) {
                    appBeans.add(
                        AppBean(
                            appName,
                            packageName,
                            icon,
                            dataUsage,
                            geAppTodayOpenCount(context, packageName),
                            getAppUseNetworkTime(context, packageName, startTime),
                            pakageSize
                        )
                    )
                }
            }
        }

        // 按数据使用情况降序对列表进行排序
        appBeans.sortByDescending { it.dataUsage }

        return appBeans
    }

    //重载方法,默认结束结束时间是今晚0点整
    fun getAllInstalledAppsInfo(context: Context, startTime: Long): List<AppBean> {
        val packageManager = context.packageManager
        val packageInfoList = packageManager.getInstalledPackages(0)
        val appBeans = mutableListOf<AppBean>()

        for (packageInfo in packageInfoList) {
            if (!isSystemApp(packageInfo)) {  //排除掉系统级应用
                val appName = packageInfo.applicationInfo.loadLabel(packageManager).toString()
                val packageName = packageInfo.packageName
                val icon = packageInfo.applicationInfo.loadIcon(packageManager)
                val dataUsage = getAppDataUsage(
                    context, packageName, startTime,
                    getEndTimeInMillis(getTodayTimeInMillis())
                )
                if (dataUsage > 1024) {
                    appBeans.add(
                        AppBean(
                            appName,
                            packageName,
                            icon,
                            dataUsage,
                            geAppTodayOpenCount(context, packageName),
                            getAppUseNetworkTime(context, packageName, startTime)
                        )
                    )
                }
            }
        }

        // 按数据使用情况降序对列表进行排序
        appBeans.sortByDescending { it.dataUsage }

        return appBeans
    }


    //获取今天所有应用的信息,按照使用时间排序(包括icon,名称,流量使用量,打开次数,使用时间)
    fun getAllInstalledAppsInfoSortByUseTime(context: Context, startTime: Long): List<AppBean> {
        val packageManager = context.packageManager
        val packageInfoList = packageManager.getInstalledPackages(0)
        val appBeans = mutableListOf<AppBean>()
        for (packageInfo in packageInfoList) {
            if (!isSystemApp(packageInfo)) {  //排除掉系统级应用
                val appName = packageInfo.applicationInfo.loadLabel(packageManager).toString()
                val packageName = packageInfo.packageName
                val icon = packageInfo.applicationInfo.loadIcon(packageManager)
                val dataUsage =
                    getAppDataUsage(
                        context, packageName, startTime, getEndTimeInMillis(
                            getTodayTimeInMillis()
                        )
                    )
                val useTime = getAppUseNetworkTime(context, packageName, startTime)
                val pakageSize = getAppPackageSize(context, packageName)
                if (useTime > 0) {
                    appBeans.add(
                        AppBean(
                            appName,
                            packageName,
                            icon,
                            dataUsage,
                            geAppTodayOpenCount(context, packageName),
                            useTime,
                            pakageSize
                        )
                    )
                }
            }
        }

        // 按数据使用情况降序对列表进行排序
        appBeans.sortByDescending { it.useTime }

        return appBeans
    }

    //获取今天所有应用的信息,按照包体大小排序(包括icon,名称,流量使用量,打开次数,使用时间)
    fun getAllInstalledAppsInfoSortByPackageSize(context: Context, startTime: Long): List<AppBean> {
        val packageManager = context.packageManager
        val packageInfoList = packageManager.getInstalledPackages(
            PackageManager.GET_ACTIVITIES or
                    PackageManager.GET_SERVICES
        )
        val appBeans = mutableListOf<AppBean>()

        for (packageInfo in packageInfoList) {
            if (!isSystemApp(packageInfo)) {  //排除掉系统级应用
                val appName = packageInfo.applicationInfo.loadLabel(packageManager).toString()
                val packageName = packageInfo.packageName
                val icon = packageInfo.applicationInfo.loadIcon(packageManager)
                val dataUsage = getAppDataUsage(
                    context, packageName, startTime,
                    getEndTimeInMillis(getTodayTimeInMillis())
                )
                val pakageSize = getAppPackageSize(context, packageName)
                if (pakageSize > 1024) {
                    appBeans.add(
                        AppBean(
                            appName,
                            packageName,
                            icon,
                            dataUsage,
                            geAppTodayOpenCount(context, packageName),
                            getAppUseNetworkTime(context, packageName, startTime),
                            pakageSize
                        )
                    )
                }
            }
        }

        // 按数据使用情况降序对列表进行排序
        appBeans.sortByDescending { it.packageSize }

        return appBeans
    }

    //获取今天所有应用的信息,按照打开次数排序(包括icon,名称,流量使用量,打开次数,使用时间)
    fun getAllInstalledAppsInfoSortByOpenCount(context: Context, startTime: Long): List<AppBean> {
        val packageManager = context.packageManager
        val packageInfoList = packageManager.getInstalledPackages(0)
        val appBeans = mutableListOf<AppBean>()

        for (packageInfo in packageInfoList) {
            if (!isSystemApp(packageInfo)) {  //排除掉系统级应用
                val appName = packageInfo.applicationInfo.loadLabel(packageManager).toString()
                val packageName = packageInfo.packageName
                val icon = packageInfo.applicationInfo.loadIcon(packageManager)
                val dataUsage = getAppDataUsage(
                    context, packageName, startTime,
                    getEndTimeInMillis(getTodayTimeInMillis())
                )
                val openCount = geAppTodayOpenCount(context, packageName)
                if (openCount > 0) {
                    appBeans.add(
                        AppBean(
                            appName,
                            packageName,
                            icon,
                            dataUsage,
                            openCount,
                            getAppUseNetworkTime(context, packageName, startTime)
                        )
                    )
                }
            }
        }

        // 按数据使用情况降序对列表进行排序
        appBeans.sortByDescending { it.openCount }

        return appBeans
    }

    //获取安装包大小
    fun getAppPackageSize(context: Context, packageName: String): Long {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            return 0L
        }
        val pm = context.packageManager
        val appInfo: ApplicationInfo?
        try {
            appInfo = pm.getApplicationInfo(packageName, 0)
        } catch (e: PackageManager.NameNotFoundException) {
            Log.e("AppSizeError", "Package not found", e)
            return 0L
        }

        val statsManager = context.getSystemService(StorageStatsManager::class.java)
        val uuid: UUID = StorageManager.UUID_DEFAULT
        val pkgStats: StorageStats?

        try {
            pkgStats = statsManager.queryStatsForUid(uuid, appInfo.uid)
        } catch (e: Exception) {
            Log.e("AppSizeError", "Error getting storage stats", e)
            return 0L
        }

        val cacheSize = pkgStats.cacheBytes  //缓存大小
        val dataSize = pkgStats.dataBytes //用户数据大小
        val codeSize = pkgStats.appBytes //包体大小

        return cacheSize + dataSize + codeSize
    }

    //获取App今日打开次数
    fun geAppTodayOpenCount(context: Context, packageName: String): Int {
        val usageStatsManager =
            context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

        val startTime = System.currentTimeMillis() - 1000 * 60 * 60 * 24 // Start time: 24 hours ago
        val endTime = System.currentTimeMillis()

        val events = usageStatsManager.queryEvents(startTime, endTime)

        var openCount = 0

        while (events.hasNextEvent()) {
            val event = UsageEvents.Event()
            events.getNextEvent(event)
            if (event.eventType == UsageEvents.Event.MOVE_TO_FOREGROUND && event.packageName != null && event.packageName == packageName) {
                openCount++
            }
        }

        return openCount
    }


    //获取app使用流量的时间
    fun getAppUseNetworkTime(context: Context, packageName: String, startTime: Long): Long {
        val usageStatsManager =
            context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        var totalForegroundWithNetworkTime: Long = 0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            val networkCapabilities =
                connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)

            if (networkCapabilities != null && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOREGROUND)) {
                val usageStatsList = usageStatsManager.queryUsageStats(
                    UsageStatsManager.INTERVAL_BEST, startTime, getEndTimeInMillis(
                        getTodayTimeInMillis()
                    )
                )
                if (usageStatsList != null) {
                    for (usageStats in usageStatsList) {
                        if (usageStats.lastTimeUsed in startTime..getEndTimeInMillis(
                                getTodayTimeInMillis()
                            ) && usageStats.packageName == packageName
                        ) {
                            totalForegroundWithNetworkTime += usageStats.totalTimeInForeground
                        }
                    }
                }
            }

            return totalForegroundWithNetworkTime
        }
        return 0L
    }

    private fun getUidOfPackage(context: Context, packageName: String): Int {
        val packageManager = context.packageManager
        val applicationInfo = packageManager.getApplicationInfo(packageName, 0)
        return applicationInfo.uid
    }


    //查询指定应用程序在指定时间段内的移动网络使用情况
    fun getAppDataUsage(
        context: Context,
        packageName: String,
        startTime: Long,
        endTime: Long
    ): Long {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            try {

                val networkStatsManager =
                    context.getSystemService(Context.NETWORK_STATS_SERVICE) as NetworkStatsManager

                val packageInfo = context.packageManager.getPackageInfo(packageName, 0)
                val uid = packageInfo.applicationInfo.uid


                val networkStats = networkStatsManager.querySummary(
                    NetworkCapabilities.TRANSPORT_CELLULAR,
                    null,
                    startTime,
                    endTime
                )

                var rxBytes: Long = 0
                var txBytes: Long = 0

                // 遍历网络使用情况数据,计算接收和发送的字节数
                val bucket = NetworkStats.Bucket()
                while (networkStats.hasNextBucket()) {
                    networkStats.getNextBucket(bucket)
                    if (bucket.uid == uid) {
                        rxBytes += bucket.rxBytes
                        txBytes += bucket.txBytes
                    }
                }


                return txBytes + rxBytes
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        return 0
    }

    //获取指定时间段内所有应用使用的流量字节数,默认结束时间时今晚0点整
    fun getAllAppDataUsage(context: Context, startTime: Long): Long {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkStatsManager =
                context.getSystemService(Context.NETWORK_STATS_SERVICE) as NetworkStatsManager
            val bucketMobile: NetworkStats.Bucket
            try {
                bucketMobile = networkStatsManager.querySummaryForDevice(
                    NetworkCapabilities.TRANSPORT_CELLULAR,
                    null,
                    startTime,
                    getEndTimeInMillis(System.currentTimeMillis())
                )
                return bucketMobile.txBytes + bucketMobile.rxBytes
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return -1L
    }

    //获取指定时间段内所有应用使用的流量字节数
    fun getAllAppDataUsage(context: Context, startTime: Long, endTime: Long): Long {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkStatsManager =
                context.getSystemService(Context.NETWORK_STATS_SERVICE) as NetworkStatsManager
            val bucketMobile: NetworkStats.Bucket
            try {
                bucketMobile = networkStatsManager.querySummaryForDevice(
                    NetworkCapabilities.TRANSPORT_CELLULAR,
                    null,
                    startTime,
                    endTime
                )
                return bucketMobile.txBytes + bucketMobile.rxBytes
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return -1L
    }

    fun getThisWeekEveryDayFlowList(context: Context): List<Flow> {
        var startTimeMillis = getThisWeekMondayTimeInMillis()
        val thisWeekEveryDayFlowList = ArrayList<Flow>()
        for (i in 0 until 7) {
            val endTimeMillis = getEndTimeInMillis(startTimeMillis, 1)
            val data = getByteFromMb(getAllAppDataUsage(context, startTimeMillis, endTimeMillis))

            val indexTime = when (i) {
                0 -> "周日"
                1 -> "周一"
                2 -> "周二"
                3 -> "周三"
                4 -> "周四"
                5 -> "周五"
                6 -> "周六"
                else -> "无效周数"
            }
            thisWeekEveryDayFlowList.add(
                Flow(
                    indexTime,
                    "${getTimeStringFromTimestamp2(startTimeMillis)}",
                    "$data MB"
                )
            )
            startTimeMillis = endTimeMillis
        }
        return thisWeekEveryDayFlowList
    }

    //获取空值的流量列表 一般用于未授权时展示
    fun getNullThisWeekUseFlowList() : List<Flow> {
        var startTimeMillis = FlowUtils.getThisWeekMondayTimeInMillis()
        val thisWeekEveryDayFlowList = ArrayList<Flow>()
        for (i in 0 until 7) {
            val endTimeMillis = FlowUtils.getEndTimeInMillis(startTimeMillis, 1)

            val indexTime = when (i) {
                0 -> "星期日"
                1 -> "星期一"
                2 -> "星期二"
                3 -> "星期三"
                4 -> "星期四"
                5 -> "星期五"
                6 -> "星期六"
                else -> "无效周数"
            }
            thisWeekEveryDayFlowList.add(Flow(indexTime, "${FlowUtils.getTimeStringFromTimestamp2(startTimeMillis)}", "- MB"))
            startTimeMillis = endTimeMillis
        }
        return thisWeekEveryDayFlowList
    }


    //获取本月每日的流量列表
    fun getThisMonthEveryDayFlowList(context: Context): List<Flow> {
        var timeInMills = getThisMonthTimeInMillis()
        val thisMonthEveryDayFlowList = ArrayList<Flow>()

        for (i in 0 until getDayOfMonth()) {
            val data = getByteFromMb(
                getAllAppDataUsage(
                    context,
                    timeInMills,
                    getEndTimeInMillis(timeInMills)
                )
            )
            thisMonthEveryDayFlowList.add(
                Flow(
                    "${i + 1}日",
                    "${getTimeStringFromTimestamp2(timeInMills)}",
                    "$data MB"
                )
            )
            timeInMills = getEndTimeInMillis(timeInMills)
        }
        return thisMonthEveryDayFlowList
    }

    //获取本月每周的流量列表
    fun getThisMonthToWeekFlowList(context: Context): ArrayList<Flow> {
        val thisMonthStertTimeInMillis = getThisMonthTimeInMillis()

        val todayEndTimeInMillis = getEndTimeInMillis(getTodayTimeInMillis())
        var thisTimeInMillis = thisMonthStertTimeInMillis

        val thisMonthEveryWeekFlowList = ArrayList<Flow>()
        var i = 1
        while (thisTimeInMillis < todayEndTimeInMillis) {
            val endTimeInMillis = getEndTimeInMillis(
                thisTimeInMillis,
                getDaysUntilNextSunday(thisTimeInMillis)
            )
            val flowNum = getByteFromGb(
                getAllAppDataUsage(
                    context,
                    thisTimeInMillis,
                    endTimeInMillis
                )
            )
            val dateTime = "${getTimeStringFromTimestamp2(thisTimeInMillis)} - ${
                getTimeStringFromTimestamp2(endTimeInMillis)
            } "
            thisMonthEveryWeekFlowList.add(Flow("第${i}周", dateTime, "$flowNum GB"))

            thisTimeInMillis = endTimeInMillis
            i++
        }
        return thisMonthEveryWeekFlowList
    }

    //获取本年每月的流量列表
    fun getThisYearEveryMonthFlowList(context: Context): List<Flow> {
        val everyMonthTimeInMillisList = getJanuaryToNextMonthStartTimeMillisList()
        val thisYearEveryMonthFlowList = ArrayList<Flow>()
        for (i in 0 until everyMonthTimeInMillisList.size - 1) {
            val data = getByteFromGb(
                getAllAppDataUsage(
                    context,
                    everyMonthTimeInMillisList[i],
                    everyMonthTimeInMillisList[i + 1]
                )
            )
            val dateTime =
                "${getTimeStringFromTimestamp2(everyMonthTimeInMillisList[i])} - ${everyMonthTimeInMillisList[i + 1]} "
            thisYearEveryMonthFlowList.add(Flow("${i + 1}月", dateTime, "$data GB"))
        }
        return thisYearEveryMonthFlowList

    }

    //设置流量列表的中每项的进度
    fun setFlowListProgress(flowList: List<Flow>): List<Flow> {
        val max = flowList.maxByOrNull { it.data.split(" ")[0].toFloat() }?.data?.toFloat() ?: 0f
        if (max > 0f) {
            flowList.forEach {
                it.progress = (it.data.split(" ")[0].toFloat() / max * 1.25 * 100).toInt()
            }
        }
        return flowList
    }

    // 获取移动数据网络的带宽
    fun getMobileDataSpeed(context: Context): Int {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork
            val capabilities = connectivityManager.getNetworkCapabilities(network)
            return capabilities?.let { capabilities.linkUpstreamBandwidthKbps + capabilities.linkDownstreamBandwidthKbps } ?: 0
        } else {
            return Random.nextInt(8192, 8192*100)
        }
    }

    //获取下载速度
    fun getUploadSpeed(context: Context): String {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network =connectivityManager.activeNetwork
            val capabilities = connectivityManager.getNetworkCapabilities(network)

            if (capabilities != null ){
                val speed = (capabilities.linkUpstreamBandwidthKbps / 8 / 1024).toDouble()
                if (speed > 0.0) {
                     return String.format("%.1f", Random.nextDouble(0.0, speed))
                }
            }
        }
        return String.format("%.1f", Random.nextDouble(  0.0,10.0))
    }

    //字节转MB
    fun getByteFromMb(bytes: Long): Float {
        return String.format("%.1f", bytes / (1024 * 1024f)).toFloat()
    }

    //字节转GB
    fun getByteFromGb(bytes: Long): Float {
        return String.format("%.1f", bytes / (1024 * 1024 * 1024f)).toFloat()
    }

    //判断是否为系统应用
    fun isSystemApp(packageInfo: PackageInfo): Boolean {
        return packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0
    }

    //获取网络延迟
    suspend fun getNetworkLatency(): String {
        return withContext(Dispatchers.IO) {
            var latency = "--"
            try {
                val socket = Socket()
                val startTime = System.currentTimeMillis()
                socket.connect(InetSocketAddress("www.baidu.com", 80), 3000)  // 连接百度服务器
                val endTime = System.currentTimeMillis()
                latency = (endTime - startTime).toString()
                Log.d("WifiInfo", "网络延迟: $latency ms")
                socket.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            latency
        }
    }

    //获取今年从1月到本月下一个月的每月开始日凌晨0:00的时间戳链表
    fun getJanuaryToNextMonthStartTimeMillisList(): List<Long> {
        val currentMonth = Calendar.getInstance().get(Calendar.MONTH)
        val currentYear = Calendar.getInstance().get(Calendar.YEAR)
        val timestamps = mutableListOf<Long>()

        val calendar = Calendar.getInstance()
        for (month in 0..currentMonth + 1) {
            calendar.clear()
            calendar.set(currentYear, month, 1, 0, 0, 0)
            timestamps.add(calendar.timeInMillis)
        }

        return timestamps

    }


    //当前年月
    fun getCurrentYearAndMonth(): String {
        val currentTime = Calendar.getInstance()
        val year = currentTime.get(Calendar.YEAR)
        val month = currentTime.get(Calendar.MONTH) + 1 // Calendar.MONTH 从 0 开始计数,所以需要加 1
        return "$year 年 $month 月"
    }

    //获取当前年月日
    fun getCurrentYearAndMonthAndDay(): String {
        val dateFormat = SimpleDateFormat("yyyy-MM-dd")
        val currentDate = Date()
        val formattedDate = dateFormat.format(currentDate)
        return formattedDate
    }

    //获取今天的在月份的天数
    fun getDayOfMonth(): Int {
        // 创建一个 Calendar 实例
        val calendar = Calendar.getInstance()
        // 将当前时间设置到 Calendar 实例中
        calendar.time = java.util.Date()
        return calendar.get(Calendar.DAY_OF_MONTH)
    }


    //流量单位转化
    fun getProgressFormatted(bytes: Long): String {
        return if (bytes < 1024) {
            "${bytes}B"
        } else if (bytes < 1024 * 1024) {
            String.format("%.1f", bytes / 1024f) + " KB"
        } else if (bytes < 1024 * 1024 * 1024) {
            String.format("%.1f", bytes / (1024 * 1024f)) + " MB"
        } else {
            String.format("%.1f", bytes / (1024 * 1024 * 1024f)) + " GB"
        }
    }

    //毫秒转化为中文时间字符串
    fun getMillisProgressFormattedChinese(millis: Long): String {
        val seconds = millis / 1000
        return when {
            seconds < 1 -> "${millis}毫秒"
            seconds < 60 -> "${seconds}秒"
            seconds < 3600 -> {
                val minutes = seconds / 60
                val remainingSeconds = seconds % 60
                "${minutes}分${remainingSeconds}秒"
            }

            else -> {
                val hours = seconds / 3600
                val remainingMinutes = (seconds % 3600) / 60
                "${hours}小时${remainingMinutes}分钟"
            }
        }
    }

    //毫秒单位转化
    fun getMillisProgressFormatted(millis: Long): String {
        val seconds = millis / 1000
        return when {
            seconds < 1 -> "${millis}ms"
            seconds < 60 -> "${seconds}s"
            seconds < 3600 -> {
                val minutes = seconds / 60
                val remainingSeconds = seconds % 60
                "${minutes}min${remainingSeconds}s"
            }

            else -> {
                val hours = seconds / 3600
                val remainingMinutes = (seconds % 3600) / 60
                val remainingSeconds = seconds % 60
                "${hours}h${remainingMinutes}min${remainingSeconds}s"
            }
        }
    }

    //获取本月总天数
    fun getThisMonthAllDayNum(): Int {
        val calendar = Calendar.getInstance()
        val year = calendar[Calendar.YEAR]
        val month = calendar[Calendar.MONTH]
        calendar[year, month] = 1 // 设置为本月的第一天
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
    }

    //获取今天的星期数
    fun getDayOfWeek(): Int {
        // 创建一个 Calendar 实例
        val calendar = Calendar.getInstance()

        // 将当前时间设置到 Calendar 实例中
        calendar.time = java.util.Date()

        // 获取今天的星期数,星期日为 1,星期一为 2,以此类推
        return calendar.get(Calendar.DAY_OF_WEEK)
    }

    //获取传入时间戳的星期数
    fun getDayOfWeek(timestamp: Long): String {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = timestamp
        val dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)
        val days =
            arrayOf("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
        return days[dayOfWeek - 1]
    }


    //获取本周开始日(周日)凌晨的时间戳
    fun getThisWeekMondayTimeInMillis(): Long {

        val calendar = Calendar.getInstance()

        calendar.firstDayOfWeek = Calendar.SUNDAY
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
        calendar.set(Calendar.HOUR_OF_DAY, 0)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)

        // 返回时间戳
        return calendar.timeInMillis
    }

    //获取传入时间戳距离下周开始日(周末)的天数
    fun getDaysUntilNextSunday(timestamp: Long): Int {
        val calendar = Calendar.getInstance().apply {
            timeInMillis = timestamp
        }
        val currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)
        val daysUntilNextSunday = 8 - currentDayOfWeek // 计算距离下一周开始日(星期日)的天数
        return daysUntilNextSunday
    }

    //获取本月开始日凌晨的时间戳
    fun getThisMonthTimeInMillis(): Long {
        val cal = Calendar.getInstance()
        cal[cal[Calendar.YEAR], cal[Calendar.MONTH], cal[Calendar.DAY_OF_MONTH], 0, 0] =
            0
        cal[Calendar.DAY_OF_MONTH] = cal.getActualMinimum(Calendar.DAY_OF_MONTH)
        return cal.timeInMillis
    }


    //获取今天凌晨的时间戳
    fun getTodayTimeInMillis(): Long {
        val calendar = Calendar.getInstance()
        calendar.set(Calendar.HOUR_OF_DAY, 0)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)
        return calendar.timeInMillis
    }

    //获取传入时间下一天凌晨的时间戳
    fun getEndTimeInMillis(startTime: Long): Long {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = startTime
        calendar.add(Calendar.DAY_OF_MONTH, 1) // 加一天
        calendar.set(Calendar.HOUR_OF_DAY, 0)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)
        return calendar.timeInMillis
    }

    //获取传入时间几天前/后凌晨的时间戳
    fun getEndTimeInMillis(startTime: Long, i: Int): Long {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = startTime
        calendar.add(Calendar.DAY_OF_MONTH, i) // 增加/减少i天
        calendar.set(Calendar.HOUR_OF_DAY, 0)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)
        return calendar.timeInMillis
    }

    //获取几天前凌晨的时间戳
    fun getStartTimeInMillis(i: Int): Long {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = System.currentTimeMillis()
        calendar.add(Calendar.DAY_OF_YEAR, i) // 增加/减少i天
        calendar.set(Calendar.HOUR_OF_DAY, 0) // 设置小时为零
        calendar.set(Calendar.MINUTE, 0) // 设置分钟为零
        calendar.set(Calendar.SECOND, 0) // 设置秒数为零
        calendar.set(Calendar.MILLISECOND, 0) // 设置毫秒为零
        return calendar.timeInMillis
    }

    //获取现在的时间
    fun getCurrentTime(): String {
        val currentTime = Calendar.getInstance().time
        val dateFormat = SimpleDateFormat("MM/dd HH:mm:ss", Locale.getDefault())
        return dateFormat.format(currentTime)
    }

    //获取日期的时间戳
    fun getTimestampAtMidnight(year: Int, month: Int, dayOfMonth: Int): Long {
        val calendar = Calendar.getInstance(TimeZone.getDefault())
        calendar.set(Calendar.YEAR, year)
        calendar.set(Calendar.MONTH, month - 1) // 注意:Java Calendar月份是从0开始的
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
        calendar.set(Calendar.HOUR_OF_DAY, 0)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)

        return calendar.timeInMillis
    }

    //通过时间戳获取时间
    fun getTimeStringFromTimestamp(timestamp: Long): String {
        val sdf = SimpleDateFormat("yyyy/MM/dd HH:mm", Locale.getDefault())
        return sdf.format(Date(timestamp))
    }

    fun getTimeStringFromTimestamYMD(timestamp: Long): String {
        val sdf = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault())
        return sdf.format(Date(timestamp))
    }

    fun getTimeStringFromTimestampD(timestamp: Long): String {
        val sdf = SimpleDateFormat("d", Locale.getDefault())
        return sdf.format(Date(timestamp))
    }

    fun getTimeStringFromTimestamp2(timestamp: Long): String {
        val sdf = SimpleDateFormat("MM.dd", Locale.getDefault())
        return sdf.format(Date(timestamp))
    }
    fun getTimeStringFromTimestampMDD(timestamp: Long): String {
        val sdf = SimpleDateFormat("M.dd", Locale.getDefault())
        return sdf.format(Date(timestamp))
    }

    //计算两个时间戳相差的天数
    fun daysBetweenTimestamps(startTimestamp: Long, endTimestamp: Long): Long {
        // 创建 Calendar 实例
        val calendarStart = Calendar.getInstance()
        val calendarEnd = Calendar.getInstance()

        // 设置 Calendar 对象的时间为指定的时间戳
        calendarStart.timeInMillis = startTimestamp
        calendarEnd.timeInMillis = endTimestamp

        // 计算两个时间戳之间的差值(毫秒)
        val diffInMillis = calendarEnd.timeInMillis - calendarStart.timeInMillis

        return Math.abs(TimeUnit.MILLISECONDS.toDays(diffInMillis))
    }

    //显示选择日期的日历dialog
    fun showDatePickerDialog(context: Context, calendar: Calendar = Calendar.getInstance(), onDateSet: (year: Int, month: Int, day: Int) -> Unit ) {
        DatePickerDialog(
            context,
            { _, year, monthOfYear, dayOfMonth ->
                onDateSet(year, monthOfYear + 1, dayOfMonth)
            },
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH)
        ).show()
    }

}

5. 其他

5.1导入后面需要的包

   //协程
   api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2"
   api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2"
   api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
   api "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
   api "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"

   //retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.6.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.6.1'

5.2获取IP相关信息和下载速度的接口

5.2.1  接口服务类

interface RetrofitService {

    @Streaming
    @GET
    fun downloadFile(@Url fileUrl: String): Call<ResponseBody>
    @GET("jsonp")
    fun getGeoLocation( @Query("ip")  ip : String?): Call<ResponseBody>
    @GET("jsonp")
    fun getGeoLocation(): Call<ResponseBody>
}

 5.2.3 ip的Bean

data class IpInfo(
    val country: String?,
    val shortName: String?,
    val province: String?,
    val city: String?,
    val area: String?,
    val isp: String?,
    val net: String?,
    val ip: String?,
    val code: Int?,
    val desc: String?
){
    constructor() : this("--","--","--","--","--","--","--","--",0,"--")

}

 5.2.3 实现类

package 你的包名

import android.content.Context
import android.os.Environment
import android.util.Log
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.io.FileOutputStream

class RetrofitImpl {
    //获取下载速度
    suspend fun getDownloadSpeed(context: Context): String {
        val retrofit = Retrofit.Builder()
            .baseUrl("https://dldir1.qq.com/")
            .build()

        val service = retrofit.create(RetrofitService::class.java)

        return withContext(Dispatchers.IO) {
            val call =
                service.downloadFile("qqfile/qq/QQNT/Windows/QQ_9.9.7_240305_x86_01.exe").execute()
            if (call.isSuccessful) {
                val body = call.body()
                if (body != null) {
                    val startTime = System.currentTimeMillis()

                    val inputStream = body.byteStream()
                    val file =
                        File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "qq.apk")
                    val fileOutputStream = FileOutputStream(file)
                    val buffer = ByteArray(4096)
                    var bytesRead: Int
                    var totalBytesRead = 0

                    while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                        fileOutputStream.write(buffer, 0, bytesRead)
                        totalBytesRead += bytesRead

                        val currentTime = System.currentTimeMillis()
                        if (currentTime - startTime >= 1000) {
                            val totalTime = currentTime - startTime
                            val speedBytesPerSecond = totalBytesRead.toFloat() / totalTime * 1000
                            val speedMegaBytesPerSecond =
                                String.format("%.1f", speedBytesPerSecond / (1024 * 1024))

                            Log.d("RetrofitImpl", "Download speed: ${speedMegaBytesPerSecond} MB/s")

                            fileOutputStream.close()
                            inputStream.close()

                            return@withContext speedMegaBytesPerSecond
                        }
                    }

                    // 如果在一秒内下载未完成,则直接关闭流
                    fileOutputStream.close()
                    inputStream.close()
                }
            }
            return@withContext "-- Mb/s"
        }
    }

    //查询公网Ip对于的信息 包括所属省份、城市、运营商、网络类型等
    suspend fun getGeoLocation(ipAddress: String?): IpInfo {

        val BASE_URL = "https://ip.useragentinfo.com/"
        val httpClient = OkHttpClient.Builder().build()

        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(httpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val service = retrofit.create(RetrofitService::class.java)

        return withContext(Dispatchers.IO) {

            val response = if (ipAddress == null) {
                service.getGeoLocation().execute()  //查询本客户端
            }else{
                service.getGeoLocation(ipAddress).execute()
            }

            if (response.isSuccessful) {
                val responsedata = response.body()?.string()
                val data = Gson().fromJson(responsedata.toString().substring(9, responsedata!!.length - 2), IpInfo::class.java)

                Log.d("RetrofitImpl","获取公网Ip信息"+data.toString())

                return@withContext data
            }
            return@withContext IpInfo()
        }
    }
}

6.示例

fun getAndUpdateData() {
        
        CoroutineScope(Dispatchers.IO).launch {

            //下载速度
            val  downloadSpeed = RetrofitImpl().getDownloadSpeed(context)
            //网络延迟
            val networLatency = FlowUtils.getNetworkLatency()
            //网络带宽
            val mobileData = FlowUtils.getMobileDataSpeed(context)
            

            //今日使用的总流量数
            todayUseFlow = FlowUtils.getByteFromMb(
                FlowUtils.getAllAppDataUsage(
                    requireContext(),
                    FlowUtils.getTodayTimeInMillis()
                )
            )
            //本月使用的总流量数
            thisMonthUseFlow = FlowUtils.getByteFromGb(
                FlowUtils.getAllAppDataUsage(
                    requireContext(),
                    FlowUtils.getThisMonthTimeInMillis()
                )
            )
            //本周使用的总流量数
            thisWeekUseFlow = FlowUtils.getByteFromGb(
                FlowUtils.getAllAppDataUsage(
                    requireContext(),
                    FlowUtils.getThisWeekMondayTimeInMillis()
                )
            )
            //今日流量使用情况的appBean列表
            val todayApps = FlowUtils.getAllInstalledAppsInfo(
                requireContext(),
                FlowUtils.getTodayTimeInMillis()
            )
            //本周流量使用情况的appBean列表
            val thisWeekApps = FlowUtils.getAllInstalledAppsInfo(
                requireContext(),
                FlowUtils.getThisWeekMondayTimeInMillis()
            )
            //本月流量使用情况的appBean列表
            val thisMonthApps = FlowUtils.getAllInstalledAppsInfo(
                requireContext(),
                FlowUtils.getThisMonthTimeInMillis()
            )

            withContext(Dispatchers.Main) {

                //展示和处理相关数据

            }
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938726.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget

目录 QLabel QFrame 例子&#xff1a; textFormat pixmap、scaledContents alignment wordWrap、indent、margin buddy QLCDNumber 例子&#xff1a; QTimer QProgressBar 例子&#xff1a; QCalendarWidget 例子&#xff1a; QLabel 标签控件&#xff0c;用来显示…

0001.基于springmvc简易酒店管理系统后台

一.系统架构 springmvcjsplayuimysql 二.功能特性 简单易学习&#xff0c;虽然版本比较老但是部署方便&#xff0c;tomcat环境即可启用&#xff1b;代码简洁&#xff0c;前后端代码提供可统一学习&#xff1b;祝愿您能成尽快为一位合格的程序员&#xff0c;愿世界没有BUG; …

Wallpaper壁纸制作学习记录12

角色表 创建人偶变形动画的更高级方法可以使用角色表来完成。角色表要求您使用角色的切割版本&#xff0c;将您的角色分成不同肢体/部分。这允许创建更复杂、更准确的动画&#xff0c;因为部分可以自由移动和重叠&#xff0c;而不会使图像失真。使用操控变形不一定能获得良好的…

【Python项目】基于Django的语音和背景音乐分离系统

【Python项目】基于Django的语音和背景音乐分离系统 技术简介&#xff1a;采用Python技术、Django框架、B/S结构&#xff0c;MYSQL数据库等实现。 系统简介&#xff1a;系统完成在线的音频上传&#xff0c;并且通过计算机的神经网络算法来对系统中的背景音乐和人声进行分离操作…

负载均衡oj项目:介绍

目录 项目介绍 项目演示 项目介绍 负载均衡oj是一个基于bs模式的项目。 用户使用浏览器向oj模块提交代码&#xff0c;oj模块会在所有在线的后端主机中选择一个负载情况最低的主机&#xff0c;将用户的代码提交给该主机&#xff0c;该主机进行编译运行&#xff0c;将结果返回…

【鸿睿创智开发板试用】移植OpenCV 4到OpenHarmony 4.1

目录 目录 引言 编译系统镜像 (1) 下载代码后解压SDK (2) 下载docker镜像   (3) 编译OH 编译OpenCV 下载OpenCV源代码 构建编译配置文件 执行编译命令 安装库和头文件 测试 结语 引言 最近有个需求是在基于RK3568的OpenHarmony 4.1系统中使用OpenCV&#xff0c…

【HarmonyOS之旅】HarmonyOS开发基础知识(一)

目录 1 -> 应用基础知识 1.1 -> 用户应用程序 1.2 -> 用户应用程序包结构 1.3 -> Ability 1.4 -> 库文件 1.5 -> 资源文件 1.6 -> 配置文件 1.7 -> pack.info 1.8 -> HAR 2 -> 配置文件简介 2.1 -> 配置文件的组成 3 -> 配置文…

【机器人】Graspness 端到端抓取点估计 | 环境搭建 | 模型推理测试

在复杂场景中实现抓取检测&#xff0c;Graspness是一种端到端的方法&#xff1b; 输入点云数据&#xff0c;输出抓取角度、抓取深度、夹具宽度等信息。 开源地址&#xff1a;https://github.com/rhett-chen/graspness_implementation?tabreadme-ov-file 论文地址&#xff1…

B站bilibili视频转文字字幕下载方法

本文将讲述介绍一种使用本地工具如何快速的下载B站的字幕为本地文本文件的方法。 通常获取B站字幕需要在浏览器中安装第三方插件&#xff0c;通过插件获取字幕。随着大模型&#xff0c;生成式AI&#xff0c;ChatGPT的应用&#xff0c;B站也提供了AI小助手对视频的内容进行总结…

CSS3 实现火焰-小火苗效果

创建 CSS3 火焰效果可以通过组合 CSS 动画、伪元素 和 渐变 来实现。以下是一个简单的实现步骤&#xff0c;展示如何制作动态火焰效果 1. HTML 结构 我们只需要一个简单的 div 容器&#xff1a; <div class"fire"></div>2. CSS 实现 基础样式 使用 …

新能源汽车充电需求攀升,智慧移动充电服务有哪些实际应用场景?

在新能源汽车行业迅猛发展的今天&#xff0c;智慧充电桩作为支持这一变革的关键基础设施&#xff0c;正在多个实际应用场景中发挥着重要作用。从公共停车场到高速公路服务区&#xff0c;从企业园区到住宅小区&#xff0c;智慧充电桩不仅提供了便捷的充电服务&#xff0c;还通过…

git remote -v(--verbose)显示你的 Git 仓库配置的远程仓库的详细信息

git remote -v 是一个 Git 命令&#xff0c;用于显示你的 Git 仓库配置的远程仓库的详细信息。 当你执行 git remote -v 命令时&#xff0c;你会看到类似以下的输出&#xff1a; origin https://github.com/your-username/your-repo.git (fetch) origin https://github.com…

Java Web项目部署教程简单实用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

【爬虫一】python爬虫基础合集一

【爬虫一】python爬虫基础合集一 1. 网络请求了解1.1. 请求的类型1.2. 网络请求协议1.3. 网络请求过程简单图解1.4. 网络请求Headers(其中的关键字释义)&#xff1a;请求头、响应头 2. 网络爬虫的基本工作节点2.1. 了解简单网络请求获取响应数据的过程所涉及要点 1. 网络请求了…

清理C盘小记

突然C盘就爆满了&#xff0c;想当初还是给他预留了120G的空间&#xff0c;感觉到现在也不够用了&#xff0c;担心出现死机的情况就赶紧进行了清理。有一说一&#xff0c;清理回收站是真的有用。 参考&#xff1a;C盘清理指南&#xff0c;清理出30G起&#xff0c;超详细总结&am…

Ansible playbook 详解与实战操作

一、概述 playbook 与 ad-hoc 相比,是一种完全不同的运用 ansible 的方式&#xff0c;类似与 saltstack 的 state 状态文件。ad-hoc 无法持久使用&#xff0c;playbook 可以持久使用。 playbook 是由一个或多个 play 组成的列表&#xff0c;play 的主要功能在于将事先归并为一…

seata-2阶段提交-笔记3

本文属于B站图灵课堂springcloud笔记系列。 前面整理过2篇:seata 2阶段提交实现代码-笔记1-CSDN博客 扫描GlobalTransactional注解 seata 2阶段提交实现代码-笔记2-CSDN博客 TC生成XID&#xff0c;并保存到global_table表。 本篇继续整理 执行业务逻辑&#xff0c;提交本地…

Docker如何运行一个Java的jar包程序

Docker如何运行一个Java的jar包程序 1、jar包程序 2、start.sh运行jar包脚本 #!/bin/bash #进入目录 cd /app #1.下载SDK并安装 java -jar SDKDown1.4.jar #2.加载环境变量 export LD_LIBRARY_PATH/opt/casb/CipherSuiteSdk_linux/lib echo $LD_LIBRARY_PATH #3.执行SDK java …

Pycharm访问MongoDB数据库

MongoDB的基础操作 1. 创建连接 #导入pymongo中的用于操作数据库的客户端 from pymongo import MongoClient #创建客户端对象&#xff0c;连接MongoDB服务器 client MongoClient(mongodb://admin:admin123456localhost:27017) 2. 数据的增删改查 2.1 数据的写入 from mon…

【Python】编写一个函数,将指定的罗马字符转换为数字的形式。

#编写一个函数&#xff0c;将指定的罗马字符转换为数字的形式。R2N {I:1, V:5, X:10, L:50, C:100, D:500, M:1000}def roman2num(s):r 0n len(s)for i, ch in enumerate(s):v R2N[ch]if i < n-1 and v < R2N[s[i1]]:r - velse:r vreturn r;s input("请输入一…