diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml new file mode 100644 index 0000000..d633830 --- /dev/null +++ b/.idea/assetWizardSettings.xml @@ -0,0 +1,73 @@ + + + + + + \ No newline at end of file diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 89b2b09..aa3e752 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..859293a 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 8fecbb8..4808ccd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,4 +28,19 @@ dependencies { androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.github.pires:obd-java-api:1.0' + implementation 'org.mapsforge:mapsforge-map-android:0.9.1' + implementation 'com.caverock:androidsvg:1.3' + implementation 'com.google.android.gms:play-services-maps:16.0.0' + implementation 'org.mapsforge:mapsforge-core:0.9.1' + implementation 'org.mapsforge:mapsforge-map:0.9.1' + implementation(group: 'com.graphhopper', name: 'graphhopper-core', version: '0.11.0') { + exclude group: 'com.google.protobuf', module: 'protobuf-java' + exclude group: 'org.openstreetmap.osmosis', module: 'osmosis-osm-binary' + exclude group: 'org.apache.xmlgraphics', module: 'xmlgraphics-commons' + } + implementation 'org.nd4j:nd4j-backends:0.9.1' + implementation 'org.mapsforge:vtm:0.9.2' + implementation 'com.google.code.gson:gson:2.8.0' + implementation 'com.android.volley:volley:1.0.0' + } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3c015e4..4cdc920 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,10 @@ + + + + - + + \ No newline at end of file diff --git a/app/src/main/java/com/example/michal/inz/Location.java b/app/src/main/java/com/example/michal/inz/Location.java new file mode 100644 index 0000000..3a2d516 --- /dev/null +++ b/app/src/main/java/com/example/michal/inz/Location.java @@ -0,0 +1,112 @@ +package com.example.michal.inz; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.FragmentActivity; +import android.support.v4.content.ContextCompat; +import android.util.Log; + +import com.example.michal.inz.fragments.MapsFragment; + +import static android.Manifest.permission.ACCESS_FINE_LOCATION; + + +public class Location implements LocationListener { + + private Context applicationContext; + public LocationManager locationManager; + boolean canGetLocation = false; + android.location.Location location; + double latitude; + MapsFragment mapa; + public double longitude; + private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 1 meter + private static final long MIN_TIME_BW_UPDATES = 1; // 1 sec + + public Location(Context context, MapsFragment mapsFragment){ + this.applicationContext = context; + this.mapa = mapsFragment; + getLocation(); + } + + @Override + public void onLocationChanged(android.location.Location location) { + setLatitude(location.getLatitude()); + setLongitude(location.getLongitude()); + mapa.updateLocation(); + } + + public android.location.Location getLocation() { + + try { + locationManager = (LocationManager) applicationContext.getSystemService(Context.LOCATION_SERVICE); + // getting GPS status + boolean checkGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + Log.v("isGPSEnabled", "=" + checkGPS); + + if (!checkGPS) { + // no network provider is enabled + } else { + this.canGetLocation = true; + // if GPS Enabled get lat/long using GPS Services + if (checkGPS) { + location = null; + locationManager.requestLocationUpdates( + LocationManager.GPS_PROVIDER, + MIN_TIME_BW_UPDATES, + MIN_DISTANCE_CHANGE_FOR_UPDATES, this); + Log.d("GPS Enabled", "GPS Enabled"); + if (locationManager != null) { + location = locationManager + .getLastKnownLocation(LocationManager.GPS_PROVIDER); + if (location != null) { + latitude = location.getLatitude(); + longitude = location.getLongitude(); + } + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return location; + } + + @Override + public void onStatusChanged(String s, int i, Bundle bundle) { + + } + + @Override + public void onProviderEnabled(String s) { + + } + + @Override + public void onProviderDisabled(String s) { + + } + + public double getLatitude() { + return latitude; + } + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + public double getLongitude() { + return longitude; + } + + private void setLongitude(double longitude) { + this.longitude = longitude; + } +} diff --git a/app/src/main/java/com/example/michal/inz/MainActivity.java b/app/src/main/java/com/example/michal/inz/MainActivity.java index 61c8fcf..d44ce8e 100644 --- a/app/src/main/java/com/example/michal/inz/MainActivity.java +++ b/app/src/main/java/com/example/michal/inz/MainActivity.java @@ -1,12 +1,23 @@ package com.example.michal.inz; +import android.content.pm.PackageManager; import android.os.Bundle; import android.support.design.widget.TabLayout; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import com.example.michal.inz.fragments.ViewPagerAdapter; +import com.example.michal.inz.networking.Stats; + +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.Manifest.permission.BLUETOOTH; +import static android.Manifest.permission.BLUETOOTH_ADMIN; +import static android.Manifest.permission.INTERNET; +import static android.Manifest.permission.READ_EXTERNAL_STORAGE; +import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; public class MainActivity extends AppCompatActivity { @@ -31,5 +42,53 @@ protected void onCreate(Bundle savedInstanceState) { tabLayout = findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); + + checkPermissions(); + } + + private void checkPermissions() { + //read external storage + if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{READ_EXTERNAL_STORAGE}, + 1); + } + + //bluetooth + if (ContextCompat.checkSelfPermission(this, BLUETOOTH) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{BLUETOOTH}, + 2); + } + + //BLUETOOTH_ADMIN + if (ContextCompat.checkSelfPermission(this, BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{BLUETOOTH_ADMIN}, + 3); + } + + //GPS + if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{ACCESS_FINE_LOCATION}, + 4); + } + + //Internet + if (ContextCompat.checkSelfPermission(this, INTERNET) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{INTERNET}, + 5); + } + + if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{WRITE_EXTERNAL_STORAGE}, + 5); + } else { + // Permission has already been granted + } + } } diff --git a/app/src/main/java/com/example/michal/inz/MyMapView.java b/app/src/main/java/com/example/michal/inz/MyMapView.java new file mode 100644 index 0000000..d5c1e01 --- /dev/null +++ b/app/src/main/java/com/example/michal/inz/MyMapView.java @@ -0,0 +1,36 @@ +package com.example.michal.inz; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import com.example.michal.inz.fragments.MapsFragment; +import org.mapsforge.map.android.view.MapView; + +public class MyMapView extends MapView { + + public boolean centerLock = false; + MapsFragment parentFragment; + + public void setParentFragment(MapsFragment parentFragment) { + this.parentFragment = parentFragment; + } + + public MyMapView(Context context) { + super(context); + } + + public MyMapView(Context context, AttributeSet attributeSet) { + super(context, attributeSet); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_MOVE) { + centerLock = true; + parentFragment.updateLocation(); + // this.myMap = new AndroidMap(this); + } + return super.onTouchEvent(event); + } +} + diff --git a/app/src/main/java/com/example/michal/inz/fragments/MapsFragment.java b/app/src/main/java/com/example/michal/inz/fragments/MapsFragment.java index 9c2855a..1557b03 100644 --- a/app/src/main/java/com/example/michal/inz/fragments/MapsFragment.java +++ b/app/src/main/java/com/example/michal/inz/fragments/MapsFragment.java @@ -1,20 +1,80 @@ package com.example.michal.inz.fragments; - +import android.graphics.Path; +import android.os.AsyncTask; import android.os.Bundle; +import android.os.Environment; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.RadioButton; +import com.example.michal.inz.Location; +import com.example.michal.inz.MyMapView; import com.example.michal.inz.R; +import com.graphhopper.GHRequest; +import com.graphhopper.GHResponse; +import com.graphhopper.GraphHopper; +import com.graphhopper.PathWrapper; +import com.graphhopper.util.Parameters; +import com.graphhopper.util.PointList; +import com.graphhopper.util.StopWatch; + +import org.mapsforge.core.graphics.Bitmap; +import org.mapsforge.core.graphics.Cap; +import org.mapsforge.core.graphics.Color; +import org.mapsforge.core.graphics.Join; +import org.mapsforge.core.graphics.Paint; +import org.mapsforge.core.graphics.Style; +import org.mapsforge.core.model.LatLong; +import org.mapsforge.core.util.Utils; +import org.mapsforge.map.android.graphics.AndroidGraphicFactory; +import org.mapsforge.map.android.util.AndroidUtil; +import org.mapsforge.map.datastore.MapDataStore; +import org.mapsforge.map.layer.cache.TileCache; +import org.mapsforge.map.layer.overlay.Marker; +import org.mapsforge.map.layer.overlay.Polyline; +import org.mapsforge.map.layer.renderer.TileRendererLayer; +import org.mapsforge.map.reader.MapFile; +import org.mapsforge.map.rendertheme.ExternalRenderTheme; +import org.oscim.core.GeoPoint; +import org.oscim.layers.PathLayer; +import org.oscim.map.Map; +import java.io.File; +import java.util.ArrayList; +import java.util.List; /** * A simple {@link Fragment} subclass. */ public class MapsFragment extends Fragment implements FragmentName { + private static final String area = "poland-latest"; + private MyMapView mapView; + public FragmentActivity activity; + public View view; + Location myLocation = null; + Marker myLocationMarker; + Button yourLocationBtn; + Button navigateBtn; + ImageButton myDot; + GraphHopper graphHopper; + GeoPoint start; + GeoPoint end; + private boolean choosingLocation = false; + private boolean choosedLocation = false; + private boolean prepareFinished = false; + File myFolder; + PathLayer myRoute; + private boolean choosingLocationSecond = false; + Marker endMarker = null; + Polyline line = null; public MapsFragment() { // Required empty public constructor @@ -24,12 +84,225 @@ public MapsFragment() { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_maps, container, false); + + myLocation = new Location(getContext(), this); + + AndroidGraphicFactory.createInstance(getActivity().getApplication()); + activity = getActivity(); + view = inflater.inflate(R.layout.fragment_maps, container, false); + + mapView = view.findViewById(R.id.openmapview); + mapView.setClickable(true); + mapView.getMapScaleBar().setVisible(true); + mapView.setBuiltInZoomControls(true); + mapView.setParentFragment(this); + + setButtons(); + + try { + + myFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), + "/graphhopper/maps/"); + if (!myFolder.exists()) + myFolder.mkdirs(); + + File mapFile = new File(myFolder, area +"-gh/" + area + ".map"); + Log.d("map_fragment", String.valueOf(mapFile.exists())); + Bitmap markerImg = null; + markerImg = AndroidGraphicFactory.convertToBitmap(getResources().getDrawable(R.drawable.location_icon)); + + MapDataStore mapDataStore = new MapFile(mapFile); + TileCache tileCache = AndroidUtil.createTileCache(this.getActivity(), "fragments", + this.mapView.getModel().displayModel.getTileSize(), 1.0f, 1.5); + + TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, mapDataStore, + mapView.getModel().mapViewPosition, AndroidGraphicFactory.INSTANCE); + tileRendererLayer.setXmlRenderTheme(new ExternalRenderTheme(new File(myFolder, "theme.xml"))); + + myLocationMarker = new Marker(new LatLong(52.517037, 18.38886), markerImg, 0, 0); + this.mapView.getLayerManager().getLayers().add(tileRendererLayer); + this.mapView.getLayerManager().getLayers().add(myLocationMarker); + + mapView.setCenter(new LatLong(52.517037, 18.38886)); + mapView.setZoomLevel((byte) 18); + + /////////////////////////////////// + + new AsyncTask() { + + protected Path saveDoInBackground(Void... voids){ + try { + GraphHopper tmpHopp = new GraphHopper().forMobile(); + tmpHopp.load(new File(myFolder, area).getAbsolutePath() + "-gh"); + graphHopper = tmpHopp; + return null; + }catch (Exception e) { + e.printStackTrace(); + } + return null; + } + @Override + protected Path doInBackground(Void... voids) { + saveDoInBackground(voids); + return null; + } + + protected void onPostExecute(Path o) { + finishPrepare(); + } + }.execute(); + /// + + } catch (Exception e) { + e.printStackTrace(); + } + return view; + } + + private void finishPrepare() { + prepareFinished = true; + } + + private void setButtons() { + yourLocationBtn = view.findViewById(R.id.button); + yourLocationBtn.setVisibility(View.GONE); + yourLocationBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mapView.centerLock = false; + yourLocationBtn.setVisibility(View.GONE); + updateLocation(); + } + }); + + + myDot = view.findViewById(R.id.radioButton); + myDot.setVisibility(View.GONE); + navigateBtn = view.findViewById(R.id.buttonNavigate); + navigateBtn.setVisibility(View.VISIBLE); + navigateBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (prepareFinished) { + if (!choosingLocation && !choosedLocation) { + chosePointOnMap(); + } else if (!choosingLocation && choosedLocation) { + removeRoute(); + choosedLocation = false; + navigateBtn.setText("Nawiguj"); + } + else if (choosingLocation) { + choosePoint(); + choosingLocation = false; + addEndMarker(end); + navigateBtn.setText("Wyznaczanie"); + createPath(start, end); + choosedLocation = true; + } + } + } + }); + } + + private void removeRoute() { + mapView.getLayerManager().getLayers().remove(endMarker); + mapView.getLayerManager().getLayers().remove(line); + } + + private void addEndMarker(GeoPoint end) { + Bitmap markerImg = null; + markerImg = AndroidGraphicFactory.convertToBitmap(getResources().getDrawable(R.drawable.location_icon_end)); + endMarker = new Marker(new LatLong(end.getLatitude(), end.getLongitude()), markerImg, 0, 0); + mapView.getLayerManager().getLayers().add(endMarker); + } + + private void createPath(final GeoPoint start, final GeoPoint end) { + + new AsyncTask() { + float time; + + protected PathWrapper doInBackground(Void... v) { + StopWatch stopWatch = new StopWatch().start(); + GHRequest ghRequest = new GHRequest(start.getLatitude(), start.getLongitude(), + end.getLatitude(), end.getLongitude()). + setAlgorithm(Parameters.Algorithms.DIJKSTRA_BI); + + ghRequest.getHints().put(Parameters.Routing.INSTRUCTIONS, "false"); + GHResponse ghResponse = graphHopper.route(ghRequest); + time = stopWatch.stop().getSeconds(); + return ghResponse.getBest(); + } + + protected void onPostExecute(PathWrapper ghResponse) { + if (!ghResponse.hasErrors()) { + drawPath(ghResponse); + navigateBtn.setText("Nowa trasa"); + } + } + }.execute(); + + + } + + private void drawPath(PathWrapper ghResponse) { + + Paint paintStroke = AndroidGraphicFactory.INSTANCE.createPaint(); + + paintStroke.setStyle(Style.STROKE); + paintStroke.setStrokeJoin(Join.ROUND); + paintStroke.setStrokeCap(Cap.ROUND); + paintStroke.setColor(Color.GREEN); + paintStroke.setStrokeWidth(7); + + line = new Polyline(paintStroke, + AndroidGraphicFactory.INSTANCE); + + List geoPoints = line.getLatLongs(); + PointList tmp = ghResponse.getPoints(); + for (int i = 0; i < ghResponse.getPoints().getSize(); i++) { + geoPoints.add(new LatLong(tmp.getLatitude(i), tmp.getLongitude(i))); + } + mapView.getLayerManager().getLayers().add(line); + } + + private void choosePoint() { + choosingLocationSecond = true; + GeoPoint p = new GeoPoint(mapView.getModel().mapViewPosition.getMapPosition().latLong.latitude, + mapView.getModel().mapViewPosition.getMapPosition().latLong.longitude); + end = p; + start = new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude()); + myDot.setVisibility(View.GONE); + } + + private void chosePointOnMap() { + choosingLocation = true; + myDot.setVisibility(View.VISIBLE); + navigateBtn.setText("Nawiguj tutaj"); + } + + @Override + public void onResume() { + super.onResume(); + updateLocation(); } @Override public String getName() { return "Maps"; } + + public void updateLocation() { + if (!mapView.centerLock) { + mapView.setZoomLevel((byte) 18); + mapView.setCenter(new LatLong(myLocation.getLatitude(), myLocation.getLongitude())); + } + else if (yourLocationBtn.getVisibility() == View.GONE){ + yourLocationBtn.setVisibility(View.VISIBLE); + } + if (myLocationMarker != null){ + myLocationMarker.setLatLong(new LatLong(myLocation.getLatitude(), myLocation.getLongitude())); + myLocationMarker.setVisible(true); + } + } + } diff --git a/app/src/main/java/com/example/michal/inz/fragments/ParamsFragment.java b/app/src/main/java/com/example/michal/inz/fragments/ParamsFragment.java index ed9a881..28efa91 100644 --- a/app/src/main/java/com/example/michal/inz/fragments/ParamsFragment.java +++ b/app/src/main/java/com/example/michal/inz/fragments/ParamsFragment.java @@ -1,13 +1,11 @@ package com.example.michal.inz.fragments; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; -import android.os.ResultReceiver; import android.support.v4.app.Fragment; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; @@ -15,10 +13,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import android.widget.Toast; import com.example.michal.inz.R; -import com.example.michal.inz.bt_connection.BluetoothConnectionService; +import com.example.michal.inz.networking.BluetoothConnectionService; /** diff --git a/app/src/main/java/com/example/michal/inz/fragments/SettingsFragment.java b/app/src/main/java/com/example/michal/inz/fragments/SettingsFragment.java index 2626de5..3f5964f 100644 --- a/app/src/main/java/com/example/michal/inz/fragments/SettingsFragment.java +++ b/app/src/main/java/com/example/michal/inz/fragments/SettingsFragment.java @@ -8,9 +8,9 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; -import android.os.Handler; import android.os.ResultReceiver; import android.support.v4.app.Fragment; +import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -21,9 +21,10 @@ import android.widget.Switch; import android.widget.Toast; -import com.example.michal.inz.bt_connection.BluetoothConnectionService; +import com.example.michal.inz.networking.BluetoothConnectionService; import com.example.michal.inz.DeviceListAdapter; import com.example.michal.inz.R; +import com.example.michal.inz.networking.ServerConnection; import java.util.ArrayList; import java.util.Set; @@ -62,6 +63,13 @@ public void onPause() { super.onPause(); } + @Override + public void onResume(){ + IntentFilter BTIntent = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); + getActivity().registerReceiver(mBroadcastReceiver1, BTIntent); + super.onResume(); + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -95,7 +103,7 @@ public void onClick(View v) { mConnectButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - btConnect(); + startNetworking(); } }); @@ -103,20 +111,24 @@ public void onClick(View v) { return view; } - private void enableDisableBT(){ + private void enableDisableBT() { + Log.d(TAG, "onClick: enabling/disabling bluetooth."); - if(mBluetoothAdapter == null){ + if (mBluetoothAdapter == null) { Log.d(TAG, "enableDisableBT: Does not have BT capabilities."); return; } - - if(!mBluetoothAdapter.isEnabled()) { - Log.d(TAG, "enable BT"); - mBluetoothAdapter.enable(); - } else { - Log.d(TAG, "disable BT"); - mBluetoothAdapter.disable(); + try { + if (!mBluetoothAdapter.isEnabled()) { + Log.d(TAG, "enable BT"); + mBluetoothAdapter.enable(); + } else { + Log.d(TAG, "disable BT"); + mBluetoothAdapter.disable(); + } + } catch (NullPointerException e) { + e.printStackTrace(); } IntentFilter BTIntent = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); @@ -134,33 +146,45 @@ private void showPairedDevices() { mDevicesListView.setAdapter(mDeviceListAdapter); } - private void btConnect(){ - if (mElmAdapterDevice == null) { - Toast.makeText(getContext(), "You didn't choose a device!",Toast.LENGTH_LONG).show(); - return; + private void startNetworking() { + try { + btConnect(); + } catch (Exception e) { + Log.d(TAG, e.getMessage()); + Toast.makeText(getContext(), "Bluetooth socket inactive", Toast.LENGTH_LONG).show(); } - Log.d(TAG, "Starting connection thread"); - try { - Intent intent = new Intent(); - intent.setClass(getContext(), BluetoothConnectionService.class); - intent.putExtra("elmDevice", mElmAdapterDevice); - intent.putExtra("UUID", myUUID); - intent.putExtra("receiver", new ResultReceiver(null){ - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - Log.d(TAG, "received result"); - Log.d(TAG, resultData.getString("resultReceiverTag")); - } - }); - getActivity().startService(intent); + serverConnect(); } catch (Exception e) { Log.d(TAG, e.getMessage()); - Toast.makeText(getContext(), "Socket inactive", Toast.LENGTH_LONG).show(); + Toast.makeText(getContext(), "Server connection inactive", Toast.LENGTH_LONG).show(); } } + private void btConnect() { + if (mElmAdapterDevice == null) { + Toast.makeText(getContext(), "You didn't choose a device!",Toast.LENGTH_LONG).show(); + return; + } + + Log.d(TAG, "Starting bluetooth thread"); + + Intent intent = new Intent(); + intent.setClass(getContext(), BluetoothConnectionService.class); + intent.putExtra("elmDevice", mElmAdapterDevice); + intent.putExtra("UUID", myUUID); + getActivity().startService(intent); + } + + private void serverConnect() { + Log.d(TAG, "Register ServerConnection receiver"); + + ServerConnection serverConnection = new ServerConnection(); + LocalBroadcastManager.getInstance(getActivity()).registerReceiver(serverConnection, + new IntentFilter(BluetoothConnectionService.STATS_UPDATE_INTENT)); + } + private final BroadcastReceiver mBroadcastReceiver1 = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); @@ -189,10 +213,14 @@ public void onReceive(Context context, Intent intent) { }; private void updateBtSwitch() { - if (mBluetoothAdapter.isEnabled()) { - mBtOnOffSwitch.setChecked(true); - } else { - mBtOnOffSwitch.setChecked(false); + try { + if (mBluetoothAdapter.isEnabled()) { + mBtOnOffSwitch.setChecked(true); + } else { + mBtOnOffSwitch.setChecked(false); + } + } catch (NullPointerException e){ + e.printStackTrace(); } } diff --git a/app/src/main/java/com/example/michal/inz/bt_connection/BluetoothConnectionService.java b/app/src/main/java/com/example/michal/inz/networking/BluetoothConnectionService.java similarity index 85% rename from app/src/main/java/com/example/michal/inz/bt_connection/BluetoothConnectionService.java rename to app/src/main/java/com/example/michal/inz/networking/BluetoothConnectionService.java index 6db566b..4079e4f 100644 --- a/app/src/main/java/com/example/michal/inz/bt_connection/BluetoothConnectionService.java +++ b/app/src/main/java/com/example/michal/inz/networking/BluetoothConnectionService.java @@ -1,4 +1,4 @@ -package com.example.michal.inz.bt_connection; +package com.example.michal.inz.networking; import android.app.IntentService; import android.bluetooth.BluetoothDevice; @@ -12,6 +12,7 @@ import android.util.Log; import com.github.pires.obd.commands.SpeedCommand; +import com.github.pires.obd.commands.control.ModuleVoltageCommand; import com.github.pires.obd.commands.engine.RPMCommand; import com.github.pires.obd.commands.fuel.FuelLevelCommand; import com.github.pires.obd.commands.temperature.EngineCoolantTemperatureCommand; @@ -33,6 +34,7 @@ public class BluetoothConnectionService extends IntentService { public static final String RPM_TAG = "RPM"; public static final String FUEL_TAG = "FUEL"; public static final String SPEED_TAG = "SPEED"; + public static final String VOLTAGE_TAG = "VOLTAGE"; public final String TAG = "connectionService"; @@ -47,8 +49,6 @@ public class BluetoothConnectionService extends IntentService { private long statsUpdateFrequency; - private ResultReceiver receiver; - private Intent mStatResponseIntent; @@ -64,18 +64,10 @@ protected void onHandleIntent(@Nullable Intent intent) { mContext = getApplicationContext(); mmDevice = intent.getParcelableExtra("elmDevice"); deviceUUID = UUID.fromString(intent.getStringExtra("UUID")); - receiver = intent.getParcelableExtra("receiver"); mStatResponseIntent = new Intent(); mStatResponseIntent.setAction(STATS_UPDATE_INTENT); - SystemClock.sleep(5000); - for (int i = 0; i < 10; i++) { - mStatResponseIntent.putExtra("resultReceiverTag", "test " + i); - LocalBroadcastManager.getInstance(this).sendBroadcast(mStatResponseIntent); - Log.d(TAG, "message sent " + i); - } - if (!establishConnection()) { cleanup(); Log.d(TAG, "Preparing bluetooth connection failed"); @@ -112,6 +104,7 @@ private void updateStats() { getFuel(); getRpm(); getSpeed(); + getVoltage(); } private boolean establishConnection() { @@ -231,11 +224,8 @@ public void getTemperature() { EngineCoolantTemperatureCommand temp = new EngineCoolantTemperatureCommand(); try { temp.run(mInStream, mOutStream); - } catch (IOException e) { - e.printStackTrace(); - return; - } catch (InterruptedException e) { - e.printStackTrace(); + } catch (Exception e) { + Log.d(TAG, "Failed to read temperature"); return; } @@ -246,44 +236,46 @@ public void getRpm() { RPMCommand rpm = new RPMCommand(); try { rpm.run(mInStream, mOutStream); - } catch (IOException e) { - e.printStackTrace(); - return; - } catch (InterruptedException e) { - e.printStackTrace(); + } catch (Exception e) { + Log.d(TAG, "Failed to read rpm"); return; } mStatResponseIntent.putExtra(RPM_TAG, rpm.getRPM()); } public void getFuel() { -// FuelLevelCommand fuel = new FuelLevelCommand(); -// try { -// fuel.run(mInStream, mOutStream); -// } catch (IOException e) { -// e.printStackTrace(); -// return; -// } catch (InterruptedException e) { -// e.printStackTrace(); -// return; -// } -// mStatResponseIntent.putExtra(FUEL_TAG, fuel.getFuelLevel()); + FuelLevelCommand fuel = new FuelLevelCommand(); + try { + fuel.run(mInStream, mOutStream); + } catch (Exception e) { + Log.d(TAG, "Failed to read fuel"); + return; + } + mStatResponseIntent.putExtra(FUEL_TAG, fuel.getFuelLevel()); } public void getSpeed() { SpeedCommand speed = new SpeedCommand(); try { speed.run(mInStream, mOutStream); - } catch (IOException e) { - e.printStackTrace(); - return; - } catch (InterruptedException e) { - e.printStackTrace(); + } catch (Exception e) { + Log.d(TAG, "Failed to read speed"); return; } mStatResponseIntent.putExtra(SPEED_TAG, speed.getMetricSpeed()); } + public void getVoltage() { + ModuleVoltageCommand voltage = new ModuleVoltageCommand(); + try { + voltage.run(mInStream, mOutStream); + } catch (Exception e) { + Log.d(TAG, "Failed to read voltage"); + return; + } + mStatResponseIntent.putExtra(VOLTAGE_TAG, voltage.getVoltage()); + } + private void write_raw(byte[] bytes) { String text = new String(bytes, Charset.defaultCharset()); diff --git a/app/src/main/java/com/example/michal/inz/networking/ServerConnection.java b/app/src/main/java/com/example/michal/inz/networking/ServerConnection.java new file mode 100644 index 0000000..a66e0f1 --- /dev/null +++ b/app/src/main/java/com/example/michal/inz/networking/ServerConnection.java @@ -0,0 +1,111 @@ +package com.example.michal.inz.networking; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + + +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import java.io.UnsupportedEncodingException; + +public class ServerConnection extends BroadcastReceiver { + private static final String TAG = "ServerConnection"; + private static final String ADDRESS = "http://inzservv.azurewebsites.net/home/archive"; + + private float temperature = -1, speed = -1, fuelLevel = -1; + private double voltage = -1; + private int rpm = -1; + + RequestQueue requestQueue; + + public void onReceive(Context context, Intent intent) { + if (requestQueue == null) + requestQueue = Volley.newRequestQueue(context); + + String action = intent.getAction(); + if (action.equals(BluetoothConnectionService.STATS_UPDATE_INTENT)) { + getStats(intent); + + Log.d(TAG, "Creating request"); + StringRequest stringRequest = new StringRequest(Request.Method.POST, ADDRESS, + new Response.Listener() { + @Override + public void onResponse(String response) { + // Display the first 500 characters of the response string. + Log.d(TAG, "Response is: " + response); + } + }, new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + Log.d(TAG, "That didn't work!"); + } + }) { + @Override + public String getBodyContentType() { + return "application/json; charset=utf-8"; + } + + @Override + public byte[] getBody(){ + Stats stat = new Stats("SDhe", temperature, speed, (float) voltage, fuelLevel, rpm); + try { + String s = stat.toJson(); + Log.d(TAG, s); + return s.getBytes("utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + } + }; + Log.d(TAG, "Request to be put in queue"); + requestQueue.add(stringRequest); + Log.d(TAG, "Request in queue"); + } + } + + private void getStats(Intent intent) { + try { + temperature = intent.getFloatExtra(BluetoothConnectionService.TEMPERATURE_TAG, 0); + } catch (Exception e) { + temperature = -1; + Log.d(TAG, "Failed retrieve temperature from car"); + } + + try { + fuelLevel = intent.getFloatExtra(BluetoothConnectionService.FUEL_TAG, 0); + } catch (Exception e) { + fuelLevel = -1; + Log.d(TAG, "Failed retrieve fuel from car"); + } + + try { + rpm = intent.getIntExtra(BluetoothConnectionService.RPM_TAG, 0); + } catch (Exception e) { + rpm = -1; + Log.d(TAG, "Failed retrieve fuel from car"); + } + + try { + speed = intent.getIntExtra(BluetoothConnectionService.SPEED_TAG, 0); + } catch (Exception e) { + speed = -1; + Log.d(TAG, "Failed retrieve speed from car"); + } + + try { + voltage = intent.getIntExtra(BluetoothConnectionService.VOLTAGE_TAG, 0); + } catch (Exception e) { + voltage = -1; + Log.d(TAG, "Failed retrieve voltage from car"); + } + } + +} diff --git a/app/src/main/java/com/example/michal/inz/networking/Stats.java b/app/src/main/java/com/example/michal/inz/networking/Stats.java new file mode 100644 index 0000000..c6a556c --- /dev/null +++ b/app/src/main/java/com/example/michal/inz/networking/Stats.java @@ -0,0 +1,99 @@ +package com.example.michal.inz.networking; + +import org.json.JSONException; +import org.json.JSONObject; + +public class Stats { + private String vin; + private float temperature; + private float speed; + private float voltage; + private float fuelUsage; + private int engineSpeed; + + public Stats(String vin, float temperature, float speed, float voltage, + float fuelUsage, int engineSpeed) { + this.vin = vin; + this.temperature = temperature; + this.speed = speed; + this.voltage = voltage; + this.fuelUsage = fuelUsage; + this.engineSpeed = engineSpeed; + } + + @Override + public String toString() { + return "Stats{" + + "vin='" + vin + "'" + + ", temperature=" + temperature + + ", speed=" + speed + + ", voltage=" + voltage + + ", fuelUsage=" + fuelUsage + + ", engineSpeed=" + engineSpeed + + '}'; + } + + public String toJson() { + JSONObject object = new JSONObject(); + try { + object.put("vin", vin); + object.put("temperature" , temperature); + object.put("speed" , speed); + object.put("voltage" , voltage); + object.put("fuelUsage" , fuelUsage); + object.put("engineSpeed" , engineSpeed); + } catch (JSONException e) { + e.printStackTrace(); + } + + return object.toString(); + } + + public String getVin() { + return vin; + } + + public void setVin(String vin) { + this.vin = vin; + } + + public float getTemperature() { + return temperature; + } + + public void setTemperature(float temperature) { + this.temperature = temperature; + } + + public float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + public float getVoltage() { + return voltage; + } + + public void setVoltage(float voltage) { + this.voltage = voltage; + } + + public float getFuelUage() { + return fuelUsage; + } + + public void setFuelUage(float fuelUsage) { + this.fuelUsage = fuelUsage; + } + + public int getEngineSpeed() { + return engineSpeed; + } + + public void setEngineSpeed(int engineSpeed) { + this.engineSpeed = engineSpeed; + } +} diff --git a/app/src/main/res/drawable-hdpi/location_icon.png b/app/src/main/res/drawable-hdpi/location_icon.png new file mode 100644 index 0000000..da7bcb3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/location_icon.png differ diff --git a/app/src/main/res/drawable-hdpi/location_icon_end.png b/app/src/main/res/drawable-hdpi/location_icon_end.png new file mode 100644 index 0000000..07af53d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/location_icon_end.png differ diff --git a/app/src/main/res/drawable-mdpi/location_icon.png b/app/src/main/res/drawable-mdpi/location_icon.png new file mode 100644 index 0000000..ecfce2c Binary files /dev/null and b/app/src/main/res/drawable-mdpi/location_icon.png differ diff --git a/app/src/main/res/drawable-mdpi/location_icon_end.png b/app/src/main/res/drawable-mdpi/location_icon_end.png new file mode 100644 index 0000000..902b9d0 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/location_icon_end.png differ diff --git a/app/src/main/res/drawable-xhdpi/location_icon.png b/app/src/main/res/drawable-xhdpi/location_icon.png new file mode 100644 index 0000000..329da50 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/location_icon.png differ diff --git a/app/src/main/res/drawable-xhdpi/location_icon_end.png b/app/src/main/res/drawable-xhdpi/location_icon_end.png new file mode 100644 index 0000000..d4ee4a4 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/location_icon_end.png differ diff --git a/app/src/main/res/drawable-xxhdpi/location_icon.png b/app/src/main/res/drawable-xxhdpi/location_icon.png new file mode 100644 index 0000000..96afa86 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/location_icon.png differ diff --git a/app/src/main/res/drawable-xxhdpi/location_icon_end.png b/app/src/main/res/drawable-xxhdpi/location_icon_end.png new file mode 100644 index 0000000..5267282 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/location_icon_end.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/location_icon.png b/app/src/main/res/drawable-xxxhdpi/location_icon.png new file mode 100644 index 0000000..417f509 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/location_icon.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/location_icon_end.png b/app/src/main/res/drawable-xxxhdpi/location_icon_end.png new file mode 100644 index 0000000..1394466 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/location_icon_end.png differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 24322d5..59b856f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -9,7 +9,8 @@ android:orientation="vertical"> + layout="@layout/toolbar_layout" + /> - - -