blob: b6219fd2245fb2b069f68f6bec68136f119e0289 [file] [log] [blame]
/*
* 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();
}
}