mk语法 - ndk-build android.mk




如何将编写时间戳写入apk (6)

  1. 在Android通讯录包中进行一些更改
  2. 使用mm (make)命令来构建这个应用程序

因为我必须一次又一次地更改和构建这个应用程序,所以我想在Contacts.apk添加一个构建时间戳,以检查在手机中运行时的构建时间。

正如我们所知,当我们运行mm命令时,Contacts包中的Android.mk (makefile)将被调用。

现在,我们可以使用date -macro获取构建时间。

但是,我们如何将这个构建时间戳写入到我们的应用程序可以在运行时读取的文件中呢?

有什么建议么?


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

    }
}

我知道这是非常古老的,但这里是我在eclipse中使用ant的方式:

项目根目录下的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中始终有一个有效的生成日期。


检查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);

提示解决方案“classes.dex文件的最后修改时间”一个较新的AndroidStudio版本:在默认配置时间戳不再写入apk文件中的文件。 时间戳总是“1979年11月30日”。

您可以通过将此行添加到文件来更改此行为

%userdir%/。gradle / gradle.properties(如果不存在则创建)

android.keepTimestampsInApk = true

问题220039

(必须在userdir中,项目编译目录中的gradle.properties似乎不工作)


自API版本9以来:

PackageInfo.lastUpdateTime

应用程序上次更新的时间。

try {
    PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
    //TODO use packageInfo.lastUpdateTime
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}

在较低的API版本上,您必须自己编译时间。 例如将一个文件放入包含日期的assets文件夹中。 或者在本地代码中使用__ DATE__宏。 或者在您的classes.dex文件建立的时候检查日期(APK中文件的日期)。





makefile