57

My application show a TimePickerDialog to set a time. I want that the timePickerDialog show the minutes with an interval of 5 minutes.

This works fine with this code:

private final int TIME_PICKER_INTERVAL=5;
private boolean mIgnoreEvent=false;
…
    public TimePickerDialogs(Context arg0, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
    super(arg0, callBack, hourOfDay, minute, is24HourView);

    formato=Statics.formato;
}

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
    //super.onTimeChanged(arg0, arg1, arg2);

    if (mIgnoreEvent)
        return;
    if (minute%TIME_PICKER_INTERVAL!=0){
        int minuteFloor=minute-(minute%TIME_PICKER_INTERVAL);
        minute=minuteFloor + (minute==minuteFloor+1 ? TIME_PICKER_INTERVAL : 0);
        if (minute==60)
            minute=0;
        mIgnoreEvent=true;
        view.setCurrentMinute(minute);
        mIgnoreEvent=false;
    }
}

Although only minutes can be selected with an interval of five minutes, the timepickerdialog looks like:

hours and minutes

do not know how the minutes also show the range of 5 minutes, as in this picture:

hours and minutes - 5

I have searched but can not find the solution.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Sergio76
  • 3,835
  • 16
  • 61
  • 88
  • 1
    This should help you out: http://stackoverflow.com/questions/16187341/how-do-i-change-the-android-timepicker-minute-intervals – laminatefish Nov 26 '13 at 10:40
  • I already knew that answer, the problem is I'm using a timePickerDialog not have a TimePicker in xml to call (... findViewById) – Sergio76 Nov 26 '13 at 10:52
  • In my opinion, all the answers are too complex for something so simple if you do it in a custom layout xml with numberpickers. i just don't see the reason to use a CustomTimePickerDialog for this approach – CDrosos Oct 01 '20 at 21:46

11 Answers11

131

Use the following the custom class called CustomTimePickerDialog, which I think solve your problem.

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.widget.NumberPicker;
import android.widget.TimePicker;

public class CustomTimePickerDialog extends TimePickerDialog {

    private final static int TIME_PICKER_INTERVAL = 5;
    private TimePicker mTimePicker;
    private final OnTimeSetListener mTimeSetListener;

    public CustomTimePickerDialog(Context context, OnTimeSetListener listener,
            int hourOfDay, int minute, boolean is24HourView) {
        super(context, TimePickerDialog.THEME_HOLO_LIGHT, null, hourOfDay,
                minute / TIME_PICKER_INTERVAL, is24HourView);
        mTimeSetListener = listener;
    }

    @Override
    public void updateTime(int hourOfDay, int minuteOfHour) {
        mTimePicker.setCurrentHour(hourOfDay);
        mTimePicker.setCurrentMinute(minuteOfHour / TIME_PICKER_INTERVAL);
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case BUTTON_POSITIVE:
                if (mTimeSetListener != null) {
                    mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
                            mTimePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
                }
                break;
            case BUTTON_NEGATIVE:
                cancel();
                break;
        }
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field timePickerField = classForid.getField("timePicker");
            mTimePicker = (TimePicker) findViewById(timePickerField.getInt(null));
            Field field = classForid.getField("minute");

            NumberPicker minuteSpinner = (NumberPicker) mTimePicker
                .findViewById(field.getInt(null));
            minuteSpinner.setMinValue(0);
            minuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
                displayedValues.add(String.format("%02d", i));
            }
            minuteSpinner.setDisplayedValues(displayedValues
                    .toArray(new String[displayedValues.size()]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Here is the demonstrating screenshot.

enter image description here

Jeff Lockhart
  • 5,379
  • 4
  • 36
  • 51
Tanmay Mandal
  • 39,873
  • 12
  • 51
  • 48
  • 5
    NumberPicker is not available in pre honeycomb. Suggest me some solution for that – Rajiv yadav Jan 21 '14 at 06:45
  • This worked perfectly for me, thank you! I modified the constructor to take an interval argument and replaced the TIME_PICKER_INTERVAL constant with an interval variable ... but realistically I don't expect to ever need an interval other than 5. – arlomedia Jul 26 '14 at 00:51
  • 2
    I works ok for 15 minutes interval but not on 30 minutes interval – Lee Yi Hong Sep 04 '14 at 08:19
  • 4
    Ok, I manage to solve the 30 minutes interval by adding a onTimeChanged check with last save hours and minutes. If both are different, it will only change the minutes instead of both of them by using `view.setCurrentHour(lastSavedHour)`. I am not sure if this is a good way of doing it... But if there are better solution do feel free to let me know :) – Lee Yi Hong Sep 04 '14 at 08:43
  • I feel the need to clarify @LeeYiHong's comment because I was confused until I implemented it. It works. It just has an annoying bug. For example if you change from 14:00 to :30, the hour goes back to 13. – otgw Oct 16 '14 at 18:27
  • This piece of code doesn't work for the Android 5.0 version of the TimePickerDialog, since it doesn't use the NumberPicker widget for minute selection. – Leon Lucardie Jan 09 '15 at 15:29
  • 1
    @LeonLucardie if you change the super call to be `super(context, TimePickerDialog.THEME_HOLO_LIGHT, callBack, hourOfDay, minute, is24HourView); ` it will work with Android 5.0. Passing the theme makes it use the picker style timeDialog. I've submitted an edit to the answer. – Ryan C Apr 13 '15 at 22:35
  • THANKS!! you are a genius – Stornu2 May 28 '15 at 10:50
  • @LeonLucardie - this pice of code will work fine if you change your CustomTimePicker style in xml from clock to Analog . Although even i'm in need to find out which widget does time picker in clock style uses ? any idea anyone? – Khay Jun 24 '15 at 06:36
  • 1
    Hi - how do I init this class on th UI - do i init a it using a timepicker component eg CustomTimePickerDialog ctp = ...findViewById(R.id.timePicker); ? – Fearghal Sep 04 '15 at 11:53
  • 1
    This code works great, except there's one flaw. If `updateTime()` is called, the minutes are not normalized by dividing by `TIME_PICKER_INTERVAL` before setting the minutes value on the TimePicker. – Jeff Lockhart Sep 11 '16 at 07:32
  • Also, the implementation of `onClick()` has changed in the most recent versions of the API to handle `BUTTON_NEGATIVE`. I'll update the answer to reflect these changes. – Jeff Lockhart Sep 11 '16 at 07:33
  • This code also, inexplicably, doesn't work in 7.0 Nougat. The source code would seem it's mostly unchanged from 6.0.1 Marshmallow in terms of how it handles the `TimePickerMode` in the theme to choose between `TimePickerSpinnerDelegate` and `TimePickerClockDelegate`. But despite the mode being set to "spinner", on API 24 the clock layout is always used. This is an issue with the stock `android.app.TimePickerDialog` though. – Jeff Lockhart Sep 12 '16 at 05:28
  • I created an issue in the Android bug tracker: https://code.google.com/p/android/issues/detail?id=222208 – Jeff Lockhart Sep 12 '16 at 06:18
  • 1
    I've written some workaround code for this issue with Nougat only displaying the clock. I can share if anyone else is experiencing the same problem. – Jeff Lockhart Sep 12 '16 at 19:01
  • can any one help me how to call this class. bcz simply I am calling this constructor and calling method dialog.show(). But getting exception android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? – GS Nayma Nov 24 '16 at 05:50
  • 2
    I feel this will break in the future - Google is clamping down on accessing internals with reflection :( – Daniel Wilson Jan 03 '19 at 14:27
  • 1
    team, I am getting this error, any help please. java.lang.NoSuchFieldException: TimePicker with Android 9 . – user1510006 Jul 05 '19 at 14:14
  • how can we achieve this in Clock Mode? – Riddhi Shah Aug 23 '19 at 08:23
  • beware that when retrieving the resulting time via an OnTimeChangedListener, the resulting "minute" var transmitted is INCORRECT, and will be equal to "minute selected / interval". for example, using an interval of 5 minutes, selecting 6:15 on the UI will yield an OnTimeChangedListener minute var of 3. 6:30 yields minute=6, etc. – darkrider1287 Oct 02 '19 at 02:03
  • @RiddhiShah, this can be done in clock mode. Just omit the attribute TimePickerDialog.THEME_HOLO_LIGHT from the constructor and this makes the timepicker default to clock mode. your new call to super will be something like super(context, null, hourOfDay, minute / TIME_PICKER_INTERVAL, is24HourView); – Oluwasegun Wahaab Feb 12 '20 at 18:49
  • 1
    With compileSdkVersion 30 and Android 11, getting the minuteSpinner in onAttachedToWindow works differently: `mTimePicker = findViewById(Resources.getSystem().getIdentifier("timePicker", "id", "android"))`, then `val minuteSpinner = mTimePicker?.findViewById(Resources.getSystem().getIdentifier("minute", "id", "android"))` (Kotlin) – arlomedia Nov 22 '21 at 19:45
  • i have a problem when i make interval 30 For example if you change from 14:00 to :30, the hour goes back to 13. – ahmed saber Apr 29 '22 at 22:30
18

There is this awesome library MaterialDateTimePicker that creates beautiful styled material timepickers.

You can use one of the following methods to define your interval:

  • setSelectableTimes(Timepoint[] times) You can pass in an array of Timepoints. These values are the only valid selections in the picker. setMinTime(Timepoint time) and setMaxTime(Timepoint time) will further trim this list down.

  • setTimeInterval(int hourInterval, int minuteInterval, int secondInterval) Set the interval for selectable times in the TimePickerDialog. This is a convenience wrapper around setSelectableTimes

Lukas Lechner
  • 7,881
  • 7
  • 40
  • 53
  • does that lib work on a fragment with another views in it, or just as a dialog? – John Sardinha May 04 '16 at 12:39
  • @JohnSardinha, it's a dialog based on the corresponding Android api, but needs an instance of the FragmentManager for it's show() function. – Rajath Dec 29 '16 at 22:56
  • This library works for me. Solved my problem. I can set intervals of 30 minutes, for example. – André Luiz Reis Aug 04 '18 at 17:41
  • 1
    can this lib be customized to use spinner instead of clock? Most solutions I have seen seem to use reflection and they do not work on all android versions. – Dan Mar 21 '19 at 10:48
11
/**
 * Set TimePicker interval by adding a custom minutes list
 *
 * @param timePicker
 */
private void setTimePickerInterval(TimePicker timePicker) {
    try {

        NumberPicker minutePicker = (NumberPicker) timePicker.findViewById(Resources.getSystem().getIdentifier(
                "minute", "id", "android"));
        minutePicker.setMinValue(0);
        minutePicker.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
        List<String> displayedValues = new ArrayList<String>();
        for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
            displayedValues.add(String.format("%02d", i));
        }
        minutePicker.setDisplayedValues(displayedValues.toArray(new String[0]));
    } catch (Exception e) {
        Log.e(TAG, "Exception: " + e);
    }
}
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Tharik ahamed
  • 149
  • 1
  • 5
7

As @anddev84 said, you can do it with your own customized TimePickerDialog.

However, take a look of the source code you can find:

  1. TimePickerDialog is a frame layout, see this file. And it just contains a TimePicker
  2. The TimePicker widget is just a linear layout, see this file. And you can see the minute spinner is a NumberPicker
  3. Refer to the code of NumberPicker, you will find it has a public method setDisplayedValues(String[] displayedValues)

    /**
     * Sets the values to be displayed.
     *
     * @param displayedValues The displayed values.
     */
    public void setDisplayedValues(String[] displayedValues)
    

So, with these information, I suppose you can simply customize your own time picker dialog with limited minutes displayed.

Robin
  • 10,052
  • 6
  • 31
  • 52
2

Struggled with 30 min interval more then hour. Might struggle more if wouldn't see the comment of @Lee. So just post a full code of dialog with 30 min interval:

public class IntervalTimePickerDialog extends TimePickerDialog {
    private static final String TAG = "IntervalPickerDialog";

    private final static int TIME_PICKER_INTERVAL = 30;
    private TimePicker timePicker;
    private final OnTimeSetListener callback;

    private int lastHour = -1;
    private int lastMinute = -1;

    public IntervalTimePickerDialog(Context context, int themeId, OnTimeSetListener callBack,
                                    int hourOfDay, int minute, boolean is24HourView) {
        super(context, themeId, callBack, hourOfDay, minute / TIME_PICKER_INTERVAL,
                is24HourView);
        lastHour = hourOfDay;
        lastMinute = minute;
        this.callback = callBack;
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (callback != null && timePicker != null) {
            timePicker.clearFocus();
            callback.onTimeSet(timePicker, timePicker.getCurrentHour(),
                    timePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
        }
    }

    @Override
    protected void onStop() {
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field timePickerField = classForid.getField("timePicker");
            this.timePicker = (TimePicker) findViewById(timePickerField.getInt(null));
            Field field = classForid.getField("minute");

            NumberPicker mMinuteSpinner = (NumberPicker) timePicker.findViewById(field.getInt(null));
            mMinuteSpinner.setMinValue(0);
            mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
                displayedValues.add(String.format("%02d", i));
            }
            mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
        super.onTimeChanged(view, hourOfDay, minute);
        if (lastHour != hourOfDay && lastMinute != minute) {
            view.setCurrentHour(lastHour);
            lastMinute = minute;
        } else {
            lastHour = hourOfDay;
            lastMinute = minute;
        }
    }
Yev Kanivets
  • 1,780
  • 3
  • 22
  • 38
  • can any one help me how to call this class. bcz simply I am calling this constructor and calling method dialog.show(). But getting exception android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? – GS Nayma Nov 24 '16 at 05:51
  • 2
    @ Yevhenii Kanivets , getting this error for Android 9 , any help please . java.lang.NoSuchFieldException: TimePicker – user1510006 Jul 05 '19 at 18:08
  • 1
    @user1510006 they've just changed the name of field to smth another (don't know which is the new name). This is exactly why reflection is the bad solution. – Yev Kanivets Jul 08 '19 at 07:03
  • @Yevhenii Kanivets , thank you for your reply, so, do we have another solution to keep the spinner UI ? – user1510006 Jul 09 '19 at 16:15
1

Looking at the code for TimePickerDialog, it doesn't appear they give you a way to directly modify the TimePicker before it gets shown to the user and you see the "wrong minutes" are you show in the picture. See TimePickerDialog.java

My recommendation is to create your own TimePickerDialog, basing the design off the Android one. It might sound daunting at first, but

  1. that way you can customize the implementation however you want, including initializing the TimePicker values to display for the minutes (as mentioned here), and also
  2. it actually shouldn't be very hard, the Android TimePickerDialog.java itself is only 160 lines, very manageable.
Community
  • 1
  • 1
anddev84
  • 1,473
  • 12
  • 30
1

I've made an addition to the excellent accepted answer above. The problem with it is that, in at least some versions of Android, when you change the selected time it will replace the dialog title with an incorrect time value. You can't override the offending method, updateTitle(), but you can intercept the call at onTimeChanged() and either not call super or call it with fixed arguments.

I keyed mine off of whether the setTitle() method had been called with a non-zero string ID, but you could just have a getter/setter for the boolean itself or whatever.

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{
    if (autoTitle)
    {
        // Super will call a private updateTitle() method, so lets make
        // sure it has the right minute value.
        super.onTimeChanged(view, hourOfDay, minute * TIME_PICKER_INTERVAL);
    }
    else
    {
        // do nothing
    }
}

@Override
public void setTitle(int id)
{
    super.setTitle(id);
    autoTitle = (id == 0);
}

...

private boolean autoTitle = true;
benkc
  • 3,292
  • 1
  • 28
  • 37
1

Solutions so far don't work with listeners and when setting time programmatically. This solutions is fully usable and stable. Also Kotlin...

import android.content.Context
import android.util.AttributeSet
import android.widget.NumberPicker
import android.widget.TimePicker
import androidx.databinding.BindingAdapter
import java.lang.reflect.Field
import java.util.*


class TimePickerInterval @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TimePicker(context, attrs, defStyleAttr) {

    private var MINUTE_INTERVAL = 1
    override fun getCurrentMinute(): Int {
        return super.getCurrentMinute() * MINUTE_INTERVAL
    }

    override fun getMinute(): Int {
        return super.getMinute() * MINUTE_INTERVAL
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        setUp()
    }

    private fun setUp() {
        try {
            val classForid = Class.forName("com.android.internal.R\$id")
            val field: Field = classForid.getField("minute")
            val mMinuteSpinner = findViewById<NumberPicker>(field.getInt(null))
            mMinuteSpinner.minValue = 0
            mMinuteSpinner.maxValue = 60 / MINUTE_INTERVAL - 1
            val displayedValues: MutableList<String> = ArrayList()
            var i = 0
            while (i < 60) {
                displayedValues.add(String.format("%02d", i))
                i += MINUTE_INTERVAL
            }
            mMinuteSpinner.displayedValues = displayedValues.toTypedArray()

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun setOnTimeChangedListener(onTimeChangedListener: OnTimeChangedListener) {
        super.setOnTimeChangedListener { tp, hour, minute ->
            onTimeChangedListener.onTimeChanged(tp, hour, minute * MINUTE_INTERVAL)
        }
    }

    override fun setMinute(minute: Int) {
        super.setMinute(minute/MINUTE_INTERVAL)
    }

    companion object {
        @JvmStatic
        @BindingAdapter("time_picker_set_minute_interval")
        fun setInterval(view: TimePickerInterval, interval: Int?) {
            interval?.let {
                view.MINUTE_INTERVAL = interval
                view.setUp()
            }
        }
    }
}

In your XML:

        <your.path.TimePickerInterval
            android:id="@+id/tp_to"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:timePickerMode="spinner"
            time_picker_set_minute_interval="@{5}"
 />
0

The answer above works really fine for older version of Android, but it didn't work for me in Android 7 Nougat, basically the date picker is changed completely to use the Clock mode... I kind of merge the code proposed here with https://gist.github.com/jeffdgr8/6bc5f990bf0c13a7334ce385d482af9f, then it set by default the mode of the TimePickerDialog to show the Spinner controls, and it runs the code to show only 15minuts intervals in my case.

The code is posted here https://gist.github.com/smaugho/14dae83f3284fa05455ee0a9e4f13099

public class CustomTimePickerDialog extends TimePickerDialog {

private final static int TIME_PICKER_INTERVAL = 15;
private TimePicker timePicker;
private final OnTimeSetListener callback;

  public HorekoTimePicker(Context context,
        OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
      super(context, callBack, hourOfDay, minute/TIME_PICKER_INTERVAL, is24HourView);
      this.callback = callBack;
    fixSpinner(context, hourOfDay, minute, is24HourView);
  }

/**
 * Workaround for this bug: https://code.google.com/p/android/issues/detail?id=222208
 * In Android 7.0 Nougat, spinner mode for the TimePicker in TimePickerDialog is
 * incorrectly displayed as clock, even when the theme specifies otherwise, such as:
 *
 *  <resources>
 *      <style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
 *          <item name="android:timePickerStyle">@style/Widget.MyApp.TimePicker</item>
 *      </style>
 *
 *      <style name="Widget.MyApp.TimePicker" parent="android:Widget.Material.TimePicker">
 *          <item name="android:timePickerMode">spinner</item>
 *      </style>
 *  </resources>
 *
 * May also pass TimePickerDialog.THEME_HOLO_LIGHT as an argument to the constructor,
 * as this theme has the TimePickerMode set to spinner.
 *
 * Taken from: https://gist.github.com/jeffdgr8/6bc5f990bf0c13a7334ce385d482af9f
 */
private void fixSpinner(Context context, int hourOfDay, int minute, boolean is24HourView) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // android:timePickerMode spinner and clock began in Lollipop
        try {

            // Get the theme's android:timePickerMode
            final int MODE_SPINNER = 1;
            Class<?> styleableClass = Class.forName("com.android.internal.R$styleable");
            Field timePickerStyleableField = styleableClass.getField("TimePicker");
            int[] timePickerStyleable = (int[]) timePickerStyleableField.get(null);
            final TypedArray a = context.obtainStyledAttributes(null, timePickerStyleable, android.R.attr.timePickerStyle, 0);
            Field timePickerModeStyleableField = styleableClass.getField("TimePicker_timePickerMode");
            int timePickerModeStyleable = timePickerModeStyleableField.getInt(null);
            final int mode = a.getInt(timePickerModeStyleable, MODE_SPINNER);
            a.recycle();

            if (mode == MODE_SPINNER) {

                timePicker = (TimePicker) findField(TimePickerDialog.class, TimePicker.class, "mTimePicker").get(this);
                Class<?> delegateClass = Class.forName("android.widget.TimePicker$TimePickerDelegate");
                Field delegateField = findField(TimePicker.class, delegateClass, "mDelegate");
                Object delegate = delegateField.get(timePicker);
                Class<?> spinnerDelegateClass;
                if (Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP) {
                    spinnerDelegateClass = Class.forName("android.widget.TimePickerSpinnerDelegate");
                } else {
                    // TimePickerSpinnerDelegate was initially misnamed TimePickerClockDelegate in API 21!
                    spinnerDelegateClass = Class.forName("android.widget.TimePickerClockDelegate");
                }

                // In 7.0 Nougat for some reason the timePickerMode is ignored and the delegate is TimePickerClockDelegate
                if (delegate.getClass() != spinnerDelegateClass) {
                    delegateField.set(timePicker, null); // throw out the TimePickerClockDelegate!
                    timePicker.removeAllViews(); // remove the TimePickerClockDelegate views
                    Constructor spinnerDelegateConstructor = spinnerDelegateClass.getConstructor(TimePicker.class, Context.class, AttributeSet.class, int.class, int.class);
                    spinnerDelegateConstructor.setAccessible(true);
                    // Instantiate a TimePickerSpinnerDelegate
                    delegate = spinnerDelegateConstructor.newInstance(timePicker, context, null, android.R.attr.timePickerStyle, 0);
                    delegateField.set(timePicker, delegate); // set the TimePicker.mDelegate to the spinner delegate
                    // Set up the TimePicker again, with the TimePickerSpinnerDelegate
                    timePicker.setIs24HourView(is24HourView);
                    timePicker.setCurrentHour(hourOfDay);
                    timePicker.setCurrentMinute(minute);
                    timePicker.setOnTimeChangedListener(this);
                }

                setTimeIntervals();
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

private static Field findField(Class objectClass, Class fieldClass, String expectedName) {
    try {
        Field field = objectClass.getDeclaredField(expectedName);
        field.setAccessible(true);
        return field;
    } catch (NoSuchFieldException e) {} // ignore
    // search for it if it wasn't found under the expected ivar name
    for (Field searchField : objectClass.getDeclaredFields()) {
        if (searchField.getType() == fieldClass) {
            searchField.setAccessible(true);
            return searchField;
        }
    }
    return null;
}

  @Override
protected void onStop() { }

/*
 * Feature #363: (Un)availability times in 15min interval
 * https://abix.webhop.net/redmine/issues/363
 * Solution extracted from
 * http://stackoverflow.com/questions/20214547/show-timepicker-with-minutes-intervals-in-android
 */

@Override
public void onClick(DialogInterface dialog, int which) {
    super.onClick(dialog, which);

    if (callback != null && timePicker != null) {
        timePicker.clearFocus();
        callback.onTimeSet(timePicker, timePicker.getCurrentHour(),
            timePicker.getCurrentMinute()*TIME_PICKER_INTERVAL);
    }
}

private void setTimeIntervals() {
    try {
        Class<?> classForid = Class.forName("com.android.internal.R$id");
        Field field = classForid.getField("minute");

        NumberPicker mMinuteSpinner = (NumberPicker) timePicker.findViewById(field.getInt(null));
        mMinuteSpinner.setMinValue(0);
        mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
        List<String> displayedValues = new ArrayList<String>();
        for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
            displayedValues.add(String.format("%02d", i));
        }
        mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));

    } catch (Exception e) {
        e.printStackTrace();
    }

}

}

Adrián Rivero
  • 161
  • 1
  • 9
-1

If you wont to use the same time picker (not clock) dialog in android 5+ just change the theme. You can change directly in the constructor:

 public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView, int time_interval) {
        super(context, TimePickerDialog.THEME_HOLO_LIGHT, callBack, hourOfDay, minute / time_interval, is24HourView);
        this.TIME_PICKER_INTERVAL = time_interval;
        this.callback = callBack;
    }
gellezzz
  • 1,165
  • 2
  • 12
  • 21
-2

Based on Tanmay Mandal's answer shown above, I have implemented a solution for the TimePicker Widget (not the TimePickerDialog). The trick here is to substitute the original TimePicker element in the layout of the activity for a LinearLayout element, in order to add our custom TimePicker programmatically. See example below:

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.widget.NumberPicker;
import android.widget.TimePicker;

public class MyTimePicker extends TimePicker {

  private static final int TIME_PICKER_INTERVAL = 5;

    public MyTimePicker(Context context) {
        super(context);
    }

    @Override
    public Integer getCurrentMinute() {
        return super.getCurrentMinute()*TIME_PICKER_INTERVAL;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field field = classForid.getField("minute");

            NumberPicker mMinuteSpinner = (NumberPicker) findViewById(field.getInt(null));
            mMinuteSpinner.setMinValue(0);
            mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<String>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL)
                displayedValues.add(String.format("%02d", i));
             mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));     
        } catch (Exception e) {
        e.printStackTrace();
    }

   }

}

And for our activity:

          @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

            LinearLayout ll = (LinearLayout) findViewById(R.id.myLinearLayout);
            ll.removeAllViews();
            MyTimePicker tp = new MyTimePicker(this);
            tp.setIs24HourView(true);
            Calendar cal = Calendar.getInstance(); // Current time
        tp.setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));
            tp.setCurrentMinute(cal.get(Calendar.MINUTE)/5); // Aprox current minute
            ll.addView(tp);

}
MJim
  • 39
  • 5
  • Your TimePicker class have error: NumberPicker mMinuteSpinner = (NumberPicker) mMinuteSpinner.setMinValue(0); – gellezzz Sep 02 '15 at 15:03
  • 1
    Ups, you are right. I forgot a code line. Bug solved now. Thanks! – MJim Sep 02 '15 at 16:02
  • How does this get attached to the UI, do i need a Time picker on in my xml layout? – Fearghal Sep 04 '15 at 11:56
  • You don't need any TimePicker in your xml layout. Just place a LinearLayout element at the position the TimePicker would be and let the Activity populate it as shown above. – MJim Sep 04 '15 at 18:39