Как программно получить время сборки приложения?

Я немного поискал и нашел аналогичный вопрос и ответ на: Как мне узнать время последней модификации ресурса Java?

Поэтому я немного изменил код, и теперь мой код выглядит так:

import android.os.Build;
import androidx.annotation.RequiresApi;
import java.io.File;
import java.net.URL;
import java.nio.file.attribute.FileTime;
import java.text.DateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

public class GetBuildTime {

  private static String getJarName() {
    Class<?> currentClass = getCurrentClass();
    return new File(currentClass.getProtectionDomain()
                                .getCodeSource()          // Error at line 24
                                .getLocation()
                                .getPath())
                                .getName();
  }

  private static Class<?> getCurrentClass() {
    return new Object() { }.getClass().getEnclosingClass();
  }

  private static boolean runningFromJAR() {
    String jarName = getJarName();
    return jarName.endsWith(".jar");
  }

  @RequiresApi(api = Build.VERSION_CODES.O)
  public static String getLastModifiedDate() {
    Date date=null;

    try {
      if (runningFromJAR()) {
        String jarFilePath = getJarName();
        try (JarFile jarFile = new JarFile(jarFilePath)) {
          long lastModifiedDate = 0;

          for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements(); ) {
            String element = entries.nextElement().toString();
            ZipEntry entry = jarFile.getEntry(element);
            FileTime fileTime = entry.getLastModifiedTime();
            long time = fileTime.toMillis();
            if (time > lastModifiedDate) lastModifiedDate = time;
          }
          date = new Date(lastModifiedDate);
        }
      } else {
        Class<?> currentClass = getCurrentClass();
        URL resource = currentClass.getResource(currentClass.getSimpleName() + ".class");

        switch (resource.getProtocol()) {
          case "file" : date = new Date(new File(resource.toURI()).lastModified()); break;
          default : throw new IllegalStateException("No matching protocol found!");
        }
      }
    } catch (Exception e) { e.printStackTrace(); }

    if (date != null) {
      DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
      return dateFormat.format(date);
    } else return "";
  }
}

Но когда я запустил эту программу в Android Studio, я получил следующую ошибку:

java.lang.NullPointerException: попытка вызвать виртуальный метод java.security.CodeSource java.security.ProtectionDomain.getCodeSource() для ссылки на нулевой объект в com.gate.gate_android.GetBuildTime.getJarName(GetBuildTime.java:24)

Как правильно это сделать?

1 ответ

Попробуй это. (Простите за Котлина)

В вашем модуле приложения gradle:

       defaultConfig {
        minSdk = Application.minSdk
        targetSdk = Application.targetSdk
        versionCode = Application.versionCode
        versionName = Application.versionName
        multiDexEnabled = true
        setProperty("archivesBaseName", "$versionName ($versionCode)")

        vectorDrawables {
            useSupportLibrary = true
        }

        buildConfigField("long", "TIMESTAMP", "${System.currentTimeMillis()}L") // added
    }

Использование:

              val builtDate = Calendar.getInstance().apply { timeInMillis = BuildConfig.TIMESTAMP }
        val builtTime = "${builtDate.get(Calendar.HOUR_OF_DAY)}h" +
            " ${builtDate.get(Calendar.MINUTE)}m " +
            "${builtDate.get(Calendar.SECOND)}s"

        toast("Built at: $builtTime", Toast.LENGTH_LONG)
Другие вопросы по тегам