0

i'm trying to use google's utility functions for naming an image file.

i pulled them from the camera app's Util.java. license:

/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

i'm writing unit tests for them and having trouble with createJpegName

public class Util {
    private static ImageFileNamer sImageFileNamer;
    // don't instantiate this class, dummy
    private Util() {
    }
    public static String createJpegName(long dateTaken) {
    synchronized (sImageFileNamer) {
        return sImageFileNamer.generateName(dateTaken);
    }
    }
    private static class ImageFileNamer {
    private SimpleDateFormat mFormat;
    // The date (in milliseconds) used to generate the last name.
    private long mLastDate;
    // Number of names generated for the same second.
    private int mSameSecondCount;

    @SuppressWarnings("unused")
    public ImageFileNamer(String format) {
        mFormat = new SimpleDateFormat(format, Locale.US);
    }

    public String generateName(long dateTaken) {
        Date date = new Date(dateTaken);
        String result = mFormat.format(date);
        // If the last name was generated for the same second,
        // we append _1, _2, etc to the name.
        if (dateTaken / 1000 == mLastDate / 1000) {
        mSameSecondCount++;
        result += "_" + mSameSecondCount;
        } else {
        mLastDate = dateTaken;
        mSameSecondCount = 0;
        }
        return result;
    }
    }

unit test, for posterity:

public void testCreateJpegName() {
// public static String createJpegName(long dateTaken)
Calendar dateTime = Calendar.getInstance();
dateTime.set(1976, Calendar.SEPTEMBER, 20, 16, 20, 20);
assertEquals(Util.createJpegName(dateTime.getTimeInMillis()),"19760920_162020");
assertEquals(Util.createJpegName(dateTime.getTimeInMillis()),"19760920_162020_1");
}

so.. i'm assuming that sImageFileNamer isn't instantiated, because i never create a Util object, correct?

how is this intended to be used? did i miss something?

the rest of the util functions i can use in-place.

i get an NPE whenever i try to access sImageFileNamer, in the above it occurs at the call to syncronized().

thanks!

er0ck
  • 113
  • 7

2 Answers2

1

You are not initializing sImageFileNamer instance before before using in synchronized block do it as:

 public static String createJpegName(long dateTaken) {
        sImageFileNamer=  new ImageFileNamer(dateTaken);
        synchronized (sImageFileNamer) {
            return sImageFileNamer.generateName(dateTaken);
         }
    }

or both class and generateName method is static so you can access without creating object using class name.

ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
  • thanks for the reply. this compiles and runs, but circumvents the static nature of sImageFileNamer by creating a new one each time createJpegName is called (or it appears to). so the variables inside ImageFileNamer are not retained across calls. – er0ck Jun 06 '14 at 05:57
0

You have to make sure sImageFileNamer is initialized before using it. As it's private, you can only do it from inside Util class. I recommend you to do it from some method or use an static initializer:

public class Util {
    private static ImageFileNamer sImageFileNamer;
    static {
        sImageFileNamer = null; // replace null by whatever you want
    }
    // ... continue you class code
}

As said here, static initializers are called automatically and only once. I think it's what you need.

Community
  • 1
  • 1
Rafael Brasil
  • 232
  • 1
  • 6
  • this works. and the static-ness is retained. thanks! i did: `sImageFileNamer = new ImageFileNamer("yyyyMMdd_HHmmss");` because the constructor in this case takes a string date format ala simpleDateFormat – er0ck Jun 06 '14 at 05:59