Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a local web server to modify settings. #23

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
</intent-filter>
</activity>
<receiver android:name=".receiver.AlarmReceiver" />

<service
android:name=".settings.ServerService"
android:enabled="true" >
</service>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private void setViewState() {
mWaterPlants.setVisibility(ChoresModule.waterPlantsToday() ? View.VISIBLE : View.GONE);
mGroceryList.setVisibility(ChoresModule.makeGroceryListToday() ? View.VISIBLE : View.GONE);

ForecastModule.getHourlyForecast(getResources(), 40.681045, -73.9931749, mForecastListener);
ForecastModule.getHourlyForecast(getSharedPreferences(MirrorApplication.SHARED_PREF_NAME, MODE_PRIVATE), 40.681045, -73.9931749, mForecastListener);
XKCDModule.getXKCDForToday(mXKCDListener);

if (WeekUtil.isWeekday() && WeekUtil.afterFive()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
import android.os.SystemClock;

import com.morristaedt.mirror.receiver.AlarmReceiver;
import com.morristaedt.mirror.settings.ServerService;

/**
* Created by HannahMitt on 8/22/15.
*/
public class MirrorApplication extends Application {

private static final long MINUTES_10 = 10 * 60 * 1000;
public static final String SHARED_PREF_NAME = "HomeMirrorPrefs";

@Override
public void onCreate() {
Expand All @@ -25,5 +27,8 @@ public void onCreate() {
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);

alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + MINUTES_10, MINUTES_10, alarmIntent);

Intent serverIntent = new Intent(this, ServerService.class);
startService(serverIntent);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.morristaedt.mirror.modules;

import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.util.Log;
Expand Down Expand Up @@ -27,7 +28,7 @@ public interface ForecastListener {
void onShouldBike(boolean showToday, boolean shouldBike);
}

public static void getHourlyForecast(final Resources resources, final double lat, final double lon, final ForecastListener listener) {
public static void getHourlyForecast(final SharedPreferences sharedPreferences, final double lat, final double lon, final ForecastListener listener) {
new AsyncTask<Void, Void, ForecastResponse>() {

@Override
Expand All @@ -47,7 +48,13 @@ public Throwable handleError(RetrofitError cause) {
String excludes = "minutely,daily,flags";
String units = "si";
Log.d("mirror", "backgrounddd");
return service.getHourlyForecast(resources.getString(R.string.dark_sky_api_key), lat, lon, excludes, units);
String api_key = sharedPreferences.getString("dark_sky_api_key", "not_a_valid_key");
if (!api_key.equals("not_a_valid_key")) {
return service.getHourlyForecast(api_key, lat, lon, excludes, units);
} else {
// null is well handled in onPostExecute
return null;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.morristaedt.mirror.settings;

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;

import com.morristaedt.mirror.MirrorApplication;

public class ServerService extends Service {
private SettingsWebServer server;

@Override
public void onCreate() {
super.onCreate();
server = new SettingsWebServer(this);
server.startServer();
}

@Override
public void onDestroy() {
server.stopServer();
super.onDestroy();
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.morristaedt.mirror.settings;

import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.entity.ContentProducer;
import org.apache.http.entity.EntityTemplate;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

/**
* Created by alex on 12/09/15.
*/
public class SettingsPageHandler implements HttpRequestHandler {
private static final String PAGE_HTML = "<html><head><title>HomeMirror Settings</title></head>" +
"<body>" +
"<form action=\"set_settings\" method =\"post\">" +
"<h3>Forecast.io API Key</h3>" +
"<input type=\"text\" name=\"dark_sky_api_key\"></input><br />\n" +
"<input type=\"submit\" value=\"Save settings\">\n" +
"</form>" +
"</body>";


@Override
public void handle(HttpRequest httpRequest, HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
HttpEntity entity = new EntityTemplate(new ContentProducer() {
public void writeTo(final OutputStream outstream) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8");
writer.write(PAGE_HTML);
writer.flush();
}
});
httpResponse.setHeader("Content-Type", "text/html");
httpResponse.setEntity(entity);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.morristaedt.mirror.settings;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;

import com.morristaedt.mirror.MirrorActivity;
import com.morristaedt.mirror.MirrorApplication;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* Created by alex on 13/09/15.
*/
public class SettingsSaveHandler implements HttpRequestHandler {

public static final String DARK_SKY_API_KEY = "dark_sky_api_key";
private Context context;

public SettingsSaveHandler(Context context) {
this.context = context;
}

@Override
public void handle(HttpRequest httpRequest, HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
SharedPreferences sharedPreferences = context.getSharedPreferences(MirrorApplication.SHARED_PREF_NAME, Context.MODE_PRIVATE);
HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) httpRequest;
HttpEntity entity = request.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
String out = reader.readLine();
while (out != null && !out.equals("")) {
String[] splitOutput = out.split("=");
if (splitOutput.length == 2) {
if (splitOutput[0].equals(DARK_SKY_API_KEY)) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(DARK_SKY_API_KEY, splitOutput[1]);
editor.apply();
}
}

//Get the next line from the reader, will be null if empty and loop will terminate
out = reader.readLine();
}

// Return settings page again
new SettingsPageHandler().handle(httpRequest, httpResponse, httpContext);

// Force refresh of main screen
Intent mainActivityIntent = new Intent(context, MirrorActivity.class);
mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainActivityIntent);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.morristaedt.mirror.settings;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import org.apache.http.HttpException;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* Created by alex on 12/09/15.
*/
public class SettingsWebServer {
public static final int PORT = 8080;

private boolean serverIsRunning = false;
private BasicHttpProcessor basicHttpProcessor;
private BasicHttpContext basicHttpContext;
private HttpService httpService ;
private HttpRequestHandlerRegistry handlerRegistry;
private ServerSocket serverSocket;

private String settingsPagePath = "/";
private String settingsSavePath = "/set_settings";

public SettingsWebServer(Context context) {
Log.d("SettingsWebServer", "Creating web server");
basicHttpProcessor = new BasicHttpProcessor();
basicHttpContext = new BasicHttpContext();

basicHttpProcessor.addInterceptor(new ResponseDate());
basicHttpProcessor.addInterceptor(new ResponseServer());
basicHttpProcessor.addInterceptor(new ResponseContent());
basicHttpProcessor.addInterceptor(new ResponseConnControl());

httpService = new HttpService(basicHttpProcessor, new DefaultConnectionReuseStrategy(), new DefaultHttpResponseFactory());

handlerRegistry = new HttpRequestHandlerRegistry();
handlerRegistry.register(settingsPagePath, new SettingsPageHandler());
handlerRegistry.register(settingsSavePath, new SettingsSaveHandler(context));

httpService.setHandlerResolver(handlerRegistry);
}

public void handleRequests() {
try {
serverSocket = new ServerSocket(PORT);
serverSocket.setReuseAddress(true);

while (serverIsRunning) {
final Socket clientSocket = serverSocket.accept();
DefaultHttpServerConnection serverConnection = new DefaultHttpServerConnection();
serverConnection.bind(clientSocket, new BasicHttpParams());
httpService.handleRequest(serverConnection, basicHttpContext);
serverConnection.shutdown();
}

serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (HttpException e) {
e.printStackTrace();
}
serverIsRunning = false;
}

public synchronized void startServer() {
serverIsRunning = true;
new Thread(new Runnable() {
@Override
public void run() {
handleRequests();
}
}).start();
}

public synchronized void stopServer() {
serverIsRunning = false;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}