2011-09-30 3 views
47
  1. एंड्रॉयड संपर्क पैकेज
  2. में कुछ परिवर्तन करना mm का उपयोग करते हुए समय स्टाम्प निर्माण लिखने के आदेश (बनाने) इस आवेदन

निर्माण करने के लिए और फिर, जब हम इसे हैंडसेट में चलाते समय बिल्ड समय की जांच करने के लिए Contacts.apk में एक बिल्ड टाइम स्टैंप जोड़ना चाहते हैं।कैसे apk में

जैसा कि हम जानते हैं, जब हम mm कमांड चलाते हैं, तो संपर्क पैकेज में Android.mk (मेकफ़ाइल) कहा जाएगा।

और अब, हम date -macro का उपयोग करके बिल्ड समय प्राप्त कर सकते हैं।

लेकिन हम इस बिल्ड टाइम स्टैंप को उस फ़ाइल में कैसे लिख सकते हैं जिसे हमारा एप्लिकेशन रनटाइम पर पढ़ सकता है?

कोई सुझाव?

+0

क्या आप एपीके के लिए बिल्ड टाइमस्टैम्प जोड़ना चाहते हैं? तो यह 'MyApp-201109302359.apk' बन जाता है? – Jimmy

+0

धन्यवाद, मैंने इसे हासिल किया है। MyApp-201109302359.apk के रूप में, लेकिन जैसा कि आप जानते हैं, मुझे इस ऐप को कई बार बनाना होगा। यदि मैं ऐसा करता हूं, तो * My/-। Apk * system/app फ़ोल्डर में एपीके होगा, यह वही नहीं है जो मैं चाहता हूं। – FallingRain

+0

मैं एक फ़ाइल में बिल्ड टाइमस्टैंप लिखना चाहता हूं कि मेरा एपीके पढ़ सकता है और इसे रनटाइम पर गतिविधि में प्रदर्शित कर सकता है। – FallingRain

उत्तर

22

एपीआई संस्करण 9 के बाद से नहीं है:

PackageInfo.lastUpdateTime

समय जहां पर एप्लिकेशन के अंतिम अपडेट।

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

निचले एपीआई संस्करणों पर आपको स्वयं को समय बनाना होगा। उदाहरण के लिए तिथि वाली संपत्ति फ़ोल्डर में फ़ाइल डालना। या मूल कोड में __ DATE__ मैक्रो का उपयोग कर। या दिनांक की जांच कर रहा है जब आपके classesंग.dex बनाया गया था (आपके एपीके में फ़ाइल की तारीख)।

+0

बहुत बहुत धन्यवाद, आपकी सलाह बहुत मूल्यवान है।^_^मैं पैकेजइनfo.lastUpdateTime का उपयोग कर विधि की जांच कर रहा हूं ... – FallingRain

+0

अपने स्वयं के एप्लिकेशन के जावा कोड में अपनी खुद की कक्षाओं की आखिरी संशोधित तिथि कैसे जांचें? और इससे भी बदतर बात यह है कि जब मैं अपने आवेदन का पुनर्निर्माण करता हूं तो मुझे लगता है कि class.dex अद्यतन नहीं होता है। – FallingRain

+0

PackageInfo.lastUpdate मेरे लिए काम नहीं करता है, क्योंकि इसका मान हमेशा "2000-01-01" होता है। – FallingRain

95

विधि जो 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 कार्ड पर स्थापित है, भले ही।

+1

हां, अब मैं इसे संवाद के बारे में भी उपयोग करता हूं :) –

+11

लेकिन – Sash0k

+0

पढ़ने के बाद ** zf.close() ** को कॉल करना न भूलें। मैं "स्ट्रिंग एस" को .apk नाम में कैसे जोड़ सकता हूं? – hariszaman

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

    } 
} 
4

मैं जानता हूँ कि यह वास्तव में पुराना है, लेकिन यहाँ मैं इसे कैसे ग्रहण के भीतर चींटी का उपयोग कर किया है:

परियोजना जड़ में 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 स्ट्रिंग जोड़ें .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> 

सुनिश्चित करें कि चींटी स्क्रिप्ट को प्री-बिल्ड गतिविधि के रूप में निष्पादित किया गया है और आप करेंगे हमेशा R.string.application_build_date के भीतर आपके लिए एक वैध निर्माण तिथि उपलब्ध है।

+0

शायद यह थोड़ा पुराना है, लेकिन बहुत उपयोगी है। क्या आप मेरी मदद कर सकते हैं इसे धीरे-धीरे कैसे करें? –

+0

इसलिए मैंने वास्तव में धीरे-धीरे इस स्क्रिप्ट को धीरे-धीरे लागू किया, लेकिन अंत में मुझे @AleksejsMjaliks समाधान का उपयोग करना चाहिए था। उनका दृष्टिकोण इसे सीधे BuildConfig में एकीकृत करेगा जो कि और भी अच्छा है क्योंकि आपके पास बिल्ड प्रकार, स्वाद, संस्करण टेक्स्ट और संस्करण कोड पहले से ही इसके अंदर टकरा गया है। – ShellDude

+0

लेकिन अपने प्रश्न का उत्तर देने के लिए, इसे अपने प्रोजेक्ट फ़ोल्डर की जड़ में रखें, स्ट्रिंग्स.एक्सएमएल के पथ को अपडेट करें (एंड्रॉइड स्टूडियो में स्थान = "।/Src/main/res/values ​​/ strings.xml" होना चाहिए) और फिर बस अपनी gradle.build फ़ाइल के शीर्ष पर ant.importBuild 'build.xml' का उपयोग करके इसे ग्रेड में आयात करें। फिर आप इसे अपने असेंबली कार्यों में एक निर्भर कार्य के रूप में जोड़ सकते हैं। – ShellDude

5

मैं पॉइंटर नल के समान रणनीति का उपयोग करता हूं सिवाय इसके कि मैं MANIFEST.MF फ़ाइल को प्राथमिकता देता हूं। यह एक पुन: उत्पन्न होता है भले ही एक लेआउट संशोधित किया गया हो (जो class.dex के लिए मामला नहीं है)। मैं जीएमटी में टर्मिनल और सर्वर टीजेड के बीच भ्रम से बचने के लिए तारीख को भी मजबूर करता हूं (यदि तुलना की जानी है, तो पूर्व: नवीनतम संस्करण देखें)।

यह निम्न कोड में परिणाम:

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){ 
    } 
93

आप Gradle उपयोग करते हैं, आप का निर्माण समय पर अद्यतन किया टाइमस्टैम्प के साथ buildConfigField जोड़ सकते हैं।

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

फिर इसे रनटाइम पर पढ़ें।

Date buildDate = new Date(BuildConfig.TIMESTAMP); 
+2

यदि आप Gradle –

+1

का उपयोग कर रहे हैं, तो मुझे यह सबसे अच्छा विकल्प मिल गया है धन्यवाद, मैं कुछ आसान समय के लिए कुछ समय देख रहा था – Seltsam

+3

इसे सबसे अच्छा जवाब माना जाना चाहिए। – pepan

5
अपने 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))' 
    } 
} 
9

एक नए AndroidStudio संस्करणों समाधान "classes.dex फ़ाइल का अंतिम संशोधन समय" के लिए एक संकेत: डिफ़ॉल्ट टाइमस्टैम्प कॉन्फ़िगरेशन में करने के लिए अब और नहीं लिखा है एपीके फ़ाइल में फ़ाइलें। टाइमस्टैम्प हमेशा "30 नवंबर 1 9 7 9" होता है।

आप

% userdir% /। Gradle/gradle.properties दायर करने के लिए इस लाइन जोड़कर इस व्यवहार को बदल सकते (बनाने के मौजूदा नहीं)

android.keepTimestampsInApk = true 

Issue 220039

देखें (मस्ट userdir में हो, प्रोजेक्ट बिल्ड डीआईआर में gradle.properties काम नहीं करते हैं)