| /* |
| * Copyright (C) 2014 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. |
| */ |
| |
| package com.android.fmradio; |
| |
| import android.content.Context; |
| import android.content.SharedPreferences; |
| import android.content.res.Resources; |
| import android.graphics.Bitmap; |
| import android.os.Environment; |
| import android.os.StatFs; |
| import android.os.storage.StorageManager; |
| import android.preference.PreferenceManager; |
| import android.util.Log; |
| import android.view.View.MeasureSpec; |
| import android.widget.LinearLayout; |
| import android.widget.TextView; |
| |
| import java.text.DecimalFormat; |
| import java.util.Locale; |
| |
| /** |
| * This class provider interface to compute station and frequency, get project |
| * string |
| */ |
| public class FmUtils { |
| private static final String TAG = "FmUtils"; |
| |
| // FM station variables |
| public static final int DEFAULT_STATION = 1000; |
| public static final float DEFAULT_STATION_FLOAT = computeFrequency(DEFAULT_STATION); |
| // maximum station frequency |
| private static final int HIGHEST_STATION = 1080; |
| // minimum station frequency |
| private static final int LOWEST_STATION = 875; |
| // station step |
| private static final int STEP = 1; |
| // convert rate |
| private static final int CONVERT_RATE = 10; |
| |
| // minimum storage space for record (512KB). |
| // Need to check before starting recording and during recording to avoid |
| // recording keeps going but there is no free space in sdcard. |
| public static final long LOW_SPACE_THRESHOLD = 512 * 1024; |
| // Different city may have different RDS information. |
| // We define 100 miles (160934.4m) to distinguish the cities. |
| public static final double LOCATION_DISTANCE_EXCEED = 160934.4; |
| private static final String FM_LOCATION_LATITUDE = "fm_location_latitude"; |
| private static final String FM_LOCATION_LONGITUDE = "fm_location_longitude"; |
| private static final String FM_IS_FIRST_TIME_PLAY = "fm_is_first_time_play"; |
| private static final String FM_IS_SPEAKER_MODE = "fm_is_speaker_mode"; |
| private static final String FM_IS_FIRST_ENTER_STATION_LIST = "fm_is_first_enter_station_list"; |
| // StorageManager For FM record |
| private static StorageManager sStorageManager = null; |
| |
| /** |
| * Whether the frequency is valid. |
| * |
| * @param station The FM station |
| * |
| * @return true if the frequency is in the valid scale, otherwise return |
| * false |
| */ |
| public static boolean isValidStation(int station) { |
| boolean isValid = (station >= LOWEST_STATION && station <= HIGHEST_STATION); |
| return isValid; |
| } |
| |
| /** |
| * Compute increase station frequency |
| * |
| * @param station The station frequency |
| * |
| * @return station The frequency after increased |
| */ |
| public static int computeIncreaseStation(int station) { |
| int result = station + STEP; |
| if (result > HIGHEST_STATION) { |
| result = LOWEST_STATION; |
| } |
| return result; |
| } |
| |
| /** |
| * Compute decrease station frequency |
| * |
| * @param station The station frequency |
| * |
| * @return station The frequency after decreased |
| */ |
| public static int computeDecreaseStation(int station) { |
| int result = station - STEP; |
| if (result < LOWEST_STATION) { |
| result = HIGHEST_STATION; |
| } |
| return result; |
| } |
| |
| /** |
| * Compute station value with given frequency |
| * |
| * @param frequency The station frequency |
| * |
| * @return station The result value |
| */ |
| public static int computeStation(float frequency) { |
| return (int) (frequency * CONVERT_RATE); |
| } |
| |
| /** |
| * Compute frequency value with given station |
| * |
| * @param station The station value |
| * |
| * @return station The frequency |
| */ |
| public static float computeFrequency(int station) { |
| return (float) station / CONVERT_RATE; |
| } |
| |
| /** |
| * According station to get frequency string |
| * |
| * @param station for 100KZ, range 875-1080 |
| * |
| * @return string like 87.5 |
| */ |
| public static String formatStation(int station) { |
| float frequency = (float) station / CONVERT_RATE; |
| DecimalFormat decimalFormat = new DecimalFormat("0.0"); |
| return decimalFormat.format(frequency); |
| } |
| |
| /** |
| * Get the phone storage path |
| * |
| * @return The phone storage path |
| */ |
| public static String getDefaultStoragePath() { |
| return Environment.getExternalStorageDirectory().getPath(); |
| } |
| |
| /** |
| * Get the default storage state |
| * |
| * @return The default storage state |
| */ |
| public static String getDefaultStorageState(Context context) { |
| ensureStorageManager(context); |
| String state = sStorageManager.getVolumeState(getDefaultStoragePath()); |
| return state; |
| } |
| |
| private static void ensureStorageManager(Context context) { |
| if (sStorageManager == null) { |
| sStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); |
| } |
| } |
| |
| /** |
| * Get the FM play list path |
| * |
| * @param context The context |
| * |
| * @return The FM play list path |
| */ |
| public static String getPlaylistPath(Context context) { |
| ensureStorageManager(context); |
| String[] externalStoragePaths = sStorageManager.getVolumePaths(); |
| String path = externalStoragePaths[0] + "/Playlists/"; |
| return path; |
| } |
| |
| /** |
| * Check if has enough space for record |
| * |
| * @param recordingSdcard The recording sdcard path |
| * |
| * @return true if has enough space for record |
| */ |
| public static boolean hasEnoughSpace(String recordingSdcard) { |
| boolean ret = false; |
| try { |
| StatFs fs = new StatFs(recordingSdcard); |
| long blocks = fs.getAvailableBlocks(); |
| long blockSize = fs.getBlockSize(); |
| long spaceLeft = blocks * blockSize; |
| ret = spaceLeft > LOW_SPACE_THRESHOLD ? true : false; |
| } catch (IllegalArgumentException e) { |
| Log.e(TAG, "hasEnoughSpace, sdcard may be unmounted:" + recordingSdcard); |
| } |
| return ret; |
| } |
| |
| /** |
| * Get the latest searched location |
| * @return the list of latitude and longitude |
| */ |
| public static double[] getLastSearchedLocation(Context context) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| |
| String strLatitude = prefs.getString(FM_LOCATION_LATITUDE, "0.0"); |
| String strLongitude = prefs.getString(FM_LOCATION_LONGITUDE, "0.0"); |
| double latitude = Double.valueOf(strLatitude); |
| double longitude = Double.valueOf(strLongitude); |
| return new double[] { latitude, longitude }; |
| } |
| |
| /** |
| * Set the last searched location |
| */ |
| public static void setLastSearchedLocation(Context context, double latitude, double longitude) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| SharedPreferences.Editor editor = prefs.edit(); |
| String strLatitude = Double.valueOf(latitude).toString(); |
| String strLongitude = Double.valueOf(longitude).toString(); |
| editor.putString(FM_LOCATION_LATITUDE, strLatitude); |
| editor.putString(FM_LOCATION_LONGITUDE, strLongitude); |
| editor.commit(); |
| } |
| |
| /** |
| * check it is the first time to use Fm |
| */ |
| public static boolean isFirstTimePlayFm(Context context) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| boolean isFirstTime = prefs.getBoolean(FM_IS_FIRST_TIME_PLAY, true); |
| return isFirstTime; |
| } |
| |
| /** |
| * Called when first time play FM. |
| * @param context The context |
| */ |
| public static void setIsFirstTimePlayFm(Context context) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| SharedPreferences.Editor editor = prefs.edit(); |
| editor.putBoolean(FM_IS_FIRST_TIME_PLAY, false); |
| editor.commit(); |
| } |
| |
| /** |
| * check it is the first time enter into station list page |
| */ |
| public static boolean isFirstEnterStationList(Context context) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| boolean isFirstEnter = prefs.getBoolean(FM_IS_FIRST_ENTER_STATION_LIST, true); |
| if (isFirstEnter) { |
| SharedPreferences.Editor editor = prefs.edit(); |
| editor.putBoolean(FM_IS_FIRST_ENTER_STATION_LIST, false); |
| editor.commit(); |
| } |
| return isFirstEnter; |
| } |
| |
| /** |
| * Create the notification large icon bitmap from layout |
| * @param c The context |
| * @param text The frequency text |
| * @return The large icon bitmap with frequency text |
| */ |
| public static Bitmap createNotificationLargeIcon(Context c, String text) { |
| Resources res = c.getResources(); |
| int width = (int) res.getDimension(android.R.dimen.notification_large_icon_width); |
| int height = (int) res.getDimension(android.R.dimen.notification_large_icon_height); |
| LinearLayout iconLayout = new LinearLayout(c); |
| iconLayout.setOrientation(LinearLayout.VERTICAL); |
| iconLayout.setBackgroundColor(c.getResources().getColor(R.color.theme_primary_color)); |
| iconLayout.setDrawingCacheEnabled(true); |
| iconLayout.layout(0, 0, width, height); |
| TextView iconText = new TextView(c); |
| iconText.setTextSize(24.0f); |
| iconText.setTextColor(res.getColor(R.color.theme_title_color)); |
| iconText.setText(text); |
| iconText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), |
| MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); |
| int left = (int) ((width - iconText.getMeasuredWidth()) * 0.5); |
| int top = (int) ((height - iconText.getMeasuredHeight()) * 0.5); |
| iconText.layout(left, top, iconText.getMeasuredWidth() + left, |
| iconText.getMeasuredHeight() + top); |
| iconLayout.addView(iconText); |
| iconLayout.layout(0, 0, width, height); |
| |
| iconLayout.buildDrawingCache(); |
| Bitmap largeIcon = Bitmap.createBitmap(iconLayout.getDrawingCache()); |
| iconLayout.destroyDrawingCache(); |
| return largeIcon; |
| } |
| |
| /** |
| * Get whether speaker mode is in use when audio focus lost. |
| * @param context the Context |
| * @return true for speaker mode, false for non speaker mode |
| */ |
| public static boolean getIsSpeakerModeOnFocusLost(Context context) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| |
| return prefs.getBoolean(FM_IS_SPEAKER_MODE, false); |
| } |
| |
| /** |
| * Set whether speaker mode is in use. |
| * @param context the Context |
| * @param isSpeaker speaker state |
| */ |
| public static void setIsSpeakerModeOnFocusLost(Context context, boolean isSpeaker) { |
| SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
| SharedPreferences.Editor editor = prefs.edit(); |
| editor.putBoolean(FM_IS_SPEAKER_MODE, isSpeaker); |
| editor.commit(); |
| } |
| } |