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.
191 lines
6.1 KiB
191 lines
6.1 KiB
2 years ago
|
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;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|