Add features
This commit is contained in:
@ -19,66 +19,111 @@ import android.widget.AdapterView;
|
|||||||
|
|
||||||
import org.conscrypt.Conscrypt;
|
import org.conscrypt.Conscrypt;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
|
import okhttp3.MediaType;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
import okio.BufferedSink;
|
||||||
|
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
private CardScrollView cardScroller;
|
private CardScrollView cardScroller;
|
||||||
|
|
||||||
private View view;
|
|
||||||
private TeslaResponse vehicleData;
|
private TeslaResponse vehicleData;
|
||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
|
|
||||||
|
private ArrayList<View> scrollerViews = new ArrayList<View>();
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle bundle) {
|
protected void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
||||||
StrictMode.setThreadPolicy(policy);
|
StrictMode.setThreadPolicy(policy);
|
||||||
prefs = getPreferences(MODE_PRIVATE);
|
prefs = getPreferences(MODE_PRIVATE);
|
||||||
view = buildStatusView();
|
scrollerViews.add(buildStatusView());
|
||||||
view.setKeepScreenOn(true);
|
scrollerViews.add(buildLocksView());
|
||||||
|
scrollerViews.add(buildControlView());
|
||||||
|
|
||||||
cardScroller = new CardScrollView(this);
|
cardScroller = new CardScrollView(this);
|
||||||
cardScroller.setAdapter(new CardScrollAdapter() {
|
cardScroller.setAdapter(new CardScrollAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return 1;
|
return scrollerViews.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getItem(int position) {
|
public Object getItem(int position) {
|
||||||
return view;
|
return scrollerViews.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
return view;
|
return scrollerViews.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPosition(Object item) {
|
public int getPosition(Object item) {
|
||||||
if (view.equals(item)) {
|
return scrollerViews.indexOf(item);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return AdapterView.INVALID_POSITION;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cardScroller.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
cardScroller.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
|
||||||
|
if (position == 2) {
|
||||||
|
postCommand("flash_lights");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position == 1) {
|
||||||
|
if (vehicleData.vehicle_state.locked) {
|
||||||
|
postCommand("door_unlock");
|
||||||
|
} else {
|
||||||
|
postCommand("door_lock");
|
||||||
|
}
|
||||||
|
scrollerViews.set(1, buildLocksView());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position == 0) {
|
||||||
|
scrollerViews.set(0, buildStatusView());
|
||||||
|
}
|
||||||
|
|
||||||
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
||||||
am.playSoundEffect(Sounds.TAP);
|
am.playSoundEffect(Sounds.TAP);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
cardScroller.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
|
||||||
|
if (position == 2) {
|
||||||
|
return postCommand("honk_horn");
|
||||||
|
}
|
||||||
|
if (position == 1) {
|
||||||
|
return postCommand("set_sentry_mode?on=" + !vehicleData.vehicle_state.sentry_mode);
|
||||||
|
}
|
||||||
|
if (position == 0) {
|
||||||
|
return postCommand("remote_start_drive?password=" + prefs.getString("auth_password", ""));
|
||||||
|
}
|
||||||
|
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
am.playSoundEffect(Sounds.DISALLOWED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
setContentView(cardScroller);
|
setContentView(cardScroller);
|
||||||
}
|
}
|
||||||
@ -95,8 +140,28 @@ public class MainActivity extends Activity {
|
|||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
private View buildStatusView() {
|
private View buildControlView() {
|
||||||
if (vehicleData == null) {
|
CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT);
|
||||||
|
card.setText("Tap to flash lights, long press to honk.");
|
||||||
|
return card.getView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private View buildLocksView() {
|
||||||
|
updateIfNeeded();
|
||||||
|
|
||||||
|
CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT);
|
||||||
|
String body = vehicleData.vehicle_state.locked ? "Tap to unlock" : "Tap to lock";
|
||||||
|
body += "\nLong press to ";
|
||||||
|
body += vehicleData.vehicle_state.sentry_mode ? "disable" : "enable";
|
||||||
|
body += " Sentry Mode";
|
||||||
|
card.setText(body);
|
||||||
|
return card.getView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateIfNeeded() {
|
||||||
|
Calendar expire = Calendar.getInstance();
|
||||||
|
expire.add(Calendar.MINUTE, -5);
|
||||||
|
if (vehicleData == null || new Date(vehicleData.vehicle_state.timestamp).after(expire.getTime())) {
|
||||||
try {
|
try {
|
||||||
getVehicleData();
|
getVehicleData();
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
@ -105,6 +170,10 @@ public class MainActivity extends Activity {
|
|||||||
System.exit(0); // Shouldn't be reached, but just in case let's kill it dead
|
System.exit(0); // Shouldn't be reached, but just in case let's kill it dead
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private View buildStatusView() {
|
||||||
|
updateIfNeeded();
|
||||||
|
|
||||||
CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT);
|
CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT);
|
||||||
String chargeDuration = "";
|
String chargeDuration = "";
|
||||||
@ -133,20 +202,49 @@ public class MainActivity extends Activity {
|
|||||||
);
|
);
|
||||||
card.setFootnote(String.format("%s last updated: %s",
|
card.setFootnote(String.format("%s last updated: %s",
|
||||||
vehicleData.display_name,
|
vehicleData.display_name,
|
||||||
new SimpleDateFormat("hh:mm").format(vehicleData.charge_state.timestamp)
|
new SimpleDateFormat("hh:mm").format(vehicleData.vehicle_state.timestamp)
|
||||||
));
|
));
|
||||||
|
View v = card.getView();
|
||||||
return card.getView();
|
v.setKeepScreenOn(true);
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /api/1/vehicles/{id}/vehicle_data
|
// /api/1/vehicles/{id}/vehicle_data
|
||||||
public void getVehicleData() {
|
public void getVehicleData() {
|
||||||
String vehicleId = prefs.getString("vehicle_id", "");
|
String vehicleId = prefs.getString("vehicle_id", "");
|
||||||
String json = getResponseFromJsonURL("https://owner-api.teslamotors.com/api/1/vehicles/" + vehicleId +"/vehicle_data");
|
String json = getResponseFromJsonURL("https://owner-api.teslamotors.com/api/1/vehicles/"
|
||||||
|
+ vehicleId +"/vehicle_data");
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
ResponseRoot root = gson.fromJson(json, ResponseRoot.class);
|
ResponseRoot root = gson.fromJson(json, ResponseRoot.class);
|
||||||
vehicleData = root.response;
|
vehicleData = root.response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean postCommand(String command) {
|
||||||
|
try {
|
||||||
|
String token = prefs.getString("bearer_token", "");
|
||||||
|
String vehicleId = prefs.getString("vehicle_id", "");
|
||||||
|
URL object = new URL("https://owner-api.teslamotors.com/api/1/vehicles/"
|
||||||
|
+ vehicleId +"/command/" + command);
|
||||||
|
OkHttpClient client = new OkHttpClient();
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(object)
|
||||||
|
.method("POST", RequestBody.create(null, new byte[]{}))
|
||||||
|
.addHeader("Authorization", "Bearer " + token)
|
||||||
|
.addHeader("User-Agent", "Tesla-GLASS")
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
Response response = client.newCall(request).execute();
|
||||||
|
|
||||||
|
return response.code() == 200;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public String getResponseFromJsonURL(String url) {
|
public String getResponseFromJsonURL(String url) {
|
||||||
String token = prefs.getString("bearer_token", "");
|
String token = prefs.getString("bearer_token", "");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user