You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
6.1 KiB
190 lines
6.1 KiB
package haus.nightmare.GlassTesla; |
|
|
|
import com.google.android.glass.media.Sounds; |
|
import com.google.android.glass.widget.CardBuilder; |
|
import com.google.android.glass.widget.CardScrollAdapter; |
|
import com.google.android.glass.widget.CardScrollView; |
|
import com.google.gson.Gson; |
|
|
|
import android.app.Activity; |
|
import android.content.Context; |
|
import android.content.SharedPreferences; |
|
import android.media.AudioManager; |
|
import android.os.Bundle; |
|
import android.os.StrictMode; |
|
import android.util.Log; |
|
import android.view.View; |
|
import android.view.ViewGroup; |
|
import android.widget.AdapterView; |
|
|
|
import org.conscrypt.Conscrypt; |
|
|
|
import java.net.URL; |
|
import java.security.Security; |
|
import java.text.SimpleDateFormat; |
|
import java.util.Calendar; |
|
|
|
import javax.net.ssl.SSLException; |
|
|
|
import okhttp3.OkHttpClient; |
|
import okhttp3.Request; |
|
import okhttp3.Response; |
|
|
|
|
|
public class MainActivity extends Activity { |
|
|
|
private CardScrollView cardScroller; |
|
|
|
private View view; |
|
private TeslaResponse vehicleData; |
|
private SharedPreferences prefs; |
|
@Override |
|
protected void onCreate(Bundle bundle) { |
|
super.onCreate(bundle); |
|
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); |
|
StrictMode.setThreadPolicy(policy); |
|
prefs = getPreferences(MODE_PRIVATE); |
|
view = buildStatusView(); |
|
view.setKeepScreenOn(true); |
|
cardScroller = new CardScrollView(this); |
|
cardScroller.setAdapter(new CardScrollAdapter() { |
|
@Override |
|
public int getCount() { |
|
return 1; |
|
} |
|
|
|
@Override |
|
public Object getItem(int position) { |
|
return view; |
|
} |
|
|
|
@Override |
|
public View getView(int position, View convertView, ViewGroup parent) { |
|
return view; |
|
} |
|
|
|
@Override |
|
public int getPosition(Object item) { |
|
if (view.equals(item)) { |
|
return 0; |
|
} |
|
return AdapterView.INVALID_POSITION; |
|
} |
|
}); |
|
|
|
cardScroller.setOnItemClickListener(new AdapterView.OnItemClickListener() { |
|
@Override |
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
|
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); |
|
am.playSoundEffect(Sounds.TAP); |
|
|
|
} |
|
}); |
|
setContentView(cardScroller); |
|
} |
|
|
|
@Override |
|
protected void onResume() { |
|
super.onResume(); |
|
cardScroller.activate(); |
|
} |
|
|
|
@Override |
|
protected void onPause() { |
|
cardScroller.deactivate(); |
|
super.onPause(); |
|
} |
|
|
|
private View buildStatusView() { |
|
if (vehicleData == null) { |
|
try { |
|
getVehicleData(); |
|
} catch(Exception e) { |
|
Log.v("Tesla API Setup", "Unable to get Tesla data", e); |
|
this.finishAffinity(); |
|
System.exit(0); // Shouldn't be reached, but just in case let's kill it dead |
|
} |
|
} |
|
|
|
CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT); |
|
String chargeDuration = ""; |
|
int totalSecs = (int) (vehicleData.charge_state.time_to_full_charge * 3600); |
|
int hours = totalSecs / 3600; |
|
int minutes = (totalSecs % 3600) / 60; |
|
if (hours > 0) { |
|
chargeDuration += hours + "h"; |
|
} |
|
if (minutes > 0) { |
|
chargeDuration += minutes + "m"; |
|
} |
|
Calendar cal = Calendar.getInstance(); |
|
cal.add(Calendar.HOUR_OF_DAY, hours); |
|
cal.add(Calendar.MINUTE, minutes); |
|
card.setText( |
|
String.format(getString(R.string.StatusFormat), |
|
vehicleData.charge_state.battery_level, |
|
(int) vehicleData.charge_state.battery_range, |
|
vehicleData.vehicle_state.sentry_mode ? "Enabled" : "Disabled", |
|
vehicleData.charge_state.charging_state, |
|
vehicleData.charge_state.charger_power, |
|
chargeDuration, |
|
new SimpleDateFormat("hh:mm").format(cal.getTime()) |
|
) |
|
); |
|
card.setFootnote(String.format("%s last updated: %s", |
|
vehicleData.display_name, |
|
new SimpleDateFormat("hh:mm").format(vehicleData.charge_state.timestamp) |
|
)); |
|
|
|
return card.getView(); |
|
} |
|
|
|
// /api/1/vehicles/{id}/vehicle_data |
|
public void getVehicleData() { |
|
String vehicleId = prefs.getString("vehicle_id", ""); |
|
String json = getResponseFromJsonURL("https://owner-api.teslamotors.com/api/1/vehicles/" + vehicleId +"/vehicle_data"); |
|
Gson gson = new Gson(); |
|
ResponseRoot root = gson.fromJson(json, ResponseRoot.class); |
|
vehicleData = root.response; |
|
} |
|
public String getResponseFromJsonURL(String url) { |
|
String token = prefs.getString("bearer_token", ""); |
|
|
|
String jsonResponse = null; |
|
if (url.length() > 0) { |
|
try { |
|
Security.insertProviderAt(Conscrypt.newProvider(), 1); |
|
|
|
|
|
|
|
/************** For getting response from HTTP URL start ***************/ |
|
URL object = new URL(url); |
|
|
|
OkHttpClient client = new OkHttpClient(); |
|
Request request = new Request.Builder() |
|
.url(object) |
|
.addHeader("Authorization", "Bearer " + token) |
|
.addHeader("User-Agent", "Tesla-GLASS") |
|
.addHeader("Content-Type", "application/json") |
|
.build(); |
|
|
|
Response response = client.newCall(request).execute(); |
|
|
|
int responseCode = response.code(); |
|
|
|
if (responseCode == 200) { |
|
return response.body().string(); |
|
|
|
} |
|
} catch (SSLException e) { |
|
Log.e("DataSSL", "SSL Exception getting json:", e); |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
} |
|
} |
|
return jsonResponse; |
|
} |
|
|
|
} |
|
|
|
|
|
|