diff options
Diffstat (limited to 'app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider')
20 files changed, 1220 insertions, 0 deletions
diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/DebugActivity.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/DebugActivity.java new file mode 100644 index 0000000..d4be2bd --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/DebugActivity.java @@ -0,0 +1,237 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import android.content.Context; +import android.location.Criteria; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; +import android.os.Looper; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.ConverterUtils; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.Feature; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.WundergroundServiceManager; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.CurrentObservationResponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.DisplayLocationResponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.ForecastResponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.WundergroundReponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.forecast.SimpleForecastResponse; + +import java.util.ArrayList; + +import javax.inject.Inject; + +import cyanogenmod.providers.WeatherContract; +import cyanogenmod.weather.CMWeatherManager; +import cyanogenmod.weather.WeatherInfo; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class DebugActivity extends WUBaseActivity implements + CMWeatherManager.WeatherServiceProviderChangeListener, + CMWeatherManager.WeatherUpdateRequestListener, + LocationListener { + + private static final String TAG = DebugActivity.class.getSimpleName(); + + @Inject + WundergroundServiceManager mWundergroundServiceManager; + + private CMWeatherManager mWeatherManager; + private LocationManager mLocationManager; + + private boolean mDirectRequest = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + mWeatherManager = CMWeatherManager.getInstance(this); + mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + mWeatherManager.registerWeatherServiceProviderChangeListener(this); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + public void requestWeatherInfo(View v) { + mDirectRequest = false; + requestWeatherInfo(); + } + + public void requestWeatherInfoDirectly(View v) { + mDirectRequest = true; + requestWeatherInfo(); + } + + private void requestWeatherInfo() { + Log.d(TAG, "Requesting weather!"); + Criteria criteria = new Criteria(); + criteria.setAccuracy(Criteria.ACCURACY_FINE); + mLocationManager.requestSingleUpdate(criteria, this, Looper.getMainLooper()); + } + + @Override + public void onWeatherServiceProviderChanged(String s) { + + } + + @Override + public void onWeatherRequestCompleted(int i, WeatherInfo weatherInfo) { + switch (i) { + case CMWeatherManager.WEATHER_REQUEST_COMPLETED: + Log.d(TAG, "Weather request completed: " + weatherInfo.toString()); + break; + case CMWeatherManager.WEATHER_REQUEST_FAILED: + Log.d(TAG, "Weather request failed!"); + break; + case CMWeatherManager.WEATHER_REQUEST_ALREADY_IN_PROGRESS: + Log.d(TAG, "Weather request already in progress"); + break; + case CMWeatherManager.WEATHER_REQUEST_SUBMITTED_TOO_SOON: + Log.d(TAG, "Weather request submitted too soon"); + break; + } + } + + @Override + public void onLocationChanged(Location location) { + if (mDirectRequest) { + Call<WundergroundReponse> wundergroundCall = + mWundergroundServiceManager.query(location.getLatitude(), + location.getLongitude(), Feature.conditions, Feature.forecast); + + wundergroundCall.enqueue(new Callback<WundergroundReponse>() { + @Override + public void onResponse(Call<WundergroundReponse> call, Response<WundergroundReponse> response) { + if (response.isSuccessful()) { + Log.d(TAG, "Received response:\n" + response.body().toString()); + WundergroundReponse wundergroundReponse = response.body(); + + if (wundergroundReponse == null) { + Log.d(TAG, "Null wu reponse, return"); + return; + } + + CurrentObservationResponse currentObservationResponse = + wundergroundReponse.getCurrentObservation(); + + if (currentObservationResponse == null) { + Log.d(TAG, "Null co reponse, return"); + return; + } + + WeatherInfo.Builder weatherInfoBuilder = + new WeatherInfo.Builder(System.currentTimeMillis()); + + weatherInfoBuilder.setTemperature(currentObservationResponse.getTempF() + .floatValue(), + WeatherContract.WeatherColumns.TempUnit.FAHRENHEIT); + + weatherInfoBuilder.setWeatherCondition( + WeatherContract.WeatherColumns.WeatherCode.CLOUDY); + + DisplayLocationResponse displayLocationResponse = + currentObservationResponse.getDisplayLocation(); + + if (displayLocationResponse == null) { + Log.d(TAG, "Null dl reponse, return"); + return; + } + + weatherInfoBuilder.setCity(displayLocationResponse.getCity(), + displayLocationResponse.getCity()); + + ForecastResponse forecastResponse = + wundergroundReponse.getForecast(); + + if (forecastResponse == null) { + Log.d(TAG, "Null fc reponse, return"); + return; + } + + SimpleForecastResponse simpleForecastResponse = + forecastResponse.getSimpleForecast(); + + if (simpleForecastResponse == null) { + Log.d(TAG, "Null sf reponse, return"); + return; + } + + ArrayList<WeatherInfo.DayForecast> dayForecasts = + ConverterUtils.convertSimpleFCToDayForcast( + simpleForecastResponse.getForecastDay()); + weatherInfoBuilder.setForecast(dayForecasts); + + Log.d(TAG, "Weather info " + weatherInfoBuilder.build().toString()); + } else { + Log.d(TAG, "Response " + response.toString()); + } + } + + @Override + public void onFailure(Call<WundergroundReponse> call, Throwable t) { + Log.d(TAG, "Failure " + t.toString()); + } + }); + } else { + mWeatherManager.requestWeatherUpdate(location, this); + } + } + + @Override + public void onStatusChanged(String s, int i, Bundle bundle) { + + } + + @Override + public void onProviderEnabled(String s) { + + } + + @Override + public void onProviderDisabled(String s) { + + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUBaseActivity.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUBaseActivity.java new file mode 100644 index 0000000..2ac412e --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUBaseActivity.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import android.app.Activity; +import android.os.Bundle; + +public class WUBaseActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + WundergroundCMApplication.get(this).inject(this); + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUBasePreferenceActivity.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUBasePreferenceActivity.java new file mode 100644 index 0000000..31fdacc --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUBasePreferenceActivity.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import android.os.Bundle; +import android.preference.PreferenceActivity; + +public class WUBasePreferenceActivity extends PreferenceActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + WundergroundCMApplication.get(this).inject(this); + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUSettingsPreferenceFragment.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUSettingsPreferenceFragment.java new file mode 100644 index 0000000..b6c855a --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WUSettingsPreferenceFragment.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import android.os.Bundle; +import android.preference.PreferenceFragment; + +public class WUSettingsPreferenceFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //TODO: Implement + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WeakReferenceHandler.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WeakReferenceHandler.java new file mode 100644 index 0000000..d65a7c5 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WeakReferenceHandler.java @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import android.os.Handler; +import android.os.Message; + +import java.lang.ref.WeakReference; + +public abstract class WeakReferenceHandler<T> extends Handler { + private WeakReference<T> mReference; + + public WeakReferenceHandler(T reference) { + mReference = new WeakReference<T>(reference); + } + + @Override + public void handleMessage(Message msg) { + T reference = mReference.get(); + if (reference == null) + return; + handleMessage(reference, msg); + } + + protected abstract void handleMessage(T reference, Message msg); +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundCMApplication.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundCMApplication.java new file mode 100644 index 0000000..7de4717 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundCMApplication.java @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import android.app.Application; +import android.content.Context; + +import dagger.ObjectGraph; + +public class WundergroundCMApplication extends Application { + private ObjectGraph mObjectGraph; + + @Override + public void onCreate() { + super.onCreate(); + mObjectGraph = ObjectGraph.create(new WundergroundModule(this)); + } + + public static WundergroundCMApplication get(Context context) { + return (WundergroundCMApplication) context.getApplicationContext(); + } + + public final void inject(Object object) { + mObjectGraph.inject(object); + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundModule.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundModule.java new file mode 100644 index 0000000..c07de64 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundModule.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.WundergroundServiceManager; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module( + injects = { + DebugActivity.class, + WundergroundWeatherProviderService.class + } +) +public class WundergroundModule { + + private static final String API_KEY = "API_KEY"; + private WundergroundCMApplication mWeatherviewApplication; + + public WundergroundModule(WundergroundCMApplication weatherviewApplication) { + mWeatherviewApplication = weatherviewApplication; + } + + @Provides + @Singleton + public WundergroundServiceManager providesWundergroundServiceManager() { + return new WundergroundServiceManager(API_KEY); + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundWeatherProviderService.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundWeatherProviderService.java new file mode 100644 index 0000000..d9351ad --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/WundergroundWeatherProviderService.java @@ -0,0 +1,224 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider; + +import android.content.Context; +import android.location.Criteria; +import android.location.Location; +import android.location.LocationManager; +import android.os.Message; +import android.util.Log; + +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.ConverterUtils; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.Feature; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.WundergroundServiceManager; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.CurrentObservationResponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.DisplayLocationResponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.ForecastResponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.WundergroundReponse; +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.forecast.SimpleForecastResponse; + +import cyanogenmod.providers.WeatherContract; +import cyanogenmod.weather.RequestInfo; +import cyanogenmod.weather.WeatherInfo; +import cyanogenmod.weatherservice.ServiceRequest; +import cyanogenmod.weatherservice.ServiceRequestResult; +import cyanogenmod.weatherservice.WeatherProviderService; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +import java.util.ArrayList; + +import javax.inject.Inject; + +public class WundergroundWeatherProviderService extends WeatherProviderService { + private static final String TAG = WundergroundWeatherProviderService.class.getSimpleName(); + private static final int SERVICE_REQUEST_CANCELLED = -1; + private static final int SERVICE_REQUEST_SUBMITTED = 0; + + @Inject + public WundergroundServiceManager mWundergroundServiceManager; + + @Override + public void onCreate() { + super.onCreate(); + WundergroundCMApplication.get(this).inject(this); + } + + @Override + protected void onRequestSubmitted(final ServiceRequest serviceRequest) { + Log.d(TAG, "Received service request: " + serviceRequest.toString()); + Message request = mHandler.obtainMessage(SERVICE_REQUEST_SUBMITTED, serviceRequest); + request.sendToTarget(); + } + + @Override + protected void onRequestCancelled(ServiceRequest serviceRequest) { + Log.d(TAG, "Received service request cancelled: " + serviceRequest.toString()); + Message request = mHandler.obtainMessage(SERVICE_REQUEST_CANCELLED, serviceRequest); + request.sendToTarget(); + } + + private final NonLeakyMessageHandler mHandler = new NonLeakyMessageHandler(this); + + private static class NonLeakyMessageHandler + extends WeakReferenceHandler<WundergroundWeatherProviderService> { + public NonLeakyMessageHandler(WundergroundWeatherProviderService reference) { + super(reference); + } + + @Override + protected void handleMessage(WundergroundWeatherProviderService reference, + Message inputMessage) { + ServiceRequest serviceRequest = (ServiceRequest)inputMessage.obj; + switch (inputMessage.what) { + case SERVICE_REQUEST_SUBMITTED: + RequestInfo requestInfo = serviceRequest.getRequestInfo(); + switch (requestInfo.getRequestType()) { + case RequestInfo.TYPE_WEATHER_LOCATION_REQ: + reference.processWeatherLocationRequest(serviceRequest); + break; + default: + //Don't support anything else, fail. + serviceRequest.fail(); + break; + } + break; + case SERVICE_REQUEST_CANCELLED: + //TODO; Implement + break; + default: + //Don't support anything else, fail. + if (serviceRequest != null) { + serviceRequest.fail(); + } + } + } + } + + private void processWeatherLocationRequest(final ServiceRequest serviceRequest) { + final RequestInfo requestInfo = serviceRequest.getRequestInfo(); + Log.d(TAG, "Received weather request info: " + requestInfo.toString()); + + Location location = requestInfo.getLocation(); + if (location == null) { + LocationManager locationManager = (LocationManager) + getSystemService(Context.LOCATION_SERVICE); + Criteria criteria = new Criteria(); + criteria.setAccuracy(Criteria.ACCURACY_HIGH); + location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria + , false)); + } + + Call<WundergroundReponse> wundergroundCall = + mWundergroundServiceManager.query(location.getLatitude(), + location.getLongitude(), Feature.conditions, Feature.forecast); + + wundergroundCall.enqueue(new Callback<WundergroundReponse>() { + @Override + public void onResponse(Call<WundergroundReponse> call, Response<WundergroundReponse> response) { + if (response.isSuccessful()) { + Log.d(TAG, "Received response:\n" + response.body().toString()); + + WundergroundReponse wundergroundReponse = response.body(); + + if (wundergroundReponse == null) { + Log.d(TAG, "Null wu reponse, return"); + serviceRequest.fail(); + return; + } + + CurrentObservationResponse currentObservationResponse = + wundergroundReponse.getCurrentObservation(); + + if (currentObservationResponse == null) { + Log.d(TAG, "Null co reponse, return"); + serviceRequest.fail(); + return; + } + + WeatherInfo.Builder weatherInfoBuilder = + new WeatherInfo.Builder(System.currentTimeMillis()); + + weatherInfoBuilder.setTemperature(currentObservationResponse.getTempF() + .floatValue(), + WeatherContract.WeatherColumns.TempUnit.FAHRENHEIT); + + weatherInfoBuilder.setWeatherCondition( + WeatherContract.WeatherColumns.WeatherCode.CLOUDY); + + DisplayLocationResponse displayLocationResponse = + currentObservationResponse.getDisplayLocation(); + + if (displayLocationResponse == null) { + Log.d(TAG, "Null dl reponse, return"); + return; + } + + weatherInfoBuilder.setCity(displayLocationResponse.getCity(), + displayLocationResponse.getCity()); + + ForecastResponse forecastResponse = + wundergroundReponse.getForecast(); + + if (forecastResponse == null) { + Log.d(TAG, "Null fc reponse, return"); + serviceRequest.fail(); + return; + } + + SimpleForecastResponse simpleForecastResponse = + forecastResponse.getSimpleForecast(); + + if (simpleForecastResponse == null) { + Log.d(TAG, "Null sf reponse, return"); + serviceRequest.fail(); + return; + } + + ArrayList<WeatherInfo.DayForecast> dayForecasts = + ConverterUtils.convertSimpleFCToDayForcast( + simpleForecastResponse.getForecastDay()); + weatherInfoBuilder.setForecast(dayForecasts); + + ServiceRequestResult serviceRequestResult = + new ServiceRequestResult.Builder() + .setWeatherInfo(weatherInfoBuilder.build()).build(); + serviceRequest.complete(serviceRequestResult); + } else { + Log.d(TAG, "Response " + response.toString()); + } + } + + @Override + public void onFailure(Call<WundergroundReponse> call, Throwable t) { + Log.d(TAG, "Failure " + t.toString()); + serviceRequest.fail(); + } + }); + } + + //TODO IMPLEMENT + private void processCityNameLookupRequest(final ServiceRequest serviceRequest) { + final RequestInfo requestInfo = serviceRequest.getRequestInfo(); + Log.d(TAG, "Received city lookup request info: " + requestInfo.toString()); + + + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/ConverterUtils.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/ConverterUtils.java new file mode 100644 index 0000000..41ea613 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/ConverterUtils.java @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground; + +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.forecast.ForecastDayResponse; + +import java.util.ArrayList; +import java.util.List; + +import cyanogenmod.providers.WeatherContract; +import cyanogenmod.weather.WeatherInfo; + +public class ConverterUtils { + + private ConverterUtils() { + } + + public static ArrayList<WeatherInfo.DayForecast> convertSimpleFCToDayForcast( + List<ForecastDayResponse> forecastDayResponses) { + ArrayList<WeatherInfo.DayForecast> dayForecasts = new ArrayList<>(); + for (ForecastDayResponse forecastDayResponse : forecastDayResponses) { + WeatherInfo.DayForecast dayForecast = new WeatherInfo.DayForecast.Builder() + .setHigh(forecastDayResponse.getHigh().getFahrenheit()) + .setLow(forecastDayResponse.getLow().getFahrenheit()) + .setWeatherCondition(WeatherContract.WeatherColumns.WeatherCode.SUNNY) + .build(); + dayForecasts.add(dayForecast); + } + return dayForecasts; + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/Feature.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/Feature.java new file mode 100644 index 0000000..d072a09 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/Feature.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground; + +public enum Feature implements FeatureParam { + conditions, + forecast; + + @Override + public String toString() { + return name(); + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/FeatureParam.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/FeatureParam.java new file mode 100644 index 0000000..e8fe214 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/FeatureParam.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground; + +public interface FeatureParam { +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/WundergroundServiceInterface.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/WundergroundServiceInterface.java new file mode 100644 index 0000000..1d544e5 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/WundergroundServiceInterface.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground; + +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.WundergroundReponse; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Path; + +public interface WundergroundServiceInterface { + @GET("{features}/q/{state}/{city}.json") + public Call<WundergroundReponse> query(@Path("state") String state, + @Path("city") String city, @Path(value ="features", + encoded = true) String features); + + @GET("{features}/q/{latitude},{longitude}.json") + public Call<WundergroundReponse> query(@Path("latitude") double latitude, + @Path("longitude") double longitude, @Path(value ="features", + encoded = true) String features); +}
\ No newline at end of file diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/WundergroundServiceManager.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/WundergroundServiceManager.java new file mode 100644 index 0000000..5dbe3f4 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/WundergroundServiceManager.java @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground; + +import android.util.Log; + +import com.google.common.base.Joiner; + +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.WundergroundReponse; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Call; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class WundergroundServiceManager { + private final static String TAG = WundergroundServiceManager.class.getSimpleName(); + private final WundergroundServiceInterface mWundergroundServiceInterface; + + public WundergroundServiceManager(String apiKey) { + Retrofit baseAdapter = buildRestAdapter(apiKey); + mWundergroundServiceInterface = baseAdapter.create(WundergroundServiceInterface.class); + } + + public Call<WundergroundReponse> query(String state, String city, + FeatureParam... features) { + return mWundergroundServiceInterface.query(state, city, + coerceVarArgFeaturesToDelimitedString(features)); + } + + public Call<WundergroundReponse> query(double latitude, double longitude, + FeatureParam... features) { + return mWundergroundServiceInterface.query(latitude, longitude, + coerceVarArgFeaturesToDelimitedString(features)); + } + + private String coerceVarArgFeaturesToDelimitedString(FeatureParam... featureParams) { + return Joiner.on('/').join(featureParams); + } + + private Retrofit buildRestAdapter(String apiKey) { + //TODO: Wrap this in debug flag + //HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); + //interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + //OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); + + return new Retrofit.Builder() + .baseUrl("http://api.wunderground.com/api/" + apiKey + "/") + //.client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + } +} + diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/CurrentObservationResponse.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/CurrentObservationResponse.java new file mode 100644 index 0000000..d496a6c --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/CurrentObservationResponse.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +public class CurrentObservationResponse implements Serializable { + + @SerializedName("display_location") + private DisplayLocationResponse displayLocationResponse; + + private String weather; + + @SerializedName("temperature_string") + private String temperatureString; + + @SerializedName("temp_f") + private Double tempF; + + @SerializedName("temp_c") + private Double tempC; + + @SerializedName("wind_dir") + private String windDir; + + @SerializedName("wind_degrees") + private Double windDegrees; + + @SerializedName("wind_mph") + private Double windMph; + + public DisplayLocationResponse getDisplayLocation() { + return displayLocationResponse; + } + + public void setDisplayLocation(DisplayLocationResponse city) { + this.displayLocationResponse = city; + } + + public String getWeather() { + return weather; + } + + public void setWeather(String weather) { + this.weather = weather; + } + + public String getTemperatureString() { + return temperatureString; + } + + public void setTemperatureString(String temperatureString) { + this.temperatureString = temperatureString; + } + + public Double getTempF() { + return tempF; + } + + public void setTempF(Double tempF) { + this.tempF = tempF; + } + + public Double getTempC() { + return tempC; + } + + public void setTempC(Double tempC) { + this.tempC = tempC; + } + + public String getWindDir() { + return windDir; + } + + public void setWindDir(String windDir) { + this.windDir = windDir; + } + + public Double getWindDegrees() { + return windDegrees; + } + + public void setWindDegrees(Double windDegrees) { + this.windDegrees = windDegrees; + } + + public Double getWindMph() { + return windMph; + } + + public void setWindMph(Double windMph) { + this.windMph = windMph; + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/DisplayLocationResponse.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/DisplayLocationResponse.java new file mode 100644 index 0000000..c0f6372 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/DisplayLocationResponse.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses; + +import java.io.Serializable; + +public class DisplayLocationResponse implements Serializable { + private String city; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/ForecastResponse.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/ForecastResponse.java new file mode 100644 index 0000000..f647575 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/ForecastResponse.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses; + +import com.google.gson.annotations.SerializedName; + +import org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.forecast.SimpleForecastResponse; + +import java.io.Serializable; + +public class ForecastResponse implements Serializable { + @SerializedName("simpleforecast") + private SimpleForecastResponse simpleForecast; + + public SimpleForecastResponse getSimpleForecast() { + return simpleForecast; + } + + public void setSimpleForecastResponse(SimpleForecastResponse simpleForecast) { + this.simpleForecast = simpleForecast; + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/WundergroundReponse.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/WundergroundReponse.java new file mode 100644 index 0000000..40a5587 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/WundergroundReponse.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +public class WundergroundReponse implements Serializable { + @SerializedName("current_observation") + private CurrentObservationResponse currentObservationResponse; + + @SerializedName("forecast") + private ForecastResponse forecastResponse; + + public CurrentObservationResponse getCurrentObservation() { + return currentObservationResponse; + } + + public void setCurrentObservationResponse(CurrentObservationResponse + currentObservationResponse) { + this.currentObservationResponse = currentObservationResponse; + } + + public ForecastResponse getForecast() { + return forecastResponse; + } + + public void setForecastResponse(ForecastResponse forecastResponse) { + this.forecastResponse = forecastResponse; + } + + @Override + public String toString() { + return "WundergroundResponse:\n" + + "Forecast: " + forecastResponse.toString() + "\n" + + "Current Observation: " + currentObservationResponse.toString(); + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/ForecastDayResponse.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/ForecastDayResponse.java new file mode 100644 index 0000000..8aec0f6 --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/ForecastDayResponse.java @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.forecast; + +import java.io.Serializable; + +public class ForecastDayResponse implements Serializable { + private TemperatureForecastResponse high; + private TemperatureForecastResponse low; + + private String conditions; + + public TemperatureForecastResponse getHigh() { + return high; + } + + public void setHigh(TemperatureForecastResponse high) { + this.high = high; + } + + public TemperatureForecastResponse getLow() { + return low; + } + + public void setLow(TemperatureForecastResponse low) { + this.low = low; + } + + public String getConditions() { + return conditions; + } + + public void setConditions(String conditions) { + this.conditions = conditions; + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/SimpleForecastResponse.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/SimpleForecastResponse.java new file mode 100644 index 0000000..dcef37a --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/SimpleForecastResponse.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.forecast; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.List; + +public class SimpleForecastResponse implements Serializable { + @SerializedName("forecastday") + private List<ForecastDayResponse> forecastDay; + + public List<ForecastDayResponse> getForecastDay() { + return forecastDay; + } + + public void setForecastDay(List<ForecastDayResponse> forecastDay) { + this.forecastDay = forecastDay; + } +} diff --git a/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/TemperatureForecastResponse.java b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/TemperatureForecastResponse.java new file mode 100644 index 0000000..3379cfd --- /dev/null +++ b/app/src/main/java/org/cyanogenmod/wundergroundcmweatherprovider/wunderground/responses/forecast/TemperatureForecastResponse.java @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2016 The CyanogenMod 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 org.cyanogenmod.wundergroundcmweatherprovider.wunderground.responses.forecast; + +import java.io.Serializable; + +public class TemperatureForecastResponse implements Serializable { + private int fahrenheit; + private int celsius; + + public int getFahrenheit() { + return fahrenheit; + } + + public void setFahrenheit(int fahrenheit) { + this.fahrenheit = fahrenheit; + } + + public int getCelsius() { + return celsius; + } + + public void setCelsius(int celsius) { + this.celsius = celsius; + } +} |