Как написать метку времени создания в apk
- Внесение изменений в пакет контактов Android
- Использование команды
mm
(make) для создания этого приложения
Потому что мне нужно снова и снова менять и создавать это приложение, поэтому я хочу добавить штамп времени сборки в Contacts.apk
, чтобы проверить время сборки, когда мы запустили его в трубке.
Как мы знаем, когда мы запустим команду mm
, вызывается Android.mk
(makefile) в пакете Contacts.
И теперь мы можем получить время сборки с помощью date
-macro.
Но как мы можем записать эту метку времени сборки в файл, который наше приложение может читать во время выполнения?
Любые предложения?
Ответы
Ответ 1
Если вы используете Gradle, вы можете добавить buildConfigField
с меткой времени, обновленной во время сборки.
android {
defaultConfig {
buildConfigField "long", "TIMESTAMP", System.currentTimeMillis() + "L"
}
}
Затем прочитайте его во время выполнения.
Date buildDate = new Date(BuildConfig.TIMESTAMP);
Ответ 2
Метод, который проверяет дату последней модификации classes.dex, это означает последний раз, когда был создан ваш код приложения:
try{
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), 0);
ZipFile zf = new ZipFile(ai.sourceDir);
ZipEntry ze = zf.getEntry("classes.dex");
long time = ze.getTime();
String s = SimpleDateFormat.getInstance().format(new java.util.Date(time));
zf.close();
}catch(Exception e){
}
Протестировано и прекрасно работает, даже если приложение установлено на SD-карте.
Ответ 3
Начиная с версии API версии 9:
PackageInfo.lastUpdateTime
Время последнего обновления приложения.
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
//TODO use packageInfo.lastUpdateTime
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
В более низких версиях API вы должны самостоятельно создать время сборки. Например, вставьте файл в папку с данными, содержащую дату. Или используя макрос __ DATE__ в собственном коде. Или проверить дату, когда был создан ваш класс .dex(дата файла в вашем APK).
Ответ 4
Подсказка для решения "время последней модификации файла classes.dex" - более новые версии AndroidStudio:
В конфигурации по умолчанию метка времени больше не записывается в файлы в файле apk. Временная метка всегда "30 ноября 1979 года".
Вы можете изменить это поведение, добавив эту строку в файл
% userdir%/. gradle/ gradle.properties(создать, если не существует)
android.keepTimestampsInApk = true
См. Проблема 220039
(Должно быть в userdir, gradle.properties в проекте build dir, похоже, не работает)
Ответ 5
в вашем build.gradle:
android {
defaultConfig {
buildConfigField 'String', 'BUILD_TIME', 'new java.text.SimpleDateFormat("MM.dd.yy HH:mm", java.util.Locale.getDefault()).format(new java.util.Date(' + System.currentTimeMillis() +'L))'
}
}
Ответ 6
Install time : packageInfo.lastUpdateTime
build time : zf.getEntry("classes.dex").getTime()
Оба имеют разное время.
Вы можете проверить код ниже.
public class BuildInfoActivity extends Activity {
private static final String TAG = BuildInfoActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
PackageManager pm = getPackageManager();
PackageInfo packageInfo = null;
try {
packageInfo = pm.getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
// install datetime
String appInstallDate = DateUtils.getDate(
"yyyy/MM/dd hh:mm:ss.SSS", packageInfo.lastUpdateTime);
// build datetime
String appBuildDate = DateUtils.getDate("yyyy/MM/dd hh:mm:ss.SSS",
DateUtils.getBuildDate(this));
Log.i(TAG, "appBuildDate = " + appBuildDate);
Log.i(TAG, "appInstallDate = " + appInstallDate);
} catch (Exception e) {
}
}
static class DateUtils {
public static String getDate(String dateFormat) {
Calendar calendar = Calendar.getInstance();
return new SimpleDateFormat(dateFormat, Locale.getDefault())
.format(calendar.getTime());
}
public static String getDate(String dateFormat, long currenttimemillis) {
return new SimpleDateFormat(dateFormat, Locale.getDefault())
.format(currenttimemillis);
}
public static long getBuildDate(Context context) {
try {
ApplicationInfo ai = context.getPackageManager()
.getApplicationInfo(context.getPackageName(), 0);
ZipFile zf = new ZipFile(ai.sourceDir);
ZipEntry ze = zf.getEntry("classes.dex");
long time = ze.getTime();
return time;
} catch (Exception e) {
}
return 0l;
}
}
}
Ответ 7
Я использую ту же стратегию, что и указатель Null, за исключением того, что я предпочитаю файл MANIFEST.MF.
Этот регенерируется, даже если макет изменен (что не относится к classes.dex).
Я также заставляю дату формироваться в GMT, чтобы избежать путаницы между терминальными и серверными ТЗ (если нужно провести сравнение, например: проверить последнюю версию).
В результате получается следующий код:
try{
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), 0);
ZipFile zf = new ZipFile(ai.sourceDir);
ZipEntry ze = zf.getEntry("META-INF/MANIFEST.MF");
long time = ze.getTime();
SimpleDateFormat formatter = (SimpleDateFormat) SimpleDateFormat.getInstance();
formatter.setTimeZone(TimeZone.getTimeZone("gmt"));
String s = formatter.format(new java.util.Date(time));
zf.close();
}catch(Exception e){
}
Ответ 8
Я знаю, что это действительно старо, но вот как я это сделал, используя ant внутри eclipse:
build.xml в корне проекта
<project name="set_strings_application_build_date" default="set_build_date" basedir=".">
<description>
This ant script updates strings.xml application_build_date to the current date
</description>
<!-- set global properties for this build -->
<property name="strings.xml" location="./res/values/strings.xml"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
</target>
<target name="set_build_date" depends="init" description="sets the build date" >
<replaceregexp file="${strings.xml}"
match="(<string name="application_build_date">)\d+(</string>)"
replace="<string name="application_build_date">${DSTAMP}</string>" />
</target>
</project>
Затем добавьте строку application_build_date в свой файл strings.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">your app name</string>
<string name="application_build_date">20140101</string>
...
</resources>
Убедитесь, что ant script выполняется как операция предварительной сборки, и вы всегда будете иметь действительную дату сборки, доступную для вас в файле R.string.application_build_date.
Ответ 9
Итак, Android Developer - Руководство пользователя Android Studio - Советы и рецепты Gradle - Упрощенная разработка приложений фактически документирует, что добавить, чтобы иметь метку времени выпуска, доступную для вашего приложения:
android {
...
buildTypes {
release {
// These values are defined only for the release build, which
// is typically used for full builds and continuous builds.
buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
resValue("string", "build_time", "${minutesSinceEpoch}")
...
}
debug {
// Use static values for incremental builds to ensure that
// resource files and BuildConfig aren't rebuilt with each run.
// If they were dynamic, they would prevent certain benefits of
// Instant Run as well as Gradle UP-TO-DATE checks.
buildConfigField("String", "BUILD_TIME", "\"0\"")
resValue("string", "build_time", "0")
}
}
}
...
В коде приложения вы можете получить доступ к свойствам следующим образом:
...
Log.i(TAG, BuildConfig.BUILD_TIME);
Log.i(TAG, getString(R.string.build_time));
Я включил это здесь, так как все другие решения, по-видимому, были до официального примера.
Ответ 10
Для отметки времени и управления версиями build.gradle/android/defaultConfig:
def buildDateStamp = new Date().format("yyyyMMdd").toInteger()
versionCode buildDateStamp
versionName "$buildDateStamp"
buildConfigField "String", "BUILD_DATE_STAMP", "\"$buildDateStamp\""
Использование в коде: BuildConfig.BUILD_DATE_STAMP
resValue "string", "build_date_stamp", "$buildDateStamp"
Использование в xml: "@string/build_date_stamp"
Предостережение: добавление HHmm
приведет к ошибкам (возможно, целочисленное переполнение)