import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.graphics.Rect; | import android.graphics.Rect; | ||||
import android.util.Log; | import android.util.Log; | ||||
import android.view.Gravity; | |||||
import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||
import android.view.View; | import android.view.View; | ||||
import android.view.ViewGroup; | import android.view.ViewGroup; | ||||
import android.widget.BaseAdapter; | import android.widget.BaseAdapter; | ||||
import android.widget.ImageView; | import android.widget.ImageView; | ||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import android.widget.Toast; | |||||
import com.example.meinwald.BuildConfig; | import com.example.meinwald.BuildConfig; | ||||
import com.example.meinwald.R; | import com.example.meinwald.R; | ||||
public View getView(final int i, View view, final ViewGroup viewGroup) { | public View getView(final int i, View view, final ViewGroup viewGroup) { | ||||
view = inflater.inflate(R.layout.area_element, null); | view = inflater.inflate(R.layout.area_element, null); | ||||
final ConstraintLayout elementView = view.findViewById(R.id.areaInfoView); | |||||
final ConstraintLayout elementView = view.findViewById(R.id.areaElement); | |||||
final ConstraintLayout infovView = view.findViewById(R.id.areaInfoView); | final ConstraintLayout infovView = view.findViewById(R.id.areaInfoView); | ||||
final TextView title = (TextView) view.findViewById(R.id.areaInfoTitle); | final TextView title = (TextView) view.findViewById(R.id.areaInfoTitle); | ||||
final TextView notice = (TextView) view.findViewById(R.id.areaInfoNotice); | final TextView notice = (TextView) view.findViewById(R.id.areaInfoNotice); | ||||
final ImageView icon = (ImageView) view.findViewById(R.id.areaIcon); | final ImageView icon = (ImageView) view.findViewById(R.id.areaIcon); | ||||
context = view.getContext(); | |||||
final ImageView manageArea = (ImageView) view.findViewById(R.id.areaManageArea); | |||||
context = view.getContext(); | |||||
if (BuildConfig.DEBUG) | if (BuildConfig.DEBUG) | ||||
{ | { | ||||
notice.setText(areaList.get(i).getNotice()); | notice.setText(areaList.get(i).getNotice()); | ||||
icon.setImageBitmap(areaList.get(i).getImage()); | icon.setImageBitmap(areaList.get(i).getImage()); | ||||
title.setOnClickListener(new View.OnClickListener() { | |||||
manageArea.setOnClickListener(new View.OnClickListener() { | |||||
@Override | @Override | ||||
public void onClick(View v) | public void onClick(View v) | ||||
{ | { | ||||
final AlertDialog.Builder builder = new AlertDialog.Builder(v.getRootView().getContext()); | |||||
final View viewInflated = LayoutInflater.from(v.getRootView().getContext()).inflate(R.layout.area_management, viewGroup, false); | |||||
builder.setView(viewInflated); | |||||
} | |||||
}); | |||||
//get elements | |||||
TextView title = viewInflated.findViewById(R.id.areaManageTitle); | |||||
final TextView notice = viewInflated.findViewById(R.id.areaManageNotice); | |||||
TextView gpscount = viewInflated.findViewById(R.id.areaManageGPSPoints); | |||||
ImageView image = (ImageView) viewInflated.findViewById(R.id.areaManageImage); | |||||
notice.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) | |||||
{ | |||||
ImageView newNotice = (ImageView) viewInflated.findViewById(R.id.areaManageNewDescription); | |||||
ImageView newGPS = (ImageView) viewInflated.findViewById(R.id.areaManageNewGPS); | |||||
ImageView newImage = (ImageView) viewInflated.findViewById(R.id.areaManageNewImage); | |||||
ImageView deleteArea = (ImageView) viewInflated.findViewById(R.id.areaManageDeleteArea); | |||||
//set current vlues | |||||
title.setText(areaList.get(i).getTitle()); | |||||
notice.setText(areaList.get(i).getNotice()); | |||||
gpscount.setText(String.valueOf(areaList.get(i).getLocations().size())); | |||||
if (areaList.get(i).getImage() != null) | |||||
{ | |||||
image.setImageBitmap(areaList.get(i).getImage()); | |||||
} | |||||
newNotice.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) | |||||
{ | |||||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||||
final View viewInflated = LayoutInflater.from(v.getRootView().getContext()).inflate(R.layout.area_management_notice, viewGroup, false); | |||||
newbuilder.setView(viewInflated); | |||||
final TextView noticeView = viewInflated.findViewById(R.id.areaManagementNoticeUserInput); | |||||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
areaList.get(i).setNotice(noticeView.getText().toString()); | |||||
notice.setText(areaList.get(i).getNotice()); | |||||
dialog.dismiss(); | |||||
} | |||||
}); | |||||
newbuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
newbuilder.show(); | |||||
}}); | |||||
builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.dismiss(); | |||||
} | |||||
}); | |||||
builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
builder.show(); | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
}); | }); | ||||
view.setOnLongClickListener(new View.OnLongClickListener() { | |||||
elementView.setOnLongClickListener(new View.OnLongClickListener() { | |||||
@Override | @Override | ||||
public boolean onLongClick(View v) { | public boolean onLongClick(View v) { | ||||
// TODO Auto-generated method stub | |||||
Toast toast = Toast.makeText(context, "on long click!", Toast.LENGTH_SHORT); | |||||
TextView tv = (TextView) toast.getView().findViewById(android.R.id.message); | |||||
if( v != null) | |||||
{ | |||||
//text align center | |||||
tv.setGravity(Gravity.CENTER); | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
}); | }); |
import android.Manifest; | import android.Manifest; | ||||
import android.annotation.SuppressLint; | import android.annotation.SuppressLint; | ||||
import android.app.AlertDialog; | import android.app.AlertDialog; | ||||
import android.content.ComponentName; | |||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.content.ServiceConnection; | |||||
import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||
import android.location.Location; | |||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.os.IBinder; | |||||
import android.os.PowerManager; | import android.os.PowerManager; | ||||
import android.preference.PreferenceManager; | import android.preference.PreferenceManager; | ||||
import android.util.Log; | import android.util.Log; | ||||
import android.widget.Toast; | import android.widget.Toast; | ||||
import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
import androidx.annotation.Nullable; | |||||
import androidx.core.app.ActivityCompat; | import androidx.core.app.ActivityCompat; | ||||
import androidx.core.content.ContextCompat; | import androidx.core.content.ContextCompat; | ||||
import androidx.fragment.app.Fragment; | import androidx.fragment.app.Fragment; | ||||
import androidx.lifecycle.Observer; | |||||
import com.example.meinwald.BuildConfig; | import com.example.meinwald.BuildConfig; | ||||
import com.example.meinwald.R; | import com.example.meinwald.R; | ||||
import com.example.meinwald.ui.task.TaskAdapter; | |||||
import com.example.meinwald.ui.task.TasksFragment; | |||||
import com.google.android.gms.location.FusedLocationProviderClient; | import com.google.android.gms.location.FusedLocationProviderClient; | ||||
import com.google.android.gms.location.LocationServices; | import com.google.android.gms.location.LocationServices; | ||||
import com.google.android.gms.maps.model.LatLng; | import com.google.android.gms.maps.model.LatLng; | ||||
import com.google.android.gms.tasks.OnCompleteListener; | |||||
import com.google.android.gms.tasks.Task; | |||||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
import org.json.JSONArray; | import org.json.JSONArray; | ||||
import org.json.JSONException; | import org.json.JSONException; | ||||
import org.json.JSONObject; | import org.json.JSONObject; | ||||
import org.json.JSONStringer; | |||||
import java.io.BufferedReader; | import java.io.BufferedReader; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||
import java.io.FileReader; | import java.io.FileReader; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | |||||
import java.io.InputStreamReader; | |||||
import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
public class AreaFragment extends Fragment { | public class AreaFragment extends Fragment { | ||||
private static final String TAG = TasksFragment.class.getSimpleName(); | |||||
private static final String TAG = AreaFragment.class.getSimpleName(); | |||||
/** | /** | ||||
* ______________________________________________________________________________________________ | * ______________________________________________________________________________________________ | ||||
PowerManager.WakeLock wakeLock; | PowerManager.WakeLock wakeLock; | ||||
LocationService gps; | LocationService gps; | ||||
@Override | |||||
public void onCreate (Bundle savedInstanceState) | |||||
{ | |||||
super.onCreate(savedInstanceState); | |||||
areaReferences = new ArrayList<>(); | |||||
areaReferences = readAreaReferencesFromPreferences(); | |||||
} | |||||
@SuppressLint("InvalidWakeLockTag") | @SuppressLint("InvalidWakeLockTag") | ||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||||
//instantiate area lists | //instantiate area lists | ||||
areaList = (ListView) root.findViewById(R.id.areaListView); | areaList = (ListView) root.findViewById(R.id.areaListView); | ||||
allAreas = new ArrayList<>(); | allAreas = new ArrayList<>(); | ||||
areaReferences = new ArrayList<>(); | |||||
//get saved areas | |||||
allAreas = loadAreasFromPreferences(); | |||||
instantiateAreasList(); | |||||
PowerManager powerManager = (PowerManager) getContext().getSystemService(POWER_SERVICE); | PowerManager powerManager = (PowerManager) getContext().getSystemService(POWER_SERVICE); | ||||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag"); | wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag"); | ||||
getLocationPermission(); | getLocationPermission(); | ||||
getWriteStoragePPermission(); | getWriteStoragePPermission(); | ||||
//get saved areas | |||||
areaReferences = readAreaReferencesFromPreferences(); | |||||
allAreas = loadAreasFromPreferences(); | |||||
instantiateAreasList(); | |||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | ||||
newArea = new OwnArea(); | newArea = new OwnArea(); | ||||
public void onClick(DialogInterface dialog, int which) { | public void onClick(DialogInterface dialog, int which) { | ||||
final TextView titleView = viewInflated.findViewById(R.id.areaTitleUserInput); | final TextView titleView = viewInflated.findViewById(R.id.areaTitleUserInput); | ||||
final TextView noticeView = viewInflated.findViewById(R.id.areaNoticeUserInput); | |||||
final TextView noticeView = viewInflated.findViewById(R.id.areaManagementNoticeUserInput); | |||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.d(TAG, "new title: " + titleView.getText()); | Log.d(TAG, "new title: " + titleView.getText()); | ||||
Log.d(TAG, "add new task result: " + result); | Log.d(TAG, "add new task result: " + result); | ||||
} | } | ||||
//stop tracking | |||||
//wakeLock.release(); | |||||
emptyPreferencesAndSaveAreaReferencesToPreferences(); | |||||
//save new area | |||||
allAreas.add(newArea); | |||||
writeAreaToExternalStorage(newArea); | |||||
areaReferences.add(new AreaReference(newArea.getId(), writeAreaToExternalStorage(newArea))); | |||||
//actuate list | //actuate list | ||||
instantiateAreasList(); | instantiateAreasList(); | ||||
@Override | @Override | ||||
public void onPause() { | public void onPause() { | ||||
//save area references to shared preferences | |||||
emptyPreferencesAndSaveEpiColorsToPreferences(); | |||||
super.onPause(); | super.onPause(); | ||||
//save area references to shared preferences | |||||
emptyPreferencesAndSaveAreaReferencesToPreferences(); | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
private List<OwnArea> loadAreasFromPreferences() | private List<OwnArea> loadAreasFromPreferences() | ||||
{ | { | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "loadAreasFromPreferences() reference size: " + areaReferences.size()); | |||||
} | |||||
List<OwnArea> areas = new ArrayList<>(); | List<OwnArea> areas = new ArrayList<>(); | ||||
Integer i = 0; | |||||
for (AreaReference reference: areaReferences) | for (AreaReference reference: areaReferences) | ||||
{ | { | ||||
String jsonString = readAreaFromExternalStorage(reference.getPath()); | String jsonString = readAreaFromExternalStorage(reference.getPath()); | ||||
areas.add(new OwnArea(jsonString)); | areas.add(new OwnArea(jsonString)); | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "load area from preferences: " + areas.get(i).toString()); | |||||
} | |||||
i++; | |||||
} | } | ||||
return areas; | return areas; | ||||
*/ | */ | ||||
private String writeAreaToExternalStorage(OwnArea newArea){ | private String writeAreaToExternalStorage(OwnArea newArea){ | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "writeAreaToExternalStorage()"); | |||||
} | |||||
// Find the root of the external storage. | // Find the root of the external storage. | ||||
File root = android.os.Environment.getExternalStorageDirectory(); | File root = android.os.Environment.getExternalStorageDirectory(); | ||||
//create file if it does not exist | //create file if it does not exist | ||||
File path = new File (root.getAbsolutePath() + "meinWald" + File.pathSeparator + "areas"); | |||||
File path = new File (getContext().getFilesDir(), "meinWald" + File.pathSeparator + "areas"); | |||||
if(!path.exists()){ | if(!path.exists()){ | ||||
path.mkdirs(); | path.mkdirs(); | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Create new text file: " + path); | |||||
} | |||||
} | } | ||||
File file = new File(path, newArea.getId() + ".txt"); | File file = new File(path, newArea.getId() + ".txt"); | ||||
pw.close(); | pw.close(); | ||||
f.close(); | f.close(); | ||||
} catch (FileNotFoundException e) { | } catch (FileNotFoundException e) { | ||||
e.printStackTrace(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "Failed write to external storage: " + e.toString()); | |||||
} | |||||
} catch (IOException e) { | } catch (IOException e) { | ||||
e.printStackTrace(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "Failed write to external storage: " + e.toString()); | |||||
} | |||||
} | } | ||||
return file.getPath(); | return file.getPath(); | ||||
*/ | */ | ||||
private String readAreaFromExternalStorage(String path) | private String readAreaFromExternalStorage(String path) | ||||
{ | { | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "readAreaFromExternalStorage()"); | |||||
} | |||||
//Get the text file | //Get the text file | ||||
File file = new File(path); | File file = new File(path); | ||||
br.close(); | br.close(); | ||||
} | } | ||||
catch (IOException e) { | catch (IOException e) { | ||||
e.printStackTrace(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "Failed read from external storage: " + e.toString()); | |||||
} | |||||
} | } | ||||
return text.toString(); | return text.toString(); | ||||
/** | /** | ||||
* Reads areaReferences saved in preferences as jsonStrings | * Reads areaReferences saved in preferences as jsonStrings | ||||
* | * | ||||
* @return list of epiColorDtos | |||||
* @return list of AreaReferences | |||||
*/ | */ | ||||
private List<AreaReference> readAreaReferencesFromPreferences() { | private List<AreaReference> readAreaReferencesFromPreferences() { | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "readAreaReferencesFromPreferences()"); | |||||
} | |||||
List<AreaReference> areas = new ArrayList<>(); | List<AreaReference> areas = new ArrayList<>(); | ||||
try { | try { | ||||
if(!"error".equalsIgnoreCase(jsonString)) { | if(!"error".equalsIgnoreCase(jsonString)) { | ||||
JSONArray jsonObjects = new JSONArray(jsonString); | JSONArray jsonObjects = new JSONArray(jsonString); | ||||
for (int i = 0; i<jsonObjects.length();i++) { | for (int i = 0; i<jsonObjects.length();i++) { | ||||
areaReferences.add(new AreaReference(jsonObjects.getJSONObject(i))); | |||||
areas.add(new AreaReference(jsonObjects.getJSONObject(i))); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "read area reference error"); | |||||
} | } | ||||
} | } | ||||
} catch (JSONException e) { | } catch (JSONException e) { | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.e(TAG, "Error while parsing epicolors as jsonObjects from preferences"); | |||||
Log.e(TAG, "Error while parsing area references as jsonObjects from preferences"); | |||||
e.printStackTrace(); | e.printStackTrace(); | ||||
} | } | ||||
} | } | ||||
for (AreaReference reference: areas) | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "read reference: " + reference.toString()); | |||||
} | |||||
} | |||||
return areas; | return areas; | ||||
} | } | ||||
/** | /** | ||||
* Saves epicolors to preferences | * Saves epicolors to preferences | ||||
*/ | */ | ||||
private void emptyPreferencesAndSaveEpiColorsToPreferences() | |||||
private void emptyPreferencesAndSaveAreaReferencesToPreferences() | |||||
{ | { | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "emptyPreferencesAndSaveAreaReferencesToPreferences()"); | |||||
} | |||||
if (!areaReferences.isEmpty()) { | if (!areaReferences.isEmpty()) { | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.d(TAG, "areaReferences not empty"); | Log.d(TAG, "areaReferences not empty"); | ||||
writeObjects.put(object); | writeObjects.put(object); | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.d("Color is ", object.toString()); | |||||
Log.d(TAG, "area reference is " + object.toString()); | |||||
} | } | ||||
} | } | ||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_AREA_REFERENCES, writeObjects.toString()).commit(); | PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_AREA_REFERENCES, writeObjects.toString()).commit(); | ||||
} | } | ||||
else | |||||
{ | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(TAG, "area references are empty!"); | |||||
} | |||||
} | |||||
} | } | ||||
/** | /** |
import com.example.meinwald.BuildConfig; | import com.example.meinwald.BuildConfig; | ||||
import com.google.android.gms.maps.model.LatLng; | import com.google.android.gms.maps.model.LatLng; | ||||
import org.json.JSONArray; | |||||
import org.json.JSONException; | import org.json.JSONException; | ||||
import org.json.JSONObject; | import org.json.JSONObject; | ||||
import java.sql.Time; | import java.sql.Time; | ||||
import java.util.ArrayList; | |||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.List; | import java.util.List; | ||||
private String pathImage; | private String pathImage; | ||||
private String pathLocations; | private String pathLocations; | ||||
private String id; | private String id; | ||||
private Date time; | |||||
public void setImage(Bitmap image) { | public void setImage(Bitmap image) { | ||||
this.image = image; | this.image = image; | ||||
this.title = areaObject.getString("title"); | this.title = areaObject.getString("title"); | ||||
this.notice = areaObject.getString("description"); | this.notice = areaObject.getString("description"); | ||||
this.id = areaObject.getString("id"); | this.id = areaObject.getString("id"); | ||||
this.time = new Date(areaObject.getString("time")); | |||||
String locationsString = areaObject.getString("locations"); | |||||
JSONArray locations = new JSONArray(locationsString); | |||||
this.locations = new ArrayList<>(); | |||||
for (int i = 0; i<locations.length();i++) { | |||||
this.locations.add(new LatLng((float) (locations.getJSONObject(i).getDouble("Lat")), (float) (locations.getJSONObject(i).getDouble("Lng")))); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "read location: " + this.locations.get(i).toString()); | |||||
} | |||||
} | |||||
} catch (JSONException e) { | } catch (JSONException e) { | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.e(this.getClass().getSimpleName(), "earthquakeJSON " + jsonString); | |||||
Log.e(this.getClass().getSimpleName(), "area json: " + jsonString); | |||||
Log.e(this.getClass().getSimpleName(), e.toString()); | |||||
e.printStackTrace(); | e.printStackTrace(); | ||||
} | } | ||||
} | } | ||||
object.put("description",this.notice); | object.put("description",this.notice); | ||||
object.put("id",this.id); | object.put("id",this.id); | ||||
if (this.time != null) | |||||
{ | |||||
object.put("time", this.time); | |||||
} | |||||
else | |||||
{ | |||||
object.put("time", new Date().getTime()); | |||||
} | |||||
//convert all locations | |||||
JSONArray writeObjects = new JSONArray(); | |||||
for (LatLng location: this.locations) { | |||||
JSONObject locations = new JSONObject(); | |||||
Long count = Long.valueOf(0); | |||||
JSONObject singleLocationObject = new JSONObject(); | |||||
singleLocationObject.put("Lat", location.latitude); | |||||
singleLocationObject.put("Lng", location.longitude); | |||||
//convert all locations | |||||
for (LatLng location: this.locations) | |||||
{ | |||||
JSONObject locationObject = new JSONObject(); | |||||
locationObject.put("Lat", location.latitude); | |||||
locationObject.put("Lng", location.longitude); | |||||
locations.put("location"+count, locationObject.toString()); | |||||
writeObjects.put(singleLocationObject); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("OwnArea", "added location object: " + singleLocationObject.toString()); | |||||
} | |||||
} | } | ||||
object.put("locations", locations.toString()); | |||||
object.put("locations", writeObjects.toString()); | |||||
return object; | return object; | ||||
package com.example.meinwald.ui.main.map; | |||||
package com.example.meinwald.ui.map; | |||||
import android.Manifest; | import android.Manifest; | ||||
import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||
import com.example.meinwald.BuildConfig; | import com.example.meinwald.BuildConfig; | ||||
import com.example.meinwald.R; | import com.example.meinwald.R; | ||||
import com.example.meinwald.ui.area.AreaReference; | |||||
import com.example.meinwald.ui.area.OwnArea; | |||||
import com.example.meinwald.ui.task.OwnTask; | import com.example.meinwald.ui.task.OwnTask; | ||||
import com.google.android.gms.dynamic.IObjectWrapper; | import com.google.android.gms.dynamic.IObjectWrapper; | ||||
import com.google.android.gms.location.FusedLocationProviderClient; | import com.google.android.gms.location.FusedLocationProviderClient; | ||||
import com.google.android.gms.maps.model.CameraPosition; | import com.google.android.gms.maps.model.CameraPosition; | ||||
import com.google.android.gms.maps.model.LatLng; | import com.google.android.gms.maps.model.LatLng; | ||||
import com.google.android.gms.maps.model.MarkerOptions; | import com.google.android.gms.maps.model.MarkerOptions; | ||||
import com.google.android.gms.maps.model.Polyline; | |||||
import com.google.android.gms.maps.model.PolylineOptions; | |||||
import com.google.android.gms.tasks.OnCompleteListener; | import com.google.android.gms.tasks.OnCompleteListener; | ||||
import com.google.android.gms.tasks.Task; | import com.google.android.gms.tasks.Task; | ||||
import org.json.JSONArray; | import org.json.JSONArray; | ||||
import org.json.JSONException; | import org.json.JSONException; | ||||
import java.io.BufferedReader; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileReader; | |||||
import java.io.IOException; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
private boolean mReadStorageGranted; | private boolean mReadStorageGranted; | ||||
private boolean mWriteStorageGranted; | private boolean mWriteStorageGranted; | ||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* AREA | |||||
*/ | |||||
private List<OwnArea> allAreas; | |||||
private static final String KEY_AREA_REFERENCES = "areaReferences"; | |||||
private List<AreaReference> areaReferences; | |||||
@Override | |||||
public void onCreate (Bundle savedInstanceState) | |||||
{ | |||||
super.onCreate(savedInstanceState); | |||||
areaReferences = new ArrayList<>(); | |||||
areaReferences = readAreaReferencesFromPreferences(); | |||||
} | |||||
/** | /** | ||||
* Is called when the MapsFragment view is created. Initializes all service connections, the location client and map itself. | * Is called when the MapsFragment view is created. Initializes all service connections, the location client and map itself. | ||||
* @param inflater Calling LayoutInflater | * @param inflater Calling LayoutInflater | ||||
//get tasks | //get tasks | ||||
allTasks = readTasksFromPreferences(); | allTasks = readTasksFromPreferences(); | ||||
//get areas | |||||
//instantiate area lists | |||||
allAreas = new ArrayList<>(); | |||||
//get saved areas | |||||
allAreas = loadAreasFromPreferences(); | |||||
//display map fragment | //display map fragment | ||||
SupportMapFragment mapFragment = new SupportMapFragment(); | SupportMapFragment mapFragment = new SupportMapFragment(); | ||||
FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); | FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); | ||||
super.onPause(); | super.onPause(); | ||||
} | } | ||||
private void drawAreas() | |||||
{ | |||||
for (OwnArea area: allAreas) | |||||
{ | |||||
PolylineOptions options = new PolylineOptions().clickable(true); | |||||
for (LatLng location: area.getLocations()) | |||||
{ | |||||
options.add(location); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Position: " + location.toString()); | |||||
} | |||||
} | |||||
Polyline polyline1 = mMap.addPolyline(options); | |||||
} | |||||
} | |||||
/** | |||||
* Reads areaReferences saved in preferences as jsonStrings | |||||
* | |||||
* @return list of AreaReferences | |||||
*/ | |||||
private List<AreaReference> readAreaReferencesFromPreferences() { | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "readAreaReferencesFromPreferences()"); | |||||
} | |||||
List<AreaReference> areas = new ArrayList<>(); | |||||
try { | |||||
String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_AREA_REFERENCES, "error"); | |||||
if(!"error".equalsIgnoreCase(jsonString)) { | |||||
JSONArray jsonObjects = new JSONArray(jsonString); | |||||
for (int i = 0; i<jsonObjects.length();i++) { | |||||
areas.add(new AreaReference(jsonObjects.getJSONObject(i))); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "read area reference error"); | |||||
} | |||||
} | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(TAG, "Error while parsing area references as jsonObjects from preferences"); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
for (AreaReference reference: areas) | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "read reference: " + reference.toString()); | |||||
} | |||||
} | |||||
return areas; | |||||
} | |||||
/** | |||||
* Get OwnAreas from a JSONString. | |||||
* @return | |||||
*/ | |||||
private List<OwnArea> loadAreasFromPreferences() | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "loadAreasFromPreferences() reference size: " + areaReferences.size()); | |||||
} | |||||
List<OwnArea> areas = new ArrayList<>(); | |||||
Integer i = 0; | |||||
for (AreaReference reference: areaReferences) | |||||
{ | |||||
String jsonString = readAreaFromExternalStorage(reference.getPath()); | |||||
areas.add(new OwnArea(jsonString)); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "load area from preferences: " + areas.get(i).toString()); | |||||
} | |||||
i++; | |||||
} | |||||
return areas; | |||||
} | |||||
/** | |||||
* Read OwnArea from file in external storage and return as a string. | |||||
* | |||||
* @param path File path where the OwnArea is saved. | |||||
* @return | |||||
*/ | |||||
private String readAreaFromExternalStorage(String path) | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "readAreaFromExternalStorage()"); | |||||
} | |||||
//Get the text file | |||||
File file = new File(path); | |||||
//Read text from file | |||||
StringBuilder text = new StringBuilder(); | |||||
try { | |||||
BufferedReader br = new BufferedReader(new FileReader(file)); | |||||
String line; | |||||
while ((line = br.readLine()) != null) { | |||||
text.append(line); | |||||
} | |||||
br.close(); | |||||
} | |||||
catch (IOException e) { | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "Failed read from external storage: " + e.toString()); | |||||
} | |||||
} | |||||
return text.toString(); | |||||
} | |||||
@Override | @Override | ||||
public void onResume() { | public void onResume() { | ||||
super.onResume(); | super.onResume(); | ||||
mMap.addMarker(marker); | mMap.addMarker(marker); | ||||
} | } | ||||
drawAreas(); | |||||
} | } | ||||
/** | /** |
* Saves tasks to preferences | * Saves tasks to preferences | ||||
*/ | */ | ||||
private void emptyPreferencesAndSaveTasksToPreferences() { | private void emptyPreferencesAndSaveTasksToPreferences() { | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "emptyPreferencesAndSaveTasksToPreferences()"); | |||||
} | |||||
if (!allTasks.isEmpty()) { | if (!allTasks.isEmpty()) { | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.d(TAG, "allTasks not empty!"); | Log.d(TAG, "allTasks not empty!"); |
<TextView | <TextView | ||||
android:id="@+id/areaInfoTitle" | android:id="@+id/areaInfoTitle" | ||||
android:layout_width="match_parent" | |||||
android:layout_height="30dp" | |||||
android:layout_width="375dp" | |||||
android:layout_height="32dp" | |||||
android:layout_gravity="left" | android:layout_gravity="left" | ||||
android:layout_marginStart="5dp" | android:layout_marginStart="5dp" | ||||
android:layout_marginLeft="5dp" | android:layout_marginLeft="5dp" | ||||
android:layout_marginTop="5dp" | android:layout_marginTop="5dp" | ||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:clickable="false" | android:clickable="false" | ||||
android:focusable="false" | |||||
android:duplicateParentState="true" | |||||
android:focusable="false" | |||||
android:textColor="@android:color/primary_text_light" | android:textColor="@android:color/primary_text_light" | ||||
android:textSize="22sp" | android:textSize="22sp" | ||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" /> | app:layout_constraintTop_toTopOf="parent" /> | ||||
<ImageView | |||||
android:id="@+id/areaManageArea" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:clickable="true" | |||||
android:duplicateParentState="true" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:src="@android:drawable/ic_menu_manage" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toTopOf="@+id/areaInfoView" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="0.0" | |||||
app:layout_constraintStart_toEndOf="@+id/areaInfoTitle" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | <androidx.constraintlayout.widget.ConstraintLayout | ||||
android:id="@+id/areaInfoView" | android:id="@+id/areaInfoView" | ||||
android:layout_width="0dp" | android:layout_width="0dp" | ||||
app:layout_constraintHorizontal_bias="1.0" | app:layout_constraintHorizontal_bias="1.0" | ||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toBottomOf="@+id/areaInfoTitle" | app:layout_constraintTop_toBottomOf="@+id/areaInfoTitle" | ||||
tools:visibility="visible"> | |||||
tools:visibility="visible" | |||||
android:duplicateParentState="true"> | |||||
<ImageView | <ImageView | ||||
app:layout_constraintBottom_toBottomOf="parent" | app:layout_constraintBottom_toBottomOf="parent" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
app:srcCompat="@android:drawable/ic_menu_camera" /> | |||||
app:srcCompat="@android:drawable/ic_menu_camera" | |||||
android:duplicateParentState="true"/> | |||||
<TextView | <TextView | ||||
android:id="@+id/areaInfoNotice" | android:id="@+id/areaInfoNotice" | ||||
android:visibility="visible" | android:visibility="visible" | ||||
app:layout_constraintEnd_toStartOf="@+id/taskIcon" | app:layout_constraintEnd_toStartOf="@+id/taskIcon" | ||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
android:duplicateParentState="true"/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||
</EditText> | </EditText> | ||||
<TextView | <TextView | ||||
android:id="@+id/areaNotice" | |||||
android:id="@+id/areaManagementNotice" | |||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:text="Beschreibung" | android:text="Beschreibung" | ||||
android:textAppearance="?android:attr/textAppearanceLarge" /> | android:textAppearance="?android:attr/textAppearanceLarge" /> | ||||
<EditText | <EditText | ||||
android:id="@+id/areaNoticeUserInput" | |||||
android:id="@+id/areaManagementNoticeUserInput" | |||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="149dp" | |||||
android:layout_height="150dp" | |||||
android:hint="Beschreibung eingeben!" | android:hint="Beschreibung eingeben!" | ||||
android:isScrollContainer="true"> | android:isScrollContainer="true"> | ||||
<requestFocus /> | <requestFocus /> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent"> | |||||
<TextView | |||||
android:id="@+id/areaManageTitle" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="50dp" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="5dp" | |||||
android:text="TextView" | |||||
android:textSize="36sp" | |||||
android:textStyle="bold" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<TextView | |||||
android:id="@+id/textView2" | |||||
android:layout_width="250dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="5dp" | |||||
android:text="Beschreibung" | |||||
android:textSize="18sp" | |||||
android:textStyle="bold" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaManageTitle" /> | |||||
<TextView | |||||
android:id="@+id/areaManageNotice" | |||||
android:layout_width="0dp" | |||||
android:layout_height="75dp" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:isScrollContainer="true" | |||||
android:textSize="12sp" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/textView2" /> | |||||
<TextView | |||||
android:id="@+id/textView4" | |||||
android:layout_width="250dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="15dp" | |||||
android:text="Anzahl GPS-Punkte" | |||||
android:textSize="18sp" | |||||
android:textStyle="bold" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaManageNotice" /> | |||||
<TextView | |||||
android:id="@+id/textView6" | |||||
android:layout_width="250dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="15dp" | |||||
android:text="Bild" | |||||
android:textSize="18sp" | |||||
android:textStyle="bold" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaManageGPSPoints" /> | |||||
<TextView | |||||
android:id="@+id/areaManageGPSPoints" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="30dp" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:textSize="12sp" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/textView4" /> | |||||
<ImageView | |||||
android:id="@+id/areaManageImage" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="200dp" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/textView6" | |||||
android:src="@android:drawable/ic_menu_gallery" | |||||
android:visibility="visible"/> | |||||
<ImageView | |||||
android:id="@+id/areaManageNewDescription" | |||||
android:layout_width="30dp" | |||||
android:layout_height="30dp" | |||||
app:tint="#1B5E20" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="@+id/areaManageNotice" | |||||
app:layout_constraintEnd_toEndOf="@+id/areaManageNotice" | |||||
android:src="@android:drawable/ic_popup_sync" /> | |||||
<ImageView | |||||
android:id="@+id/areaManageNewGPS" | |||||
android:layout_width="30dp" | |||||
android:layout_height="30dp" | |||||
app:tint="#1B5E20" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="@+id/areaManageGPSPoints" | |||||
app:layout_constraintEnd_toEndOf="@+id/areaManageGPSPoints" | |||||
android:src="@android:drawable/ic_popup_sync" /> | |||||
<ImageView | |||||
android:id="@+id/areaManageNewImage" | |||||
android:layout_width="30dp" | |||||
android:layout_height="30dp" | |||||
app:tint="#1B5E20" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="@+id/areaManageImage" | |||||
app:layout_constraintEnd_toEndOf="@+id/areaManageImage" | |||||
android:src="@android:drawable/ic_menu_camera" /> | |||||
<ImageView | |||||
android:id="@+id/areaManageDeleteArea" | |||||
android:layout_width="50dp" | |||||
android:layout_height="50dp" | |||||
android:layout_marginTop="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:src="@android:drawable/ic_menu_delete" | |||||
app:tint="#B71C1C" | |||||
android:visibility="visible" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
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="match_parent"> | |||||
<TextView | |||||
android:id="@+id/areaManagementNotice" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="5dp" | |||||
android:text="Neue Beschreibung" | |||||
android:textAppearance="?android:attr/textAppearanceLarge" | |||||
android:textStyle="bold" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<EditText | |||||
android:id="@+id/areaManagementNoticeUserInput" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="149dp" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:hint="Neue Beschreibung eingeben!" | |||||
android:isScrollContainer="true" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaManagementNotice"> | |||||
<requestFocus /> | |||||
</EditText> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
app:layout_constraintLeft_toLeftOf="parent" | app:layout_constraintLeft_toLeftOf="parent" | ||||
app:layout_constraintRight_toRightOf="parent" | app:layout_constraintRight_toRightOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
tools:context=".ui.home.MapsFragment"> | |||||
tools:context=".ui.map.MapsFragment"> | |||||
<fragment xmlns:android="http://schemas.android.com/apk/res/android" | <fragment xmlns:android="http://schemas.android.com/apk/res/android" | ||||
xmlns:map="http://schemas.android.com/apk/res-auto" | xmlns:map="http://schemas.android.com/apk/res-auto" |
<ImageView | <ImageView | ||||
android:id="@+id/taskLargeImage" | android:id="@+id/taskLargeImage" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | |||||
android:layout_height="575dp" | |||||
android:scaleType="fitXY" | android:scaleType="fitXY" | ||||
app:layout_constraintBottom_toBottomOf="parent" | app:layout_constraintBottom_toBottomOf="parent" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" |
<ImageView | <ImageView | ||||
android:id="@+id/taskImage" | android:id="@+id/taskImage" | ||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_width="100dp" | |||||
android:layout_height="200dp" | |||||
android:layout_gravity="center" | android:layout_gravity="center" | ||||
android:baselineAlignBottom="true" | android:baselineAlignBottom="true" | ||||
android:foregroundGravity="center_vertical|center_horizontal" | android:foregroundGravity="center_vertical|center_horizontal" |
<fragment | <fragment | ||||
android:id="@+id/navigation_map" | android:id="@+id/navigation_map" | ||||
android:name="com.example.meinwald.ui.main.map.MapsFragment" | |||||
android:name="com.example.meinwald.ui.map.MapsFragment" | |||||
android:label="@string/title_map" | android:label="@string/title_map" | ||||
tools:layout="@layout/fragment_map" /> | tools:layout="@layout/fragment_map" /> | ||||