获取Android中的实时时间,而不是设备设置的时间

31
如何查找“真实地理时间”,因为我想将实时时间附加到我的应用程序中。因此,如果用户更改设备上的时间,则我应该仅获得真实的流行时间-而不是设备时间。我的问题很困惑,但请尝试用简单的语言理解-我不想要设备时间,我想要任何时刻的真实流行时间。

@penguat 我只想知道现在的真实时间,不是UTC或GMT时间。 - Ashish Dwivedi
你是指设备所在地的当地时间吗? - penguat
3
"Real time" 的确切含义是什么? - Kumar Bibek
3个回答

13

您需要使用NTP(网络时间协议)协议:

这里是我在其他地方找到的一些代码...我正在使用它。这使用了Apache Commons库,可以使用Gradle安装(在commons-net:commons-net:3.6上添加依赖项)

如果您需要时间服务器列表,请检查:http://tf.nist.gov/service/time-servers.html

这里是一些Java代码供您使用:

public class TimeLookup {
    public static final String TIME_SERVER = "time-a.nist.gov";

    public static void main(String[] args) throws Exception {
        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
        TimeInfo timeInfo = timeClient.getTime(inetAddress);
        long returnTime = timeInfo.getReturnTime();
        Date time = new Date(returnTime);
        System.out.println("Time from " + TIME_SERVER + ": " + time);
    }

}

注意 Android 代码必须在后台线程上运行,并包含 gradle 依赖项:

implementation 'commons-net:commons-net:3.6'

在我的情况下,有效的时间戳是通过以下方式找到的:timeInfo.getMessage().getReceiveTimeStamp().getTime()。 - androidevil
1
long returnTime = timeInfo.getMessage().getReceiveTimeStamp().getTime();返回时间 = timeInfo.getMessage().getReceiveTimeStamp().getTime(); - Stefano
1
旧帖子,但在这里很重要:Stefano是正确的。如果像帖子中所示获取时间,则返回(在API中描述)**...本地机器接收到时间消息数据包。看起来这会返回设备时间,我试过了。但是,如果您使用timeInfo.getMessage().getReceiveTimeStamp().getTime(),则会得到(在API中描述)...根据RC_1305定义的接收时间**,这是无论设备中定义什么都是净时间。 - Opiatefuchs
1
即使您使用此方法,更改手机上的时间也会导致NTPUDPClient提供该时间,而不是来自主机的时间。 - f.trajkovski

5

没有 Android API 可以为您提供这样的时间。用户始终可以更改设备时间,对此无可奈何。

最好的方法是运行一个 Web 服务的服务器,从中获取时间。由于您控制了服务器,您可以尝试确保它返回正确的时间。


我们可以使用Joda Time库吗? - Prashanth Debbadwar
我收到的数据有一个过期时间(20秒),我如何确保我与之进行比较的设备时间是正确的,而不强制用户启用该设备的“自动时间”功能。 - Mohsin Falak

0

下面的代码可以让我获取真实日期,即使设备日期不正确。感谢@Stefano。

import org.apache.commons.net.ntp.NTPUDPClient
import java.net.InetAddress
import java.text.SimpleDateFormat
import java.util.*


object DateOperation {

    private const val TIME_SERVER = "time-a.nist.gov"
    const val DATE_PATTERN = "yyyy-MM-dd"

    suspend fun getRealDay(): String {
        val timeClient = NTPUDPClient()
        val inetAddress: InetAddress = InetAddress.getByName(TIME_SERVER)
        val timeInfo = timeClient.getTime(inetAddress)
        val returnTime = timeInfo.message.receiveTimeStamp.date
        val t = SimpleDateFormat(DATE_PATTERN, Locale.ENGLISH)
        return t.format(returnTime)
    }
}


添加依赖项后:

implementation 'commons-net:commons-net:3.6'

然后像这样使用它

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch(Dispatchers.IO) {
            val date = getRealDay()
            Log.d("TestTest", "onCreate: $date")

        }

    }

`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接