diff --git a/app/src/main/java/de/itstall/freifunkfranken/controller/NextApAdapter.java b/app/src/main/java/de/itstall/freifunkfranken/controller/NextApAdapter.java index 83e297b0a465d6fe857f41c939bae27a3d7e3ac9..4e8491948b2500df5f2b4ecbc3227357ae4b945d 100644 --- a/app/src/main/java/de/itstall/freifunkfranken/controller/NextApAdapter.java +++ b/app/src/main/java/de/itstall/freifunkfranken/controller/NextApAdapter.java @@ -18,6 +18,7 @@ import de.itstall.freifunkfranken.model.AccessPoint; public class NextApAdapter extends RecyclerView.Adapter<NextApAdapter.ViewHolder> { private static final String TAG = NextApAdapter.class.getSimpleName(); private List<AccessPoint> accessPointList; + private OnItemClicked onClick; public NextApAdapter(List<AccessPoint> aps) { this.accessPointList = aps; @@ -26,7 +27,9 @@ public class NextApAdapter extends RecyclerView.Adapter<NextApAdapter.ViewHolder @NonNull @Override public NextApAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - @SuppressLint("InflateParams") View viewApsItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.nextap_item, null); + @SuppressLint("InflateParams") View viewApsItem = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.nextap_item, null); return new ViewHolder(viewApsItem); } @@ -36,12 +39,31 @@ public class NextApAdapter extends RecyclerView.Adapter<NextApAdapter.ViewHolder public void onBindViewHolder(NextApAdapter.ViewHolder viewHolder, int position) { viewHolder.tvAp.setText(accessPointList.get(position).getName()); viewHolder.tvStatus.setText( - accessPointList.get(position).isOnline() ? R.string.statusOnline : R.string.statusOffline + accessPointList.get(position) + .isOnline() ? R.string.statusOnline : R.string.statusOffline ); - viewHolder.tvDistance.setText( - String.format("%d m", accessPointList.get(position).getDistance()) - ); - viewHolder.tvStatus.setTextColor((accessPointList.get(position).isOnline()) ? Color.GREEN : Color.RED); + + double distance = accessPointList.get(position).getDistance(); + String distanceText = ""; + + if (distance > 999) distanceText = String.format("%3.2f km", distance / 1000); + else distanceText = String.format("%3.0f m", distance); + + viewHolder.tvDistance.setText(distanceText); + + viewHolder.tvStatus.setTextColor( + (accessPointList.get(position).isOnline()) ? Color.GREEN : Color.RED); + + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onClick.onItemClick(position); + } + }); + } + + public void setOnClick(OnItemClicked onClick) { + this.onClick = onClick; } @Override @@ -49,6 +71,10 @@ public class NextApAdapter extends RecyclerView.Adapter<NextApAdapter.ViewHolder return accessPointList.size(); } + public interface OnItemClicked { + void onItemClick(int position); + } + static class ViewHolder extends RecyclerView.ViewHolder { TextView tvAp; TextView tvStatus; diff --git a/app/src/main/java/de/itstall/freifunkfranken/view/MapsFragment.java b/app/src/main/java/de/itstall/freifunkfranken/view/MapsFragment.java index 02f5ffb6dac8a13412c30dc146d78e3244cc1a83..b09201188a14b0cb9047480d3d99198c5dce5cd6 100644 --- a/app/src/main/java/de/itstall/freifunkfranken/view/MapsFragment.java +++ b/app/src/main/java/de/itstall/freifunkfranken/view/MapsFragment.java @@ -7,6 +7,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.location.Criteria; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; @@ -14,6 +15,7 @@ import android.provider.Settings; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.core.app.ActivityCompat; import androidx.fragment.app.Fragment; @@ -56,9 +58,13 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { public void onLocationChanged(Location location) { if (mMap != null) { mMap.moveCamera(CameraUpdateFactory.newLatLngZoom( - new LatLng(location.getLatitude(), location.getLongitude()), mMap.getCameraPosition().zoom) + new LatLng( + location.getLatitude(), + location.getLongitude()), + mMap.getCameraPosition().zoom) ); - sharedPreferences.edit().putInt("mapZoom", (int) mMap.getCameraPosition().zoom).apply(); + sharedPreferences.edit() + .putInt("mapZoom", (int) mMap.getCameraPosition().zoom).apply(); } } @@ -75,20 +81,31 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView( + LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState + ) { rootView = inflater.inflate(R.layout.maps_fragment, container, false); progressDialog = new ProgressDialog(rootView.getContext()); progressDialog.setMessage(getResources().getString(R.string.mapLoading)); progressDialog.show(); - SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapFragment); + SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager() + .findFragmentById(R.id.mapFragment); if (mapFragment != null) mapFragment.getMapAsync(this); - sharedPreferences = rootView.getContext().getSharedPreferences(getResources().getString(R.string.app_name), 0); + sharedPreferences = rootView.getContext() + .getSharedPreferences(getResources().getString(R.string.app_name), 0); customLocationListener = new CustomLocationListener(locationListener); - locationManager = (LocationManager) rootView.getContext().getApplicationContext().getSystemService(Context.LOCATION_SERVICE); + locationManager = (LocationManager) rootView.getContext() + .getApplicationContext() + .getSystemService(Context.LOCATION_SERVICE); + + String locationProvider = getEnabledLocationProvider(); + Dexter.withActivity((Activity) rootView.getContext()) .withPermissions( Manifest.permission.ACCESS_FINE_LOCATION, @@ -96,23 +113,39 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { ) .withListener(new MultiplePermissionsListener() { @Override - public void onPermissionsChecked(MultiplePermissionsReport report) { + public void onPermissionsChecked( + MultiplePermissionsReport report + ) { if (report.areAllPermissionsGranted()) { if ( ActivityCompat.checkSelfPermission( rootView.getContext(), - Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED + Manifest + .permission + .ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( rootView.getContext(), - Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED + Manifest + .permission + .ACCESS_COARSE_LOCATION + ) == PackageManager.PERMISSION_GRANTED ) { - locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 25, customLocationListener); + locationManager + .requestLocationUpdates( + locationProvider, + 3000, + 25, + customLocationListener); } } } @Override - public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) { + public void onPermissionRationaleShouldBeShown( + List<PermissionRequest> permissions, + PermissionToken token + ) { token.continuePermissionRequest(); } } @@ -123,15 +156,27 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { } private void showApsOnMap() { - List<AccessPoint> accessPointList = new RequestAps(Objects.requireNonNull(this.getContext())).getSortedList(sharedPreferences.getBoolean("MapOfflineRouter", false), 0); + List<AccessPoint> accessPointList = new RequestAps( + Objects.requireNonNull( + this.getContext())) + .getSortedList( + sharedPreferences.getBoolean( + "MapOfflineRouter", + false) + , 0); for (int i = 0; i < accessPointList.size(); i++) { - LatLng ap = new LatLng(accessPointList.get(i).getLat(), accessPointList.get(i).getLon()); - MarkerOptions markerOptions = new MarkerOptions().position(ap).title(accessPointList.get(i).getName()); + LatLng ap = new LatLng( + accessPointList.get(i).getLat(), accessPointList.get(i).getLon()); + MarkerOptions markerOptions = new MarkerOptions() + .position(ap) + .title(accessPointList.get(i).getName()); if (accessPointList.get(i).isOnline()) - markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); + markerOptions.icon( + BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); else - markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); + markerOptions.icon( + BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); mMap.addMarker(markerOptions); } } @@ -176,4 +221,28 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { } }).check(); } + + private String getEnabledLocationProvider() { + LocationManager locationManager = (LocationManager) rootView.getContext() + .getSystemService(Context.LOCATION_SERVICE); + + //Kriterien um den LocationProvider zu finden + Criteria criteria = new Criteria(); + + //Gebe Namen des Providers zurück, der auf die Kriterien am besten passt + String bestProvider = locationManager.getBestProvider(criteria, true); + + boolean enabled = locationManager.isProviderEnabled(bestProvider); + + if (!enabled) { + Toast.makeText( + rootView.getContext(), + "No location provider enabled!", + Toast.LENGTH_LONG + ).show(); + + return null; + } + return bestProvider; + } } diff --git a/app/src/main/java/de/itstall/freifunkfranken/view/NextApFragment.java b/app/src/main/java/de/itstall/freifunkfranken/view/NextApFragment.java index 9831b93c98ac66ba707e032ba9a5922348811a76..64caa57a5ebc353a3977e048c43348a01ae9c03b 100644 --- a/app/src/main/java/de/itstall/freifunkfranken/view/NextApFragment.java +++ b/app/src/main/java/de/itstall/freifunkfranken/view/NextApFragment.java @@ -3,14 +3,18 @@ package de.itstall.freifunkfranken.view; import android.Manifest; import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.location.Criteria; import android.location.Location; import android.location.LocationManager; +import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.core.app.ActivityCompat; import androidx.fragment.app.Fragment; @@ -32,12 +36,13 @@ import de.itstall.freifunkfranken.controller.NextApAdapter; import de.itstall.freifunkfranken.controller.RequestAps; import de.itstall.freifunkfranken.model.AccessPoint; -public class NextApFragment extends Fragment { +public class NextApFragment extends Fragment implements NextApAdapter.OnItemClicked { public static Location location; private RecyclerView rvAps; private View rootView; private SharedPreferences sharedPreferences; private LocationManager locationManager; + private List<AccessPoint> accessPointList; @Override public void onCreate(Bundle savedInstanceState) { @@ -61,6 +66,9 @@ public class NextApFragment extends Fragment { locationManager = (LocationManager) rootView.getContext() .getApplicationContext() .getSystemService(Context.LOCATION_SERVICE); + + String locationProvider = getEnabledLocationProvider(); + Dexter.withActivity((Activity) rootView.getContext()) .withPermissions( Manifest.permission.ACCESS_FINE_LOCATION, @@ -68,17 +76,26 @@ public class NextApFragment extends Fragment { ) .withListener(new MultiplePermissionsListener() { @Override - public void onPermissionsChecked(MultiplePermissionsReport report) { + public void onPermissionsChecked( + MultiplePermissionsReport report + ) { if (report.areAllPermissionsGranted()) { if ( ActivityCompat.checkSelfPermission( rootView.getContext(), - Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED + Manifest + .permission + .ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( rootView.getContext(), - Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED + Manifest + .permission + .ACCESS_COARSE_LOCATION + ) == PackageManager.PERMISSION_GRANTED ) { - location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + location = locationManager + .getLastKnownLocation(locationProvider); } } } @@ -94,12 +111,13 @@ public class NextApFragment extends Fragment { ) .check(); - List<AccessPoint> accessPointList = new RequestAps( + accessPointList = new RequestAps( Objects.requireNonNull(this.getContext())). getSortedList( sharedPreferences.getBoolean("OfflineRouter", false), sharedPreferences.getInt("RouterCount", 10) ); + showApList(accessPointList); return rootView; @@ -109,5 +127,51 @@ public class NextApFragment extends Fragment { NextApAdapter nextApAdapter = new NextApAdapter(accessPointList); rvAps.setAdapter(nextApAdapter); rvAps.setItemAnimator(new DefaultItemAnimator()); + nextApAdapter.setOnClick(this); + } + + @Override + public void onItemClick(int position) { + // TODO: Start navigation + + // Create a Uri from an intent string. Use the result to create an Intent. + Uri gmmIntentUri = Uri.parse("google.navigation:q=" + + accessPointList.get(position).getLat() + "," + + accessPointList.get(position).getLon()); + + // Create an Intent from gmmIntentUri. Set the action to ACTION_VIEW + Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri); + // Make the Intent explicit by setting the Google Maps package + mapIntent.setPackage("com.google.android.apps.maps"); + + // Attempt to start an activity that can handle the Intent + if (mapIntent.resolveActivity(getContext().getPackageManager()) != null) { + startActivity(mapIntent); + } + } + + private String getEnabledLocationProvider() { + LocationManager locationManager = (LocationManager) rootView + .getContext() + .getSystemService(Context.LOCATION_SERVICE); + + //Kriterien um den LocationProvider zu finden + Criteria criteria = new Criteria(); + + //Gebe Namen des Providers zurück, der auf die Kriterien am besten passt + String bestProvider = locationManager.getBestProvider(criteria, true); + + boolean enabled = locationManager.isProviderEnabled(bestProvider); + + if (!enabled) { + Toast.makeText( + rootView.getContext(), + "No location provider enabled!", + Toast.LENGTH_LONG + ).show(); + + return null; + } + return bestProvider; } } diff --git a/app/src/main/res/layout/nextap_item.xml b/app/src/main/res/layout/nextap_item.xml index d44161b84e1135f3150d73228e17c857e26e310e..ed5e48484614741c6c0dc58c6782188e1147f8f3 100644 --- a/app/src/main/res/layout/nextap_item.xml +++ b/app/src/main/res/layout/nextap_item.xml @@ -1,57 +1,51 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/nextApTvDistance" + android:layout_width="70dp" + android:layout_height="wrap_content" + android:layout_marginStart="5dp" + android:layout_marginTop="10dp" + android:layout_marginEnd="5dp" + android:layout_weight="1" + android:text="@string/dummyText" + android:textAlignment="viewEnd" /> <LinearLayout - android:layout_width="match_parent" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="5dp" - android:layout_marginTop="5dp" - android:layout_marginRight="5dp" - android:orientation="horizontal"> + android:layout_weight="4" + android:orientation="vertical"> <TextView android:id="@+id/nextApTvSsid" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_weight="4" + android:layout_marginTop="10dp" + android:text="@string/dummyText" android:textColor="@android:color/primary_text_light" /> - <TextView - android:id="@+id/nextApTvDistance" - android:layout_width="wrap_content" + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_weight="1" - android:textAlignment="viewEnd" /> - </LinearLayout> + android:orientation="horizontal"> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginLeft="5dp" - android:layout_marginRight="5dp" - android:layout_marginBottom="5dp" - android:orientation="horizontal"> + <TextView + android:id="@+id/nextApTvStatusLabel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/nextApTvStatusLabel" /> - <TextView - android:id="@+id/nextApTvStatusLabel" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/nextApTvStatusLabel" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + <TextView + android:id="@+id/nextApTvStatus" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/dummyText" /> + </LinearLayout> - <TextView - android:id="@+id/nextApTvStatus" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="5dp" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toTopOf="parent" /> </LinearLayout> </LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cc7ead0f17f54f2b0ceb037b3c6f059e718264bf..28343dccdd03b884eeb29dfcacd7e25878096505 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,4 +38,5 @@ <string name="newsArticleRead">Beitrag lesen</string> <string name="mapLoading">Lade Karte…</string> <string name="locationNoGps">GPS nicht aktiviert</string> + <string name="dummyText">Text Dummy</string> </resources>