Java tutorial
/* * VoIP.ms SMS * Copyright (C) 2015 Michael Kourlas and other contributors * * 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. */ package net.kourlas.voipms_sms; import android.annotation.TargetApi; import android.content.Context; import android.content.DialogInterface; import android.database.Cursor; import android.graphics.*; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Build; import android.provider.ContactsContract; import android.support.v7.app.AlertDialog; import android.view.View; import android.view.ViewOutlineProvider; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; /** * Contains various common utility methods. */ public class Utils { /** * Gets the name of a contact from the Android contacts provider, given a phone number. * * @param applicationContext The application context. * @param phoneNumber The phone number of the contact. * @return the name of the contact. */ public static String getContactName(Context applicationContext, String phoneNumber) { Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)); Cursor cursor = applicationContext.getContentResolver().query(uri, new String[] { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME }, null, null, null); if (cursor.moveToFirst()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)); cursor.close(); return name; } else { cursor.close(); return null; } } /** * Gets a URI pointing to a contact's photo, given a phone number. * * @param applicationContext The application context. * @param phoneNumber The phone number of the contact. * @return a URI pointing to the contact's photo. */ public static String getContactPhotoUri(Context applicationContext, String phoneNumber) { Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)); return getContactPhotoUri(applicationContext, uri); } /** * Gets a URI pointing to a contact's photo, given the URI for that contact. * * @param applicationContext The application context. * @param uri The URI of the contact. * @return a URI pointing to the contact's photo. */ public static String getContactPhotoUri(Context applicationContext, Uri uri) { Cursor cursor = applicationContext.getContentResolver().query(uri, new String[] { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI }, null, null, null); if (cursor.moveToFirst()) { String photoUri = cursor .getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)); cursor.close(); return photoUri; } else { cursor.close(); return null; } } /** * Formats a date for display in the application. * * @param applicationContext The application context. * @param date The date to format. * @param hideTime Omits the time in the formatted date if true. * @return the formatted date. */ public static String getFormattedDate(Context applicationContext, Date date, boolean hideTime) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); Calendar oneMinuteAgo = Calendar.getInstance(); oneMinuteAgo.add(Calendar.MINUTE, -1); if (oneMinuteAgo.getTime().before(date)) { // Last minute: X seconds ago long seconds = (Calendar.getInstance().getTime().getTime() - calendar.getTime().getTime()) / 1000; if (seconds < 10) { return applicationContext.getString(R.string.utils_date_just_now); } else { return seconds + " " + applicationContext.getString(R.string.utils_date_seconds_ago); } } Calendar oneHourAgo = Calendar.getInstance(); oneHourAgo.add(Calendar.HOUR_OF_DAY, -1); if (oneHourAgo.getTime().before(date)) { // Last hour: X minutes ago long minutes = (Calendar.getInstance().getTime().getTime() - calendar.getTime().getTime()) / (1000 * 60); if (minutes == 1) { return applicationContext.getString(R.string.utils_date_one_minute_ago); } else { return minutes + " " + applicationContext.getString(R.string.utils_date_minutes_ago); } } if (compareDateWithoutTime(Calendar.getInstance(), calendar) == 0) { // Today: h:mm a DateFormat format = new SimpleDateFormat("h:mm a", Locale.getDefault()); return format.format(date); } if (Calendar.getInstance().get(Calendar.WEEK_OF_YEAR) == calendar.get(Calendar.WEEK_OF_YEAR) && Calendar.getInstance().get(Calendar.YEAR) == calendar.get(Calendar.YEAR)) { if (hideTime) { // This week: EEE DateFormat format = new SimpleDateFormat("EEE", Locale.getDefault()); return format.format(date); } else { // This week: EEE h:mm a DateFormat format = new SimpleDateFormat("EEE h:mm a", Locale.getDefault()); return format.format(date); } } if (Calendar.getInstance().get(Calendar.YEAR) == calendar.get(Calendar.YEAR)) { if (hideTime) { // This year: MMM d DateFormat format = new SimpleDateFormat("MMM d", Locale.getDefault()); return format.format(date); } else { // This year: MMM d h:mm a DateFormat format = new SimpleDateFormat("MMM d, h:mm a", Locale.getDefault()); return format.format(date); } } if (hideTime) { // Any: MMM d, yyyy DateFormat format = new SimpleDateFormat("MMM d, yyyy", Locale.getDefault()); return format.format(date); } else { // Any: MMM d, yyyy h:mm a DateFormat format = new SimpleDateFormat("MMM d, yyyy, h:mm a", Locale.getDefault()); return format.format(date); } } /** * Returns true if two dates are equivalent (excluding times). * * @param c1 The first date to compare. * @param c2 The second date to compare. * @return true if the two dates are equivalent (excluding times). */ private static int compareDateWithoutTime(Calendar c1, Calendar c2) { if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR); if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH); return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH); } /** * Returns a phone number for display in the application. * * @param phoneNumber The phone number to format. * @return The formatted phone number. */ public static String getFormattedPhoneNumber(String phoneNumber) { if (phoneNumber.length() == 10) { MessageFormat phoneNumberFormat = new MessageFormat("({0}) {1}-{2}"); String[] phoneNumberArray = new String[] { phoneNumber.substring(0, 3), phoneNumber.substring(3, 6), phoneNumber.substring(6) }; phoneNumber = phoneNumberFormat.format(phoneNumberArray); } else if (phoneNumber.length() == 11 && phoneNumber.charAt(0) == '1') { MessageFormat phoneNumberFormat = new MessageFormat("({0}) {1}-{2}"); String[] phoneNumberArray = new String[] { phoneNumber.substring(1, 4), phoneNumber.substring(4, 7), phoneNumber.substring(7) }; phoneNumber = phoneNumberFormat.format(phoneNumberArray); } return phoneNumber; } /** * Retrieves a JSON object from the specified URL. * <p/> * Note that this is a blocking method; it should not be called from the URI thread. * * @param urlString The URL to retrieve the JSON from. * @return The JSON object at the specified URL. * @throws IOException if a connection to the server could not be established. * @throws JSONException if the server did not return valid JSON. */ public static JSONObject getJson(String urlString) throws IOException, JSONException { URL url = new URL(urlString); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setReadTimeout(10000); connection.setConnectTimeout(15000); connection.setRequestMethod("GET"); connection.setDoInput(true); connection.connect(); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); StringBuilder data = new StringBuilder(); String newLine = System.getProperty("line.separator"); String line; while ((line = reader.readLine()) != null) { data.append(line); data.append(newLine); } reader.close(); return new JSONObject(data.toString()); } /** * Checks if the Internet connection is available. * * @param applicationContext The application context. * @return true if the Internet connection is available, false otherwise. */ public static boolean isNetworkConnectionAvailable(Context applicationContext) { ConnectivityManager connMgr = (ConnectivityManager) applicationContext .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } /** * Applies a circular mask to a view. * <p/> * Note that this method only works on Lollipop and above; it will silently fail on older versions. * * @param view The view to apply the mask to. */ public static void applyCircularMask(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { view.setOutlineProvider(new ViewOutlineProvider() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void getOutline(View view, Outline outline) { outline.setOval(0, 0, view.getWidth(), view.getHeight()); } }); view.setClipToOutline(true); } } /** * Applies a circular mask to a bitmap. * * @param bitmap The bitmap to apply the mask to. */ public static Bitmap applyCircularMask(Bitmap bitmap) { final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); canvas.drawARGB(0, 0, 0, 0); canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint); paint.setAntiAlias(true); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } /** * Applies a rectangular rounded corners mask to a view. * <p/> * Note that this method only works on Lollipop and above; it will silently fail on older versions. * * @param view The view to apply the mask to. */ public static void applyRoundedCornersMask(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { view.setOutlineProvider(new ViewOutlineProvider() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void getOutline(View view, Outline outline) { outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 15); } }); view.setClipToOutline(true); } } /** * Shows a standard information dialog to the user. * * @param context The source context. * @param text The text of the dialog. */ public static void showInfoDialog(Context context, String text) { showAlertDialog(context, null, text, context.getString(R.string.ok), null, null, null); } /** * Shows an alert dialog to the user. * * @param context The source context. * @param title The title of the dialog. * @param text The text of the dialog. * @param positiveButtonText The text of the positive button of the dialog. * @param positiveButtonAction The action to be taken when the positive button is clicked. * @param negativeButtonText The text of the negative button of the dialog. * @param negativeButtonAction The action to be taken when the negative button is clicked. */ public static void showAlertDialog(Context context, String title, String text, String positiveButtonText, DialogInterface.OnClickListener positiveButtonAction, String negativeButtonText, DialogInterface.OnClickListener negativeButtonAction) { AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.DialogTheme); builder.setMessage(text); builder.setMessage(title); builder.setPositiveButton(positiveButtonText, positiveButtonAction); builder.setNegativeButton(negativeButtonText, negativeButtonAction); builder.setCancelable(false); builder.show(); } }