/*
    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();
      }
    }
  }
Пример #3
0
 @Override
 public void onResume() {
   super.onResume();
   if (mLocation != null && !mLocation.equals(Utility.getPreferredLocation(getActivity()))) {
     getLoaderManager().restartLoader(DETAIL_LOADER, null, this);
   }
 }
Пример #4
0
  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);
  }
Пример #6
0
  @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);
  }
Пример #8
0
  @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());
      }
    }
  }
Пример #9
0
    @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());
      }
    }
Пример #10
0
  /*
     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);
  }
Пример #13
0
 @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;
   }
 }
Пример #14
0
  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());
    }
  }
Пример #15
0
    @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);
    }
Пример #16
0
  @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);
  }
Пример #17
0
 /** 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());
      }
    }
  }