Java tutorial
package com.jbirdvegas.mgerrit.helpers; /* * Copyright (C) 2013 Android Open Kang Project (AOKP) * Author: Jon Stanford (JBirdVegas), 2013 * * 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. */ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import com.android.volley.Cache; import com.android.volley.NetworkResponse; import com.android.volley.toolbox.HttpHeaderParser; import com.nhaarman.listviewanimations.appearance.SingleAnimationAdapter; import com.nhaarman.listviewanimations.appearance.simple.SwingBottomInAnimationAdapter; import com.jbirdvegas.mgerrit.Prefs; import com.jbirdvegas.mgerrit.R; import com.jbirdvegas.mgerrit.objects.FileInfo; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Duration; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Map; import java.util.TimeZone; public class Tools { private static final String GERRIT_DATETIME_FORMAT = "yyyy-MM-dd hh:mm:ss.SSS"; private static final String HUMAN_READABLE_DATETIME_FORMAT = "MMMM dd, yyyy '%s' hh:mm:ss aa"; private static final String HUMAN_READABLE_DATE_FORMAT = "MMMM dd, yyyy"; private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat .forPattern("yyyy-MM-dd HH:mm:ss.SSS").withLocale(Locale.US); public static String stackTraceToString(Throwable e) { StringBuilder sb = new StringBuilder(0); sb.append(e.getLocalizedMessage()).append("\n\n"); for (StackTraceElement element : e.getStackTrace()) { sb.append("-- ").append(element.toString()).append('\n'); } return sb.toString(); } /** * Enables or disables listview animations. This simply toggles the * adapter, initialising a new adapter if necessary. * @param enable Whether to enable animations on the listview * @return The outer-most adapter that was applied to the list view. * a non-null instance of animAdapter if enable, defaultAdapter otherwise. */ public static BaseAdapter toggleAnimations(boolean enable, ListView lv, SingleAnimationAdapter animAdapter, BaseAdapter defaultAdapter) { if (enable) { if (animAdapter == null) { animAdapter = new SwingBottomInAnimationAdapter(defaultAdapter); animAdapter.setAbsListView(lv); } lv.setAdapter(animAdapter); return animAdapter; } else if (defaultAdapter != null) { lv.setAdapter(defaultAdapter); return defaultAdapter; } else return null; } /** * Queries the active network and determine if it has Internet connectivity. * @param context Application or activity context * @return Whether we are connected to the internet, regardless of the network type */ public static boolean isConnected(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); } /** * PrettyPrint the Gerrit provided timestamp * format into a more human readable format * * I have no clue what the ten zeros after the seconds are good for as * the exact same ten zeros are in all databases regardless of the stamp's * time or timezone... it comes from Google so we just handle oddities downstream :( * from "2013-06-09 19:47:40.000" * to Jun 09, 2013 07:47 40ms PM * * @return String representation of the date * example: Jun 09, 2013 07:47 40ms PM */ @SuppressWarnings("SimpleDateFormatWithoutLocale") public static String prettyPrintDate(Context context, String date, TimeZone serverTimeZone, TimeZone localTimeZone) { try { SimpleDateFormat currentDateFormat = new SimpleDateFormat(GERRIT_DATETIME_FORMAT, Locale.US); DateFormat humanDateFormat = new SimpleDateFormat( String.format(HUMAN_READABLE_DATETIME_FORMAT, context.getString(R.string.at)), Locale.getDefault()); // location of server currentDateFormat.setTimeZone(serverTimeZone); // local location humanDateFormat.setTimeZone(localTimeZone); return humanDateFormat.format(currentDateFormat.parse(date)); } catch (ParseException e) { e.printStackTrace(); return date; } } public static String prettyPrintDate(Date date) { DateFormat humanDateFormat = new SimpleDateFormat(HUMAN_READABLE_DATE_FORMAT, Locale.getDefault()); return humanDateFormat.format(date); } public static void colorPath(Resources r, TextView view, String statusText, boolean usingLightTheme) { FileInfo.Status status = FileInfo.Status.getValue(statusText); int green = r.getColor(R.color.text_green); int red = r.getColor(R.color.text_red); if (status == FileInfo.Status.ADDED) { view.setTextColor(green); } else if (status == FileInfo.Status.DELETED) { view.setTextColor(red); } else { // Need to determine from the current theme what the default color is and set it back if (usingLightTheme) { view.setTextColor(r.getColor(R.color.text_light)); } else { view.setTextColor(r.getColor(R.color.text_dark)); } } } /** * @param filePath A path to a file * @return The short file name from a full file path */ public static String getFileName(String filePath) { // Remove the path from the filename int idx = filePath.lastIndexOf("/"); return idx >= 0 ? filePath.substring(idx + 1) : filePath; } public static String getWebAddress(Context context, int commitNumber) { return String.format("%s#/c/%d/", Prefs.getCurrentGerrit(context), commitNumber); } public static Intent createShareIntent(Context context, String changeid, int changeNumber) { String webAddress = Tools.getWebAddress(context, changeNumber); return createShareIntent(context, changeid, webAddress); } public static Intent createShareIntent(Context context, String changeid, String webAddress) { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); intent.putExtra(Intent.EXTRA_SUBJECT, String.format(context.getResources().getString(R.string.commit_shared_from_mgerrit), changeid)); intent.putExtra(Intent.EXTRA_TEXT, webAddress + " #mGerrit"); return intent; } public static String getFileExtention(String filename) { int start = filename.lastIndexOf("."); return filename.substring(++start); } public static boolean isImage(String filePath) { String fileExtention = getFileExtention(filePath); return fileExtention.equals("png") || fileExtention.equals("jpg"); } public static String getRevisionUrl(Context context, Integer changeNumber, Integer patchSetNumber) { String ps; if (patchSetNumber == null || patchSetNumber < 1) ps = "current"; else ps = String.valueOf(patchSetNumber); return String.format("%schanges/%d/revisions/%s/patch?zip", Prefs.getCurrentGerrit(context), changeNumber, ps); } /** * Extracts a {@link com.android.volley.Cache.Entry} from a {@link com.android.volley.NetworkResponse}. * Cache-control headers are ignored. * @param response The network response to parse headers from * @return a cache entry for the given response, or null if the response is not cacheable. * @link http://stackoverflow.com/questions/16781244/android-volley-jsonobjectrequest-caching */ public static Cache.Entry parseIgnoreCacheHeaders(NetworkResponse response, long cacheRefreshTime, long cacheExpiresTime) { long now = System.currentTimeMillis(); Map<String, String> headers = response.headers; long serverDate = 0; String headerValue; headerValue = headers.get("Date"); if (headerValue != null) { serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue); } final long softExpire = now + cacheRefreshTime; final long ttl = now + cacheExpiresTime; Cache.Entry entry = new Cache.Entry(); entry.data = response.data; entry.etag = null; // Not worried about etag entry.softTtl = softExpire; entry.ttl = ttl; entry.serverDate = serverDate; entry.responseHeaders = headers; return entry; } public static DateTime parseDate(String dateStr, TimeZone serverTimeZone, TimeZone localTimeZone) { try { DateTime d = DATE_TIME_FORMATTER.withZone(DateTimeZone.forTimeZone(serverTimeZone)) .parseDateTime(dateStr); return d.withZone(DateTimeZone.forTimeZone(localTimeZone)).withMillisOfDay(0); } catch (IllegalArgumentException e) { return new DateTime(0); } } }