Skip to content

Instantly share code, notes, and snippets.

@proycon
Created September 9, 2015 07:13
Show Gist options
  • Select an option

  • Save proycon/16439d5b6d80b68f73ee to your computer and use it in GitHub Desktop.

Select an option

Save proycon/16439d5b6d80b68f73ee to your computer and use it in GitHub Desktop.
Home automation android app with speech to text through google API, with self-signed certificate cause I'm cheap
package com.anaproy.homecontrol;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.http.SslError;
import android.net.http.SslError;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.net.URL;
import java.net.HttpURLConnection;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.net.URLEncoder;
import java.net.MalformedURLException;
import java.lang.Exception;
import java.io.IOException;
import java.net.SocketTimeoutException;
import android.util.Log;
import android.os.AsyncTask;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.SslErrorHandler;
import android.webkit.HttpAuthHandler;
public class MainActivity extends Activity implements OnClickListener {
protected static final int REQUEST_OK = 1;
private class HomeControlWebViewClient extends WebViewClient {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // Ignore SSL certificate errors!! (we are self-signed)
}
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
handler.proceed("USERNAME", "PASSWORD");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webview = (WebView) findViewById(R.id.webview);
webview.setWebViewClient(new HomeControlWebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setDomStorageEnabled(true);
webview.getSettings().setBuiltInZoomControls(true);
webview.getSettings().setUseWideViewPort(true);
webview.getSettings().setMediaPlaybackRequiresUserGesture(false);
webview.getSettings().setLoadWithOverviewMode(true);
webview.loadUrl("https://home.anaproy.nl");
}
@Override
public void onClick(View v) {
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==REQUEST_OK && resultCode==RESULT_OK) {
ArrayList<String> speech2text = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
String text = speech2text.get(0);
//((TextView)findViewById(R.id.text1)).setText(text);
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new TransferTask().execute(text);
} else {
// display error
Toast.makeText(this, "No network connection present", Toast.LENGTH_LONG).show();
}
}
}
private class TransferTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... text) {
return transfer(text[0]);
}
protected void onPostExecute(String response) {
Toast.makeText(MainActivity.this, response, Toast.LENGTH_LONG).show();
}
}
private String transfer(String text) {
String response = "";
SSLContext sslcontext;
try {
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.anaproy2014);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, tmf.getTrustManagers(), null);
} catch (Exception e) {
Log.d("HomeControl", Log.getStackTraceString(e));
response = "Error setting up SSL";
return response;
}
// fetch data
String baseurl = "https://home.anaproy.nl/voice/process/";
String strUrl = baseurl + URLEncoder.encode(text);
try {
// Create an HostnameVerifier that hardwires the expected hostname.
// Note that is different than the URL's hostname:
// example.com versus example.org
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hv =
HttpsURLConnection.getDefaultHostnameVerifier();
return hv.verify("anaproy.nl", session);
}
};
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
String username="USERNAME";
String password="PASSWORD";
return new PasswordAuthentication(username, password.toCharArray());
}
});
URL url = new URL(strUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(hostnameVerifier);
conn.setSSLSocketFactory(sslcontext.getSocketFactory());
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
// Starts the query
conn.connect();
int httpresponse = conn.getResponseCode();
if (httpresponse == 403) {
//used when the server does not understand the user
response = "Sorry, I don't understand that";
} else if (httpresponse != 200) {
response = "Error relaying voice command, computer says no :(";
} else {
response = "ok!";
}
conn.disconnect();
} catch (MalformedURLException e) {
response = "Malformed URL: " + strUrl;
} catch (SocketTimeoutException e) {
response = "Connect to server timed out";
} catch (IOException e) {
Log.d("HomeControl", Log.getStackTraceString(e));
response = "Unable to open connect to server";
} catch (Exception e) {
Log.d("HomeControl", Log.getStackTraceString(e));
response = "Unknown error while connecting to server";
}
return response;
}
//buttons
public void backClick(View view) {
WebView webview = (WebView) findViewById(R.id.webview);
if (webview.canGoBack()) {
webview.goBack();
}
}
public void speakClick(View view) {
Intent i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
i.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
try {
startActivityForResult(i, REQUEST_OK);
} catch (Exception e) {
Toast.makeText(this, "Error initializing speech to text engine.", Toast.LENGTH_LONG).show();
}
}
public void refreshClick(View view) {
WebView webview = (WebView) findViewById(R.id.webview);
webview.reload();
}
//not in interface currently
public void lightsOn(View view) {
new TransferTask().execute("lights on");
}
public void lightsOff(View view) {
new TransferTask().execute("lights off");
}
public void officelightOn(View view) {
new TransferTask().execute("office light on");
}
public void officelightOff(View view) {
new TransferTask().execute("office light off");
}
public void tvlightOn(View view) {
new TransferTask().execute("tv light on");
}
public void tvlightOff(View view) {
new TransferTask().execute("tv light off");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment