Intereting Posts
Проблемы с камерой и фотографией для Android с Samsung Galaxy S3, S4, S5 Как установить .xap phonegap построить в Windows Phone 8? Удаляет ли приложение андроида удаление базы данных, хранящейся на SD-карте? Android Studio – с Junit 4.12 "!!! Ожидается, что версия JUnit версии 3.8 или более поздней версии: Предварительный просмотр резервной копии виджетов Использование `onRetainCustomNonConfigurationInstance` для сохранения данных при изменении конфигурации Медленная загрузка SDK через Android SDK manager Кэширование профилей ProfilePictureView для Android Android SDK Android масштабирование изображения из setImageBitmap Android Espresso Ui Test проверяет текст ярлыка ActionPage Остановите или освободите MediaPlayer, пока он все еще готовится IntelliJ / Android -> "java: требуется постоянное выражение" на случай R.id.viewId Done не работает в softKeyboard в Autocomplete TextView в android Невозможно найти цели Android в этом SDK в IntelliJ 2016 Всегда запускайте основное мероприятие

Как написать метку времени создания в apk

  1. Внесение изменений в пакет Android Contacts
  2. Использование команды mm (make) для создания этого приложения

Потому что мне нужно менять и создавать это приложение снова и снова, поэтому я хочу добавить штамп времени сборки в Contacts.apk чтобы проверить время сборки, когда мы запустим его в трубке.

Как мы знаем, когда мы запустим команду mm , Android.mk пакет Android.mk (makefile) в папке «Контакты».

И теперь мы можем получить время сборки, используя date -macro.

Но как мы можем записать эту метку времени сборки в файл, который наше приложение может читать во время выполнения?

Какие-либо предложения?

Solutions Collecting From Web of "Как написать метку времени создания в apk"

Метод, который проверяет дату последней модификации 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-карте.

Если вы используете Gradle, вы можете добавить buildConfigField с меткой времени, обновленной во время сборки.

 android { defaultConfig { buildConfigField "long", "TIMESTAMP", System.currentTimeMillis() + "L" } } 

Затем прочитайте его во время выполнения.

 Date buildDate = new Date(BuildConfig.TIMESTAMP); 

Начиная с версии 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).

Подсказка для решения «время последней модификации файла classes.dex» – новые версии AndroidStudio: в конфигурации по умолчанию метка времени больше не записывается в файлы в файле apk. Временная метка всегда «30 ноября 1979 года».

Вы можете изменить это поведение, добавив эту строку в файл

% Userdir% /. Gradle / gradle.properties (создать, если не существует)

 android.keepTimestampsInApk = true 

См. Выпуск 220039

(Должно быть, в userdir, gradle.properties в проекте build dir, похоже, не работает)

 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; } } } 

Я использую ту же стратегию, что и указатель 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){ } 

В вашем файле build.gradle:

 android { defaultConfig { buildConfigField 'String', 'BUILD_TIME', 'new java.text.SimpleDateFormat("MM.dd.yy HH:mm", java.util.Locale.GERMANY).format(new java.util.Date(' + System.currentTimeMillis() +'L))' } } 

Я знаю, что это действительно старо, но вот как я это сделал, используя 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="(&lt;string name=&quot;application_build_date&quot;&gt;)\d+(&lt;/string&gt;)" replace="&lt;string name=&quot;application_build_date&quot;&gt;${DSTAMP}&lt;/string&gt;" /> </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 выполняется как операция предварительной сборки, и вы всегда будете иметь действительную дату сборки, доступную для вас в R.string.application_build_date.