/* Updates the empty list view with contextually relevant information that the user can use to determine why they aren't seeing weather. */ private void updateEmptyView() { if (mForecastAdapter.getItemCount() == 0) { TextView tv = (TextView) getView().findViewById(R.id.recyclerview_forecast_empty); if (null != tv) { // if cursor is empty, why? do we have an invalid location int message = R.string.empty_forecast_list; @SunshineSyncAdapter.LocationStatus int location = Utility.getLocationStatus(getActivity()); switch (location) { case SunshineSyncAdapter.LOCATION_STATUS_SERVER_DOWN: message = R.string.empty_forecast_list_server_down; break; case SunshineSyncAdapter.LOCATION_STATUS_SERVER_INVALID: message = R.string.empty_forecast_list_server_error; break; case SunshineSyncAdapter.LOCATION_STATUS_INVALID: message = R.string.empty_forecast_list_invalid_location; break; default: if (!Utility.isNetworkAvailable(getActivity())) { message = R.string.empty_forecast_list_no_network; } } tv.setText(message); } } }
@Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (SunshineSyncAdapter.ACTION_DATA_UPDATED.equals(action)) { String location = Utility.getPreferredLocation(this); Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate( location, System.currentTimeMillis()); Cursor cursor = getContentResolver() .query( weatherForLocationUri, FORECAST_COLUMNS, null, null, WeatherContract.WeatherEntry.COLUMN_DATE + " ASC"); if (cursor.moveToFirst()) { int weatherId = cursor.getInt(cursor.getColumnIndex(WeatherContract.WeatherEntry.COLUMN_WEATHER_ID)); String desc = cursor.getString( cursor.getColumnIndex(WeatherContract.WeatherEntry.COLUMN_SHORT_DESC)); double high = cursor.getDouble(cursor.getColumnIndex(WeatherContract.WeatherEntry.COLUMN_MAX_TEMP)); double low = cursor.getDouble(cursor.getColumnIndex(WeatherContract.WeatherEntry.COLUMN_MIN_TEMP)); handleWatchfaceUpdate(weatherId, desc, high, low); } cursor.close(); } } }
@Override public void onResume() { super.onResume(); if (mLocation != null && !mLocation.equals(Utility.getPreferredLocation(getActivity()))) { getLoaderManager().restartLoader(DETAIL_LOADER, null, this); } }
public static String getFormattedWind(Context context, float windSpeed, float degrees) { int windFormat; if (Utility.isMetric(context)) { windFormat = R.string.format_wind_kmh; } else { windFormat = R.string.format_wind_mph; windSpeed = .621371192237334f * windSpeed; } // From wind direction in degrees, determine compass direction as a string (e.g NW) // You know what's fun, writing really long if/else statements with tons of possible // conditions. Seriously, try it! String direction = "Unknown"; if (degrees >= 337.5 || degrees < 22.5) { direction = "N"; } else if (degrees >= 22.5 && degrees < 67.5) { direction = "NE"; } else if (degrees >= 67.5 && degrees < 112.5) { direction = "E"; } else if (degrees >= 112.5 && degrees < 157.5) { direction = "SE"; } else if (degrees >= 157.5 && degrees < 202.5) { direction = "S"; } else if (degrees >= 202.5 && degrees < 247.5) { direction = "SW"; } else if (degrees >= 247.5 && degrees < 292.5) { direction = "W"; } else if (degrees >= 292.5 && degrees < 337.5) { direction = "NW"; } return String.format(context.getString(windFormat), windSpeed, direction); }
private void sendWeatherData(Cursor weatherData, Context context) { // get high temperature string double high = weatherData.getDouble(COL_WEATHER_MAX_TEMP); String highString = Utility.formatTemperature(context, high); // get low temperature string double low = weatherData.getDouble(COL_WEATHER_MIN_TEMP); String lowString = Utility.formatTemperature(context, low); // get icon asset int weatherId = weatherData.getInt(COL_WEATHER_CONDITION_ID); int defaultImage = Utility.getIconResourceForWeatherCondition(weatherId); Bitmap weatherIcon = BitmapFactory.decodeResource(context.getResources(), defaultImage); Bitmap scaleBitmap = WearUtils.scaleBitmap(weatherIcon, 22, 22); Bitmap greyScaleIcon = WearUtils.toGrayscale(scaleBitmap); // https://developer.android.com/training/wearables/data-layer/assets.html sendWeatherDataItem(greyScaleIcon, highString, lowString); }
@Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder viewHolder = (ViewHolder) view.getTag(); int viewType = getItemViewType(cursor.getPosition()); int weatherId = cursor.getInt(ForecastFragment.COL_WEATHER_CONDITION_ID); int fallbackIconId; switch (viewType) { case VIEW_TYPE_TODAY: { // Get weather icon fallbackIconId = Utility.getArtResourceForWeatherCondition(weatherId); break; } default: { // Get weather icon fallbackIconId = Utility.getIconResourceForWeatherCondition(weatherId); break; } } Glide.with(mContext) .load(Utility.getArtUrlForWeatherCondition(mContext, weatherId)) .error(fallbackIconId) .crossFade() .into(viewHolder.iconView); // Read date from cursor long dateInMillis = cursor.getLong(ForecastFragment.COL_WEATHER_DATE); // Find TextView and set formatted date on it viewHolder.dateView.setText(Utility.getFriendlyDayString(context, dateInMillis)); // Read weather forecast from cursor String description = cursor.getString(ForecastFragment.COL_WEATHER_DESC); // Find TextView and set weather forecast on it viewHolder.descriptionView.setText(description); // For accessibility, add a content description to the icon field viewHolder.iconView.setContentDescription(description); viewHolder.descriptionView.setContentDescription( context.getString(R.string.a11y_forecast, description)); // Read user preference for metric or imperial temperature units boolean isMetric = Utility.isMetric(context); // Read high temperature from cursor String high = Utility.formatTemperature(context, cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP)); viewHolder.highTempView.setText(high); viewHolder.highTempView.setContentDescription(context.getString(R.string.a11y_high_temp, high)); // Read low temperature from cursor String low = Utility.formatTemperature(context, cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP)); viewHolder.lowTempView.setText(low); viewHolder.lowTempView.setContentDescription(context.getString(R.string.a11y_low_temp, low)); }
/** * This method uses existing code from the sunshine app to query for weather data that already * exists and is being displayed to the user's in the mobile app. * * @param context used for retrieving shared perferences * @return Cursor containing data for Today's weather */ private Cursor getWearableWeatherData(Context context) { // Sort order: Ascending, by date. String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATE + " ASC"; String locationSetting = Utility.getPreferredLocation(context); Uri locationUri = WeatherContract.WeatherEntry.buildWearableWeatherLocation( locationSetting, System.currentTimeMillis()); return getContentResolver().query(locationUri, FORECAST_COLUMNS, null, null, sortOrder); }
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (data != null && data.moveToFirst()) { // Read weather condition ID from cursor int weatherId = data.getInt(COL_WEATHER_CONDITION_ID); // Use weather art image mIconView.setImageResource(Utility.getArtResourceForWeatherCondition(weatherId)); // Read date from cursor and update views for day of week and date long date = data.getLong(COL_WEATHER_DATE); String friendlyDateText = Utility.getDayName(getActivity(), date); String dateText = Utility.getFormattedMonthDay(getActivity(), date); mFriendlyDateView.setText(friendlyDateText); mDateView.setText(dateText); // Read description from cursor and update view String description = data.getString(COL_WEATHER_DESC); mDescriptionView.setText(description); // Read high temperature from cursor and update view boolean isMetric = Utility.isMetric(getActivity()); double high = data.getDouble(COL_WEATHER_MAX_TEMP); String highString = Utility.formatTemperature(getActivity(), high); mHighTempView.setText(highString); // Read low temperature from cursor and update view double low = data.getDouble(COL_WEATHER_MIN_TEMP); String lowString = Utility.formatTemperature(getActivity(), low); mLowTempView.setText(lowString); // Read humidity from cursor and update view float humidity = data.getFloat(COL_WEATHER_HUMIDITY); mHumidityView.setText(getActivity().getString(R.string.format_humidity, humidity)); // Read wind speed and direction from cursor and update view float windSpeedStr = data.getFloat(COL_WEATHER_WIND_SPEED); float windDirStr = data.getFloat(COL_WEATHER_DEGREES); mWindView.setText(Utility.getFormattedWind(getActivity(), windSpeedStr, windDirStr)); // Read pressure from cursor and update view float pressure = data.getFloat(COL_WEATHER_PRESSURE); mPressureView.setText(getActivity().getString(R.string.format_pressure, pressure)); // We still need this for the share intent mForecast = String.format("%s - %s - %s/%s", dateText, description, high, low); // If onCreateOptionsMenu has already happened, we need to update the share intent now. if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(createShareForecastIntent()); } } }
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { Log.v(LOG_TAG, "In onLoadFinished"); if (!data.moveToFirst()) { return; } String dateString = Utility.formatDate(data.getString(data.getColumnIndex(WeatherEntry.COLUMN_DATETEXT))); ((TextView) getView().findViewById(R.id.detail_date_textview)).setText(dateString); String weatherDescription = data.getString(data.getColumnIndex(WeatherEntry.COLUMN_SHORT_DESC)); ((TextView) getView().findViewById(R.id.detail_forecast_textview)) .setText(weatherDescription); boolean isMetric = Utility.isMetric(getActivity()); String high = Utility.formatTemperature( data.getDouble(data.getColumnIndex(WeatherEntry.COLUMN_MAX_TEMP)), isMetric); ((TextView) getView().findViewById(R.id.detail_high_textview)).setText(high); String low = Utility.formatTemperature( data.getDouble(data.getColumnIndex(WeatherEntry.COLUMN_MIN_TEMP)), isMetric); ((TextView) getView().findViewById(R.id.detail_low_textview)).setText(low); // We still need this for the share intent mForecast = String.format("%s - %s - %s/%s", dateString, weatherDescription, high, low); Log.v(LOG_TAG, "Forecast String: " + mForecast); // If onCreateOptionsMenu has already happened, we need to update the share intent now. if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(createShareForecastIntent()); } }
/* This is ported from FetchWeatherTask --- but now we go straight from the cursor to the string. */ private String convertCursorRowToUXFormat(Cursor cursor) { int idx_max_temp = ForecastFragment.COL_WEATHER_MAX_TEMP; int idx_min_temp = ForecastFragment.COL_WEATHER_MIN_TEMP; int idx_date = ForecastFragment.COL_WEATHER_DATE; int idx_short_desc = ForecastFragment.COL_WEATHER_DESC; String highAndLow = formatHighLows(cursor.getDouble(idx_max_temp), cursor.getDouble(idx_min_temp)); return Utility.formatDate(cursor.getLong(idx_date)) + " - " + cursor.getString(idx_short_desc) + " - " + highAndLow; }
private void putData() { Log.e("jerem", "putData: "); PutDataMapRequest putDataMapRequest = PutDataMapRequest.create( mContext.getResources().getString(R.string.wearable_data_item_path)); putDataMapRequest .getDataMap() .putDouble( mContext.getResources().getString(R.string.wearable_data_item_high_temp), mWearableHighTemp); putDataMapRequest .getDataMap() .putDouble( mContext.getResources().getString(R.string.wearable_data_item_low_temp), mWearableLowTemp); int artResourceForWeatherCondition = Utility.getArtResourceForWeatherCondition(mWearableWeatherId); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), artResourceForWeatherCondition); Asset asset = createAssetFromBitmap(bitmap); if (asset != null) { putDataMapRequest .getDataMap() .putAsset(mContext.getResources().getString(R.string.wearable_data_item_asset), asset); } PutDataRequest request = putDataMapRequest.asPutDataRequest(); Wearable.DataApi.putDataItem(mGoogleApiClient, request) .setResultCallback( new ResultCallback<DataApi.DataItemResult>() { @Override public void onResult(DataApi.DataItemResult dataItemResult) { if (dataItemResult.getStatus().isSuccess()) { Log.i("SUNSHINE", "Data update successfully sync with the wearable"); } else { Log.i("SUNSHINE", "Syncing with the wearable failed"); } } }); // mGoogleApiClient.disconnect(); }
@Override public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { // This is called when a new Loader needs to be created. This // fragment only uses one loader, so we don't care about checking the id. // To only show current and future dates, filter the query to return weather only for // dates after or including today. // Sort order: Ascending, by date. String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATE + " ASC"; String locationSetting = Utility.getPreferredLocation(getActivity()); Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate( locationSetting, System.currentTimeMillis()); return new CursorLoader( getActivity(), weatherForLocationUri, FORECAST_COLUMNS, null, null, sortOrder); }
@Override protected void onResume() { super.onResume(); String location = Utility.getPreferredLocation(this); // update the location in our second pane using the fragment manager if (location != null && !location.equals(mLocation)) { ForecastFragment ff = (ForecastFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_forecast); if (null != ff) { ff.onLocationChanged(); } DetailFragment df = (DetailFragment) getSupportFragmentManager().findFragmentByTag(DETAILFRAGMENT_TAG); if (null != df) { df.onLocationChanged(location); } mLocation = location; } }
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor data) { if (!data.moveToFirst() || data == null) return; int weatherId = data.getInt(COL_WEATHER_CONDITION_ID); // mIconView.setImageResource(R.drawable.ic_launcher); mIconView.setImageResource(Utility.getArtResourceForWeatherCondition(weatherId)); long date = data.getLong(COL_WEATHER_DATE); String friendlyDateText = Utility.getDayName(getActivity(), date); String dateText = Utility.getFormattedMonthDay(getActivity(), date); mFriendlyDateView.setText(friendlyDateText); mDateView.setText(dateText); String description = data.getString(COL_WEATHER_DESC); mDescriptionView.setText(description); boolean isMetric = Utility.isMetric(getActivity()); double high = data.getDouble(COL_WEATHER_MAX_TEMP); String highString = Utility.formatTemperature(getActivity(), high, isMetric); mHighTempView.setText(highString); double low = data.getDouble(COL_WEATHER_MIN_TEMP); String lowString = Utility.formatTemperature(getActivity(), low, isMetric); mLowTempView.setText(lowString); float humidity = data.getFloat(COL_WEATHER_HUMIDITY); mHumidityView.setText(getActivity().getString(R.string.format_humidity, humidity)); float windSpeedStr = data.getFloat(COL_WEATHER_WIND_SPEED); float windDirStr = data.getFloat(COL_WEATHER_DEGREES); mWindView.setText(Utility.getFormattedWind(getActivity(), windSpeedStr, windDirStr)); float pressure = data.getFloat(COL_WEATHER_PRESSURE); mPressureView.setText(getActivity().getString(R.string.format_pressure, pressure)); mForecast = String.format("%s - %s - %s/%s", dateText, description, high, low); if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(createShareForecastIntent()); } }
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Log.v(LOG_TAG, "In onCreateLoader"); Intent intent = getActivity().getIntent(); if (intent == null || !intent.hasExtra(DATE_KEY)) { return null; } String forecastDate = intent.getStringExtra(DATE_KEY); // Sort order: Ascending, by date. String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATETEXT + " ASC"; mLocation = Utility.getPreferredLocation(getActivity()); Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithDate(mLocation, forecastDate); Log.v(LOG_TAG, weatherForLocationUri.toString()); // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. return new CursorLoader( getActivity(), weatherForLocationUri, FORECAST_COLUMNS, null, null, sortOrder); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLocation = Utility.getPreferredLocation(this); googleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(Wearable.API) .build(); setContentView(R.layout.activity_main); if (findViewById(R.id.weather_detail_container) != null) { // The detail container view will be present only in the large-screen layouts // (res/layout-sw600dp). If this view is present, then the activity should be // in two-pane mode. mTwoPane = true; // In two-pane mode, show the detail view in this activity by // adding or replacing the detail fragment using a // fragment transaction. if (savedInstanceState == null) { getSupportFragmentManager() .beginTransaction() .replace(R.id.weather_detail_container, new DetailFragment(), DETAILFRAGMENT_TAG) .commit(); } } else { mTwoPane = false; getSupportActionBar().setElevation(0f); } ForecastFragment forecastFragment = ((ForecastFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_forecast)); forecastFragment.setUseTodayLayout(!mTwoPane); SunshineSyncAdapter.initializeSyncAdapter(this); }
/** Prepare the weather high/lows for presentation. */ private String formatHighLows(double high, double low) { boolean isMetric = Utility.isMetric(mContext); String highLowStr = Utility.formatTemperature(high, isMetric) + "/" + Utility.formatTemperature(low, isMetric); return highLowStr; }
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { /*Log.v(LOG_TAG, "In onLoadFinished"); if (!data.moveToFirst()) { return; } String date = Utility.formatDate(data.getLong(COL_WEATHER_DATE)); String desc = data.getString(COL_WEATHER_DESC); Boolean ismetric = Utility.isMetric(getActivity()); String max = Utility.formatTemperature(getActivity(), data.getDouble(COL_WEATHER_MAX_TEMP), ismetric); String min = Utility.formatTemperature(getActivity(), data.getDouble(COL_WEATHER_MIN_TEMP), ismetric); mForecast = String.format("%s - %s %s-%s", date, desc, max, min); TextView tv = (TextView) getView().findViewById(R.id.detail_text); tv.setText(mForecast); if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(createShareForecastIntent()); }*/ Log.v(LOG_TAG, "In onLoadFinished"); if (data != null && data.moveToFirst()) { // Read weather condition ID from cursor int weatherId = data.getInt(COL_WEATHER_CONDITION_ID); // Use placeholder Image // mIconView.setImageResource(Utility.getArtResourceForWeatherCondition(weatherId)); Glide.with(this) .load(Utility.getArtUrlForWeatherCondition(getActivity(), weatherId)) .error(Utility.getArtResourceForWeatherCondition(weatherId)) .crossFade() .into(mIconView); // Read date from cursor and update views for day of week and date long date = data.getLong(COL_WEATHER_DATE); String friendlyDateText = Utility.getDayName(getActivity(), date); String dateText = Utility.getFormattedMonthDay(getActivity(), date); mFriendlyDateView.setText(friendlyDateText); mDateView.setText(dateText); // Read description from cursor and update view String description = data.getString(COL_WEATHER_DESC); mDescriptionView.setText(description); // Read high temperature from cursor and update view boolean isMetric = Utility.isMetric(getActivity()); double high = data.getDouble(COL_WEATHER_MAX_TEMP); String highString = Utility.formatTemperature(getActivity(), high, isMetric); mHighTempView.setText(highString); // Read low temperature from cursor and update view double low = data.getDouble(COL_WEATHER_MIN_TEMP); String lowString = Utility.formatTemperature(getActivity(), low, isMetric); mLowTempView.setText(lowString); // Read humidity from cursor and update view float humidity = data.getFloat(COL_WEATHER_HUMIDITY); mHumidityView.setText(getActivity().getString(R.string.format_humidity, humidity)); // Read wind speed and direction from cursor and update view float windSpeedStr = data.getFloat(COL_WEATHER_WIND_SPEED); float windDirStr = data.getFloat(COL_WEATHER_DEGREES); mWindView.setText(Utility.getFormattedWind(getActivity(), windSpeedStr, windDirStr)); // Read pressure from cursor and update view float pressure = data.getFloat(COL_WEATHER_PRESSURE); mPressureView.setText(getActivity().getString(R.string.format_pressure, pressure)); // We still need this for the share intent mForecast = String.format("%s - %s - %s/%s", dateText, description, high, low); // If onCreateOptionsMenu has already happened, we need to update the share intent now. if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(createShareForecastIntent()); } } }