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!

1
  • Can you provide the code of the failing unit test? Commented Jun 6, 2014 at 1:45

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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.
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.

1 Comment

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.