testImplementation 'junit:junit:4.12' | testImplementation 'junit:junit:4.12' | ||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2' | androidTestImplementation 'androidx.test.ext:junit:1.1.2' | ||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' | ||||
compile 'com.google.maps.android:android-maps-utils:0.6.2' | |||||
} | } |
package="com.example.meinwald"> | package="com.example.meinwald"> | ||||
<application | <application | ||||
android:name="com.example.meinwald.MyApplication" | |||||
android:allowBackup="true" | android:allowBackup="true" | ||||
android:icon="@mipmap/ic_launcher" | android:icon="@mipmap/ic_launcher" | ||||
android:label="@string/app_name" | android:label="@string/app_name" | ||||
android:value="@string/google_maps_key" /> | android:value="@string/google_maps_key" /> | ||||
<service | <service | ||||
android:name=".ui.area.LocationTrack" | |||||
android:name=".ui.area.LocationService" | |||||
android:exported="false"> | android:exported="false"> | ||||
</service> | </service> | ||||
package com.example.meinwald; | |||||
import android.app.Application; | |||||
import android.content.Context; | |||||
public class MyApplication extends Application { | |||||
private static Context context; | |||||
public void onCreate() { | |||||
super.onCreate(); | |||||
MyApplication.context = getApplicationContext(); | |||||
} | |||||
public static Context getAppContext() { | |||||
return MyApplication.context; | |||||
} | |||||
} |
import android.app.AlertDialog; | import android.app.AlertDialog; | ||||
import android.content.Context; | import android.content.Context; | ||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.graphics.Rect; | |||||
import android.database.DataSetObserver; | |||||
import android.os.Build; | |||||
import android.util.Log; | import android.util.Log; | ||||
import android.view.Gravity; | import android.view.Gravity; | ||||
import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||
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.OwnTask; | |||||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Date; | |||||
import java.util.List; | import java.util.List; | ||||
import androidx.appcompat.widget.AlertDialogLayout; | |||||
import androidx.appcompat.widget.LinearLayoutCompat; | |||||
import androidx.annotation.RequiresApi; | |||||
import androidx.constraintlayout.widget.ConstraintLayout; | import androidx.constraintlayout.widget.ConstraintLayout; | ||||
import static java.security.AccessController.getContext; | |||||
public class AreaAdapter extends BaseAdapter | public class AreaAdapter extends BaseAdapter | ||||
{ | { | ||||
private final static String TAG = AreaAdapter.class.getSimpleName(); | |||||
List<OwnArea> areaList; | List<OwnArea> areaList; | ||||
LayoutInflater inflater; | LayoutInflater inflater; | ||||
Context context; | Context context; | ||||
boolean deleted = false; | |||||
Integer deletedPosition = null; | |||||
public AreaAdapter(Context applicationContext, List<OwnArea> areaList) | public AreaAdapter(Context applicationContext, List<OwnArea> areaList) | ||||
{ | { | ||||
} | } | ||||
@Override | @Override | ||||
public View getView(final int i, View view, final ViewGroup viewGroup) { | |||||
public View getView(final int i, final View view, final ViewGroup viewGroup) { | |||||
view = inflater.inflate(R.layout.area_element, null); | |||||
final ConstraintLayout elementView = view.findViewById(R.id.areaElement); | |||||
final ConstraintLayout infovView = view.findViewById(R.id.areaInfoView); | |||||
final TextView title = (TextView) view.findViewById(R.id.areaInfoTitle); | |||||
final TextView notice = (TextView) view.findViewById(R.id.areaInfoNotice); | |||||
final ImageView icon = (ImageView) view.findViewById(R.id.areaIcon); | |||||
final ImageView manageArea = (ImageView) view.findViewById(R.id.areaManageArea); | |||||
final View areaView = inflater.inflate(R.layout.area_element, null); | |||||
final ConstraintLayout elementView = areaView.findViewById(R.id.areaElement); | |||||
final ConstraintLayout infovView = areaView.findViewById(R.id.areaInfoView); | |||||
final TextView title = (TextView) areaView.findViewById(R.id.areaInfoTitle); | |||||
final TextView notice = (TextView) areaView.findViewById(R.id.areaInfoNotice); | |||||
final TextView area = (TextView) areaView.findViewById(R.id.areaInfoArea); | |||||
final ImageView icon = (ImageView) areaView.findViewById(R.id.areaIcon); | |||||
final ImageView manageArea = (ImageView) areaView.findViewById(R.id.areaManageArea); | |||||
context = view.getContext(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d("AreaAdapter",areaList.get(i).toString()); | |||||
Log.d("AreaAdapter",areaList.get(i).getTitle()); | |||||
Log.d("AreaAdapter",areaList.get(i).getNotice()); | |||||
} | |||||
context = areaView.getContext(); | |||||
title.setText(areaList.get(i).getTitle()); | title.setText(areaList.get(i).getTitle()); | ||||
notice.setText(areaList.get(i).getNotice()); | notice.setText(areaList.get(i).getNotice()); | ||||
icon.setImageBitmap(areaList.get(i).getImage()); | icon.setImageBitmap(areaList.get(i).getImage()); | ||||
if (areaList.get(i).getArea() != null) | |||||
{ | |||||
area.setText(String. format("%.2f", areaList.get(i).getArea()) + " Quadratmeter"); | |||||
} | |||||
manageArea.setOnClickListener(new View.OnClickListener() { | manageArea.setOnClickListener(new View.OnClickListener() { | ||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) | |||||
@Override | @Override | ||||
public void onClick(View v) | public void onClick(View v) | ||||
{ | { | ||||
final View viewInflated = LayoutInflater.from(v.getRootView().getContext()).inflate(R.layout.area_management, viewGroup, false); | final View viewInflated = LayoutInflater.from(v.getRootView().getContext()).inflate(R.layout.area_management, viewGroup, false); | ||||
builder.setView(viewInflated); | builder.setView(viewInflated); | ||||
builder.setCancelable(true); | |||||
//get elements | //get elements | ||||
TextView title = viewInflated.findViewById(R.id.areaManageTitle); | TextView title = viewInflated.findViewById(R.id.areaManageTitle); | ||||
final TextView notice = viewInflated.findViewById(R.id.areaManageNotice); | final TextView notice = viewInflated.findViewById(R.id.areaManageNotice); | ||||
TextView gpscount = viewInflated.findViewById(R.id.areaManageGPSPoints); | TextView gpscount = viewInflated.findViewById(R.id.areaManageGPSPoints); | ||||
ImageView image = (ImageView) viewInflated.findViewById(R.id.areaManageImage); | ImageView image = (ImageView) viewInflated.findViewById(R.id.areaManageImage); | ||||
final TextView lastChecked = viewInflated.findViewById(R.id.areaManagementLastChecked); | |||||
ImageView newNotice = (ImageView) viewInflated.findViewById(R.id.areaManageNewDescription); | ImageView newNotice = (ImageView) viewInflated.findViewById(R.id.areaManageNewDescription); | ||||
ImageView newGPS = (ImageView) viewInflated.findViewById(R.id.areaManageNewGPS); | ImageView newGPS = (ImageView) viewInflated.findViewById(R.id.areaManageNewGPS); | ||||
ImageView newImage = (ImageView) viewInflated.findViewById(R.id.areaManageNewImage); | ImageView newImage = (ImageView) viewInflated.findViewById(R.id.areaManageNewImage); | ||||
ImageView deleteArea = (ImageView) viewInflated.findViewById(R.id.areaManageDeleteArea); | ImageView deleteArea = (ImageView) viewInflated.findViewById(R.id.areaManageDeleteArea); | ||||
ImageView newDate = (ImageView) viewInflated.findViewById(R.id.areaManageNewDate); | |||||
//set current vlues | |||||
//set current values | |||||
title.setText(areaList.get(i).getTitle()); | title.setText(areaList.get(i).getTitle()); | ||||
notice.setText(areaList.get(i).getNotice()); | notice.setText(areaList.get(i).getNotice()); | ||||
gpscount.setText(String.valueOf(areaList.get(i).getLocations().size())); | |||||
if (areaList.get(i).getCheckHistory() != null) | |||||
{ | |||||
lastChecked.setText(areaList.get(i).parseAndFormatLastCheckUpdate()); | |||||
} | |||||
if (areaList.get(i).getLocations() != null) | |||||
{ | |||||
gpscount.setText(String.valueOf(areaList.get(i).getLocations().size())); | |||||
} | |||||
else | |||||
{ | |||||
gpscount.setText(String.valueOf(0)); | |||||
} | |||||
if (areaList.get(i).getImage() != null) | if (areaList.get(i).getImage() != null) | ||||
{ | { | ||||
newbuilder.setView(viewInflated); | newbuilder.setView(viewInflated); | ||||
final TextView noticeView = viewInflated.findViewById(R.id.areaManagementNoticeUserInput); | final TextView noticeView = viewInflated.findViewById(R.id.areaManagementNoticeUserInput); | ||||
noticeView.setText(areaList.get(i).getNotice()); | |||||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | ||||
@Override | @Override | ||||
newbuilder.show(); | newbuilder.show(); | ||||
}}); | }}); | ||||
newDate.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) { | |||||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||||
newbuilder.setTitle("Neu Kontrolle hinzufügen?"); | |||||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
areaList.get(i).addCheckDate(new Date()); | |||||
lastChecked.setText(areaList.get(i).parseAndFormatLastCheckUpdate()); | |||||
//notifyDataSetChanged(); | |||||
if (BuildConfig.DEBUG) { | |||||
for (OwnArea area : areaList) { | |||||
Log.d(TAG, "areaList item: " + area.toString()); | |||||
} | |||||
} | |||||
dialog.dismiss(); | |||||
} | |||||
}); | |||||
newbuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
newbuilder.show(); | |||||
}}); | |||||
deleteArea.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(final View v) { | |||||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||||
newbuilder.setTitle("Das Grundstück wirklich löschen?"); | |||||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
areaList.get(i).deleteFromExternalStorage(context); | |||||
areaList.remove(i); | |||||
notifyDataSetChanged(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
for (OwnArea area: areaList) | |||||
{ | |||||
Log.d(TAG, "areaList item: " + area.toString()); | |||||
} | |||||
} | |||||
dialog.dismiss(); | |||||
((ViewGroup)viewInflated.getParent()).removeView(viewInflated); | |||||
builder.show().cancel(); | |||||
} | |||||
}); | |||||
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() { | builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | ||||
@Override | @Override | ||||
public void onClick(DialogInterface dialog, int which) { | public void onClick(DialogInterface dialog, int which) { | ||||
if (areaList.size() > i && areaList.get(i) != null) | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "update area: " + areaList.get(i).toString()); | |||||
} | |||||
areaList.get(i).deleteFromExternalStorage(context); | |||||
areaList.get(i).writeToExternalStorage(context); | |||||
} | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
for (OwnArea area: areaList) | |||||
{ | |||||
Log.d(TAG, "areaList item: " + area.toString()); | |||||
} | |||||
} | |||||
dialog.dismiss(); | dialog.dismiss(); | ||||
} | } | ||||
}); | }); | ||||
} | } | ||||
}); | }); | ||||
return view; | |||||
return areaView; | |||||
} | |||||
public boolean isDeleted() { | |||||
return deleted; | |||||
} | |||||
public Integer getDeletedPosition() | |||||
{ | |||||
return deletedPosition; | |||||
} | } | ||||
@Override | @Override |
import android.app.AlertDialog; | import android.app.AlertDialog; | ||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||
import android.database.DataSetObserver; | |||||
import android.location.Location; | |||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.os.PowerManager; | import android.os.PowerManager; | ||||
import android.preference.PreferenceManager; | import android.preference.PreferenceManager; | ||||
import com.example.meinwald.R; | import com.example.meinwald.R; | ||||
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.CameraUpdateFactory; | |||||
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; | ||||
* LOCATION | * LOCATION | ||||
*/ | */ | ||||
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; | private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; | ||||
/** | |||||
* The geographical location where the device is currently located. | |||||
* That is the last-known location retrieved by the Fused Location Provider. | |||||
*/ | |||||
private Location mLastKnownLocation; | |||||
/** | /** | ||||
* The entry point to the Fused Location Provider. | * The entry point to the Fused Location Provider. | ||||
*/ | */ | ||||
//get saved areas | //get saved areas | ||||
allAreas = loadAreasFromPreferences(); | allAreas = loadAreasFromPreferences(); | ||||
for (int i = 0; i < allAreas.size(); i++) | |||||
{ | |||||
allAreas.get(i).setPathFile(areaReferences.get(i).getPath()); | |||||
} | |||||
instantiateAreasList(); | instantiateAreasList(); | ||||
PowerManager powerManager = (PowerManager) getContext().getSystemService(POWER_SERVICE); | PowerManager powerManager = (PowerManager) getContext().getSystemService(POWER_SERVICE); | ||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | ||||
newArea = new OwnArea(); | newArea = new OwnArea(); | ||||
newPositions = new ArrayList<>(); | |||||
final View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.area_input, (ViewGroup) getView(), false); | final View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.area_input, (ViewGroup) getView(), false); | ||||
builder.setView(viewInflated); | builder.setView(viewInflated); | ||||
final Button startTracking = viewInflated.findViewById(R.id.areaStartTracking); | final Button startTracking = viewInflated.findViewById(R.id.areaStartTracking); | ||||
final Button stopTracking = viewInflated.findViewById(R.id.areaStopTracking); | final Button stopTracking = viewInflated.findViewById(R.id.areaStopTracking); | ||||
final Button addLocation = viewInflated.findViewById(R.id.areaAddGPSPoint); | |||||
startTracking.setOnClickListener(new View.OnClickListener() { | startTracking.setOnClickListener(new View.OnClickListener() { | ||||
@Override | @Override | ||||
startTracking.setVisibility(View.INVISIBLE); | startTracking.setVisibility(View.INVISIBLE); | ||||
stopTracking.setVisibility(View.VISIBLE); | stopTracking.setVisibility(View.VISIBLE); | ||||
addLocation.setVisibility(View.INVISIBLE); | |||||
} | } | ||||
}); | }); | ||||
public void onClick(View view) { | public void onClick(View view) { | ||||
//stop tracking | //stop tracking | ||||
newPositions = gps.getPositions(); | |||||
List<LatLng> positionsToAdd = new ArrayList<>(); | |||||
positionsToAdd = gps.getPositions(); | |||||
for (LatLng pos: positionsToAdd) | |||||
{ | |||||
newPositions.add(pos); | |||||
} | |||||
if (BuildConfig.DEBUG) | if (BuildConfig.DEBUG) | ||||
{ | { | ||||
Log.d(TAG, "Received locations: " + newPositions.size()); | Log.d(TAG, "Received locations: " + newPositions.size()); | ||||
} | } | ||||
newArea.setLocations(newPositions); | |||||
wakeLock.release(); | wakeLock.release(); | ||||
startTracking.setVisibility(View.VISIBLE); | startTracking.setVisibility(View.VISIBLE); | ||||
stopTracking.setVisibility(View.INVISIBLE); | stopTracking.setVisibility(View.INVISIBLE); | ||||
addLocation.setVisibility(View.VISIBLE); | |||||
} | } | ||||
}); | }); | ||||
addLocation.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View view) { | |||||
//get last known location | |||||
getDeviceLocation(); | |||||
}}); | |||||
builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | ||||
@Override | @Override | ||||
public void onClick(DialogInterface dialog, int which) { | public void onClick(DialogInterface dialog, int which) { | ||||
//save user input | //save user input | ||||
newArea.setTitle(String.valueOf(titleView.getText())); | newArea.setTitle(String.valueOf(titleView.getText())); | ||||
newArea.setNotice(String.valueOf(noticeView.getText())); | newArea.setNotice(String.valueOf(noticeView.getText())); | ||||
newArea.setLocations(newPositions); | |||||
newArea.calculateArea(); | |||||
boolean result = allAreas.add(newArea); | boolean result = allAreas.add(newArea); | ||||
Log.d(TAG, "add new task result: " + result); | Log.d(TAG, "add new task result: " + result); | ||||
} | } | ||||
emptyPreferencesAndSaveAreaReferencesToPreferences(); | |||||
newArea.writeToExternalStorage(getContext()); | |||||
areaReferences.add(new AreaReference(newArea.getId(), newArea.getPathFile())); | |||||
areaReferences.add(new AreaReference(newArea.getId(), writeAreaToExternalStorage(newArea))); | |||||
emptyPreferencesAndSaveAreaReferencesToPreferences(); | |||||
//actuate list | //actuate list | ||||
instantiateAreasList(); | instantiateAreasList(); | ||||
builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | ||||
@Override | @Override | ||||
public void onClick(DialogInterface dialog, int which) { | |||||
public void onClick(DialogInterface dialog, int which) | |||||
{ | |||||
//reset variables | |||||
newArea = new OwnArea(); | |||||
newPositions = new ArrayList<>(); | |||||
dialog.cancel(); | dialog.cancel(); | ||||
} | } | ||||
}); | }); | ||||
public void instantiateAreasList() | public void instantiateAreasList() | ||||
{ | { | ||||
final AreaAdapter adapter = new AreaAdapter(getActivity().getApplicationContext(), allAreas); | final AreaAdapter adapter = new AreaAdapter(getActivity().getApplicationContext(), allAreas); | ||||
adapter.registerDataSetObserver(new DataSetObserver() { | |||||
@Override | |||||
public void onChanged() { | |||||
super.onChanged(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "onChanged"); | |||||
} | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "dataset size: " + areaList.getAdapter().getCount()); | |||||
} | |||||
if (areaList.getAdapter().getCount() > 0) | |||||
{ | |||||
allAreas = new ArrayList<>(); | |||||
areaReferences =new ArrayList<>(); | |||||
for (int i = 0; i < areaList.getAdapter().getCount(); i++) | |||||
{ | |||||
allAreas.add((OwnArea) areaList.getAdapter().getItem(i)); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "dataset added: " + allAreas.get(i).toString()); | |||||
} | |||||
areaReferences.add(new AreaReference(allAreas.get(i).getId(), allAreas.get(i).getPathFile())); | |||||
} | |||||
} | |||||
} | |||||
}); | |||||
areaList.setAdapter(adapter); | areaList.setAdapter(adapter); | ||||
//initialise onClickListeners | //initialise onClickListeners | ||||
return areas; | return areas; | ||||
} | } | ||||
/** | |||||
* Save OwnArea object in textfile on external storage. | |||||
* | |||||
* @param newArea OwnArea object to write to file. | |||||
* @return | |||||
*/ | |||||
private String writeAreaToExternalStorage(OwnArea newArea){ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "writeAreaToExternalStorage()"); | |||||
} | |||||
// Find the root of the external storage. | |||||
File root = android.os.Environment.getExternalStorageDirectory(); | |||||
//create file if it does not exist | |||||
File path = new File (getContext().getFilesDir(), "meinWald" + File.pathSeparator + "areas"); | |||||
if(!path.exists()){ | |||||
path.mkdirs(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Create new text file: " + path); | |||||
} | |||||
} | |||||
File file = new File(path, newArea.getId() + ".txt"); | |||||
//open file and write to it | |||||
try { | |||||
FileOutputStream f = new FileOutputStream(file); | |||||
PrintWriter pw = new PrintWriter(f); | |||||
pw.print(areaToString(newArea)); | |||||
pw.close(); | |||||
f.close(); | |||||
} catch (FileNotFoundException e) { | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "Failed write to external storage: " + e.toString()); | |||||
} | |||||
} catch (IOException e) { | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(TAG, "Failed write to external storage: " + e.toString()); | |||||
} | |||||
} | |||||
return file.getPath(); | |||||
} | |||||
/** | /** | ||||
* Read OwnArea from file in external storage and return as a string. | * Read OwnArea from file in external storage and return as a string. | ||||
* | * | ||||
while ((line = br.readLine()) != null) { | while ((line = br.readLine()) != null) { | ||||
text.append(line); | text.append(line); | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Line: " + line); | |||||
} | |||||
} | } | ||||
br.close(); | br.close(); | ||||
} | } | ||||
String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_AREA_REFERENCES, "error"); | String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_AREA_REFERENCES, "error"); | ||||
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++) | |||||
{ | |||||
areas.add(new AreaReference(jsonObjects.getJSONObject(i))); | areas.add(new AreaReference(jsonObjects.getJSONObject(i))); | ||||
// Find the root of the external storage. | |||||
File root = android.os.Environment.getExternalStorageDirectory(); | |||||
//delete reference if file does not exist | |||||
File file = new File(getContext().getFilesDir(), "meinWald" + File.pathSeparator + "areas" + File.pathSeparator + areas.get(i).getId() + ".txt"); | |||||
if(file.exists()) | |||||
{ | |||||
areas.remove(i); | |||||
} | |||||
} | } | ||||
} | } | ||||
else | else | ||||
} | } | ||||
/** | /** | ||||
* Saves epicolors to preferences | |||||
* Saves areas to preferences | |||||
*/ | */ | ||||
private void emptyPreferencesAndSaveAreaReferencesToPreferences() | private void emptyPreferencesAndSaveAreaReferencesToPreferences() | ||||
{ | { | ||||
} | } | ||||
/** | |||||
* Get the best and most recent location of the device, which may be null in rare | |||||
* cases when a location is not available. | |||||
* | |||||
*/ | |||||
private void getDeviceLocation() { | |||||
try { | |||||
if (mLocationPermissionGranted) { | |||||
Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation(); | |||||
locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener<Location>() { | |||||
@Override | |||||
public void onComplete(@NonNull Task<Location> task) { | |||||
if (task.isSuccessful()) | |||||
{ | |||||
// Set the last known position to the current location of the device and add to tracking stack | |||||
mLastKnownLocation = task.getResult(); | |||||
newPositions.add(new LatLng(mLastKnownLocation.getLatitude(),mLastKnownLocation.getLongitude())); | |||||
if (BuildConfig.DEBUG) { | |||||
if (task.getResult() != null) | |||||
{ | |||||
Log.d(TAG, "getDeviceLocation: " + task.getResult().toString()); | |||||
Log.d(TAG, "Size: " + newPositions.size()); | |||||
} | |||||
} | |||||
} else { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "Current location is null. Using defaults."); | |||||
Log.e(TAG, "Exception: %s", task.getException()); | |||||
} | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
} catch (SecurityException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(TAG, "Exception occurred: "); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
public void startLocationTracking(){ | public void startLocationTracking(){ | ||||
final Runnable runnable= new Runnable() { | final Runnable runnable= new Runnable() { |
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 5 meters | private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 5 meters | ||||
// The minimum time between updates in milliseconds | // The minimum time between updates in milliseconds | ||||
private static final long MIN_TIME_BW_UPDATES = 1000 * 5 * 1; // 5 seconds | |||||
private static final long MIN_TIME_BW_UPDATES = 1000 * 1 * 1; // 5 seconds | |||||
// Declaring a Location Manager | // Declaring a Location Manager | ||||
protected LocationManager mLocationManager; | protected LocationManager mLocationManager; | ||||
Log.d(TAG, "onLocationChanged(), new location: " + location.toString()); | Log.d(TAG, "onLocationChanged(), new location: " + location.toString()); | ||||
} | } | ||||
positions.add(new LatLng(location.getLatitude(), getLongitude())); | |||||
positions.add(new LatLng(location.getLatitude(), location.getLongitude())); | |||||
} | } | ||||
@Override | @Override |
package com.example.meinwald.ui.area; | package com.example.meinwald.ui.area; | ||||
import android.content.Context; | |||||
import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||
import android.location.Location; | |||||
import android.util.Log; | import android.util.Log; | ||||
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 com.google.maps.android.SphericalUtil; | |||||
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 java.sql.Time; | |||||
import java.io.File; | |||||
import java.io.FileNotFoundException; | |||||
import java.io.FileOutputStream; | |||||
import java.io.IOException; | |||||
import java.io.PrintWriter; | |||||
import java.text.SimpleDateFormat; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Calendar; | |||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.List; | import java.util.List; | ||||
private List<LatLng> locations; | private List<LatLng> locations; | ||||
private Bitmap image; | private Bitmap image; | ||||
private String pathImage; | private String pathImage; | ||||
private String pathLocations; | |||||
private String pathFile; | |||||
private String id; | private String id; | ||||
private List<Date> checkHistory; | |||||
private Double area; | |||||
public void setImage(Bitmap image) { | public void setImage(Bitmap image) { | ||||
this.image = image; | this.image = image; | ||||
this.pathImage = pathImage; | this.pathImage = pathImage; | ||||
} | } | ||||
public void setPathLocations(String pathLocations) { | |||||
this.pathLocations = pathLocations; | |||||
public void setPathFile(String pathFile) { | |||||
this.pathFile = pathFile; | |||||
} | |||||
public Double getArea() { | |||||
return area; | |||||
} | |||||
public void setArea(Double area) { | |||||
this.area = area; | |||||
} | |||||
public void calculateArea() | |||||
{ | |||||
this.area = SphericalUtil.computeArea(this.locations); | |||||
} | } | ||||
public String getNotice() { | public String getNotice() { | ||||
return pathImage; | return pathImage; | ||||
} | } | ||||
public String getPathLocations() { | |||||
return pathLocations; | |||||
public String getPathFile() { | |||||
return pathFile; | |||||
} | } | ||||
public OwnArea() | |||||
public List<Date> getCheckHistory() { | |||||
return checkHistory; | |||||
} | |||||
public void setCheckHistory(List<Date> checkHistory) { | |||||
this.checkHistory = checkHistory; | |||||
} | |||||
public void addCheckDate(Date newDate) | |||||
{ | { | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "add DATE"); | |||||
} | |||||
if(this.checkHistory == null) | |||||
{ | |||||
this.checkHistory = new ArrayList<>(); | |||||
} | |||||
this.checkHistory.add(newDate); | |||||
} | |||||
public OwnArea() | |||||
{ | |||||
this.title = null; | |||||
this.id = null; | |||||
this.notice = null; | |||||
this.pathFile = null; | |||||
this.image = null; | |||||
this.pathImage = null; | |||||
this.locations = new ArrayList<>(); | |||||
this.checkHistory = new ArrayList<>(); | |||||
} | } | ||||
public OwnArea(String jsonString){ | |||||
public OwnArea(String jsonString) | |||||
{ | |||||
this.checkHistory = new ArrayList<>(); | |||||
this.locations = new ArrayList<>(); | |||||
try { | try { | ||||
JSONObject areaObject = new JSONObject(jsonString); | JSONObject areaObject = new JSONObject(jsonString); | ||||
this.title = areaObject.getString("title"); | this.title = areaObject.getString("title"); | ||||
} | } | ||||
} | } | ||||
String historyString = areaObject.getString("history"); | |||||
JSONArray history = new JSONArray(historyString); | |||||
this.checkHistory = new ArrayList<>(); | |||||
for (int i = 0; i<history.length();i++) { | |||||
this.checkHistory.add(new Date(history.getJSONObject(i).getLong("date"))); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "read location: " + this.checkHistory.get(i).toString()); | |||||
} | |||||
} | |||||
if (this.locations != null && this.locations.size()>2) | |||||
{ | |||||
calculateArea(); | |||||
} | |||||
} catch (JSONException e) { | } catch (JSONException e) { | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.e(this.getClass().getSimpleName(), "area json: " + jsonString); | Log.e(this.getClass().getSimpleName(), "area json: " + jsonString); | ||||
return id; | return id; | ||||
} | } | ||||
/** | |||||
* Save OwnArea object in textfile on external storage. | |||||
* | |||||
* @return | |||||
*/ | |||||
public void writeToExternalStorage(Context context){ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "writeAreaToExternalStorage()"); | |||||
} | |||||
// Find the root of the external storage. | |||||
File root = android.os.Environment.getExternalStorageDirectory(); | |||||
//create file if it does not exist | |||||
File path = new File (context.getFilesDir(), "meinWald" + File.pathSeparator + "areas"); | |||||
if(!path.exists()){ | |||||
path.mkdirs(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "Create new text file: " + path); | |||||
} | |||||
} | |||||
File file = new File(path, this.getId() + ".txt"); | |||||
//open file and write to it | |||||
try { | |||||
FileOutputStream f = new FileOutputStream(file); | |||||
PrintWriter pw = new PrintWriter(f); | |||||
pw.print(this.toJSONObject()); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "Json to write in file: " + this.toJSONObject().toString()); | |||||
} | |||||
pw.close(); | |||||
f.close(); | |||||
} catch (FileNotFoundException e) { | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(getClass().getSimpleName(), "Failed write to external storage: " + e.toString()); | |||||
} | |||||
} catch (IOException e) { | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.e(getClass().getSimpleName(), "Failed write to external storage: " + e.toString()); | |||||
} | |||||
} | |||||
this.pathFile = file.getPath(); | |||||
} | |||||
/** | |||||
* Delete OwnArea object textfile from external storage. | |||||
*/ | |||||
public void deleteFromExternalStorage(Context context) | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "deleteFromExternalStorage()"); | |||||
} | |||||
// Find the root of the external storage. | |||||
File root = android.os.Environment.getExternalStorageDirectory(); | |||||
//delete file if exists | |||||
File file = new File(context.getFilesDir(), "meinWald" + File.pathSeparator + "areas" + File.pathSeparator + this.getId() + ".txt"); | |||||
if(!file.exists()){ | |||||
file.delete(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "Delete text file: " + file.getPath()); | |||||
} | |||||
} | |||||
} | |||||
/** | /** | ||||
* Returns OwnArea as JSONObject. | * Returns OwnArea as JSONObject. | ||||
//convert all locations | //convert all locations | ||||
JSONArray writeObjects = new JSONArray(); | JSONArray writeObjects = new JSONArray(); | ||||
for (LatLng location: this.locations) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("OwnArea", "Save locations, locations size: " + locations.size()); | |||||
} | |||||
JSONObject singleLocationObject = new JSONObject(); | |||||
singleLocationObject.put("Lat", location.latitude); | |||||
singleLocationObject.put("Lng", location.longitude); | |||||
if (this.locations != null && this.locations.size() > 0) | |||||
{ | |||||
for (LatLng location: this.locations) { | |||||
writeObjects.put(singleLocationObject); | |||||
JSONObject singleLocationObject = new JSONObject(); | |||||
singleLocationObject.put("Lat", location.latitude); | |||||
singleLocationObject.put("Lng", location.longitude); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("OwnArea", "added location object: " + singleLocationObject.toString()); | |||||
writeObjects.put(singleLocationObject); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("OwnArea", "added location object: " + singleLocationObject.toString()); | |||||
} | |||||
} | } | ||||
} | } | ||||
object.put("locations", writeObjects.toString()); | object.put("locations", writeObjects.toString()); | ||||
//convert all locations | |||||
writeObjects = new JSONArray(); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("OwnArea", "Save history, history size: " + checkHistory.size()); | |||||
} | |||||
if (this.checkHistory != null && this.checkHistory.size() > 0) | |||||
{ | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("OwnArea", "history not empty"); | |||||
} | |||||
for (Date date : this.checkHistory) { | |||||
JSONObject singleHistoryObject = new JSONObject(); | |||||
singleHistoryObject.put("date", date.getTime()); | |||||
writeObjects.put(singleHistoryObject); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("OwnArea", "added history object: " + singleHistoryObject.toString()); | |||||
} | |||||
} | |||||
} | |||||
object.put("history", writeObjects.toString()); | |||||
if (area!=null) | |||||
{ | |||||
object.put("area",this.area); | |||||
} | |||||
else | |||||
{ | |||||
object.put("area", null); | |||||
} | |||||
return object; | return object; | ||||
} catch (JSONException e) { | } catch (JSONException e) { | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
Log.e(this.getClass().getSimpleName(), | Log.e(this.getClass().getSimpleName(), | ||||
String.format("Error while parsing epiColorDto to JSONObject. Values of epiColorDto: %s", this.toString())); | |||||
String.format("Error while parsing OwnArea to JSONObject. Values of OwnArea: %s", this.toString())); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
"title='" + title + '\'' + | "title='" + title + '\'' + | ||||
", notice='" + notice + '\'' + | ", notice='" + notice + '\'' + | ||||
", pathImage='" + pathImage + '\'' + | ", pathImage='" + pathImage + '\'' + | ||||
", pathLocations='" + pathLocations + '\'' + | |||||
", pathLocations='" + pathFile + '\'' + | |||||
", id='" + id + '\'' + | ", id='" + id + '\'' + | ||||
", dates='" + checkHistory.size() + '\'' + | |||||
'}'; | '}'; | ||||
} | } | ||||
/** | |||||
* Parses last check update from milliseconds to string and formats it to "dd.MM.yyyy hh:mm". | |||||
* | |||||
* @return date parsed and mapped as string representation | |||||
*/ | |||||
public String parseAndFormatLastCheckUpdate() { | |||||
SimpleDateFormat formatter = new SimpleDateFormat( "dd.MM.yyyy kk:mm"); | |||||
Calendar calendar = Calendar.getInstance(); | |||||
if (checkHistory != null && checkHistory.size()> 0) | |||||
{ | |||||
calendar.setTimeInMillis(this.checkHistory.get(this.checkHistory.size()-1).getTime()); | |||||
} | |||||
else | |||||
{ | |||||
return "Keine Kontrolle vorhanden!"; | |||||
} | |||||
return formatter.format(calendar.getTime()); | |||||
} | |||||
public Long getLastChecked() | |||||
{ | |||||
if (checkHistory != null && checkHistory.size()> 0) | |||||
{ | |||||
return this.checkHistory.get(this.checkHistory.size()-1).getTime(); | |||||
} | |||||
else | |||||
{ | |||||
return (long) -1; | |||||
} | |||||
} | |||||
} | } |
import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||
import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||
import android.graphics.BitmapFactory; | import android.graphics.BitmapFactory; | ||||
import android.graphics.Color; | |||||
import android.location.Location; | import android.location.Location; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.os.IBinder; | import android.os.IBinder; | ||||
import android.view.View; | import android.view.View; | ||||
import android.view.ViewGroup; | import android.view.ViewGroup; | ||||
import android.widget.ListView; | import android.widget.ListView; | ||||
import android.widget.Toast; | |||||
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.AreaReference; | ||||
import com.example.meinwald.ui.area.OwnArea; | 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.common.util.Hex; | |||||
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.location.LocationServices; | import com.google.android.gms.location.LocationServices; | ||||
import com.google.android.gms.maps.model.BitmapDescriptor; | import com.google.android.gms.maps.model.BitmapDescriptor; | ||||
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.Marker; | |||||
import com.google.android.gms.maps.model.MarkerOptions; | import com.google.android.gms.maps.model.MarkerOptions; | ||||
import com.google.android.gms.maps.model.Polygon; | |||||
import com.google.android.gms.maps.model.PolygonOptions; | |||||
import com.google.android.gms.maps.model.Polyline; | import com.google.android.gms.maps.model.Polyline; | ||||
import com.google.android.gms.maps.model.PolylineOptions; | 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 com.google.maps.android.SphericalUtil; | |||||
import org.json.JSONArray; | import org.json.JSONArray; | ||||
import org.json.JSONException; | import org.json.JSONException; | ||||
import java.io.FileReader; | import java.io.FileReader; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Date; | |||||
import java.util.List; | import java.util.List; | ||||
import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity()); | mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity()); | ||||
//wait for map is ready | //wait for map is ready | ||||
mapFragment.getMapAsync(new OnMapReadyCallback() { | |||||
mapFragment.getMapAsync(new OnMapReadyCallback() | |||||
{ | |||||
@Override | @Override | ||||
public void onMapReady(GoogleMap googleMap) { | public void onMapReady(GoogleMap googleMap) { | ||||
//save map instance locally | //save map instance locally | ||||
mMap = googleMap; | mMap = googleMap; | ||||
//set max zoom level | //set max zoom level | ||||
mMap.setMaxZoomPreference(MAX_ZOOM); | mMap.setMaxZoomPreference(MAX_ZOOM); | ||||
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); | |||||
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { | |||||
@Override | |||||
public boolean onMarkerClick(Marker marker) { | |||||
if (mMap.getCameraPosition().zoom < 17.5) | |||||
{ | |||||
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(marker.getPosition().latitude, marker.getPosition().longitude),(float)17.5)); | |||||
} | |||||
else | |||||
{ | |||||
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(marker.getPosition().latitude, marker.getPosition().longitude),mMap.getCameraPosition().zoom)); | |||||
} | |||||
return false; | |||||
} | |||||
}); | |||||
//retrieve saved instance state | //retrieve saved instance state | ||||
mCameraPosition = parseCameraPosition(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_CAMERA_POSITION, new CameraPosition(new LatLng(45.0,11.0), (float) 1.0, (float) 0.0,(float) 0.0).toString())); | mCameraPosition = parseCameraPosition(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_CAMERA_POSITION, new CameraPosition(new LatLng(45.0,11.0), (float) 1.0, (float) 0.0,(float) 0.0).toString())); | ||||
{ | { | ||||
for (OwnArea area: allAreas) | for (OwnArea area: allAreas) | ||||
{ | { | ||||
PolylineOptions options = new PolylineOptions().clickable(true); | |||||
for (LatLng location: area.getLocations()) | |||||
if (area.getLocations() != null && area.getLocations().size()>0) | |||||
{ | { | ||||
options.add(location); | |||||
PolygonOptions options = new PolygonOptions().clickable(true); | |||||
if (BuildConfig.DEBUG) | if (BuildConfig.DEBUG) | ||||
{ | { | ||||
Log.d(TAG, "Position: " + location.toString()); | |||||
Log.d(TAG, "Color: " + getAreaColor(area.getLastChecked())); | |||||
Log.d(TAG, "Color: " + String.valueOf(getAreaColor(area.getLastChecked() & 0x00FFFFFF) | 0x60000000)); | |||||
Log.d(TAG, "Area: " + SphericalUtil.computeArea(area.getLocations())); | |||||
} | |||||
options.strokeColor(getAreaColor(area.getLastChecked())); | |||||
options.fillColor((options.getStrokeColor() & 0x00FFFFFF) | 0x60000000); | |||||
for (LatLng location: area.getLocations()) | |||||
{ | |||||
options.add(location); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Position: " + location.toString()); | |||||
} | |||||
} | } | ||||
} | |||||
Polyline polyline1 = mMap.addPolyline(options); | |||||
options.add(area.getLocations().get(0)); | |||||
mMap.addPolygon(options); | |||||
} | |||||
} | } | ||||
} | } | ||||
drawAreas(); | drawAreas(); | ||||
} | } | ||||
/** | |||||
* Decides color of area based on the time passed since last ckeck update. | |||||
* | |||||
* @param time difference in milliseconds between last check and now | |||||
* @return color number | |||||
*/ | |||||
private int getAreaColor(long time) { | |||||
//set transparency related to time difference | |||||
if(time > -1) | |||||
{ | |||||
long timeDiff = new Date().getTime() - time; | |||||
//less than a week | |||||
if (timeDiff < 7*24*60*60*1000L) | |||||
{ | |||||
return Color.parseColor("#57a639"); | |||||
} | |||||
//less than two weeks | |||||
else if (timeDiff < 14*24*60*60*1000L) | |||||
{ | |||||
return Color.parseColor("#819b45"); | |||||
} | |||||
//less than three weeks | |||||
else if (timeDiff < 21*24*60*60*1000L) | |||||
{ | |||||
return Color.parseColor("#d3d30c"); | |||||
} | |||||
//less than four weeks | |||||
else if (timeDiff < 28*24*60*60*1000L) | |||||
{ | |||||
return Color.parseColor("#df9600"); | |||||
} | |||||
//less than 6 weeks | |||||
else if (timeDiff < 42*24*60*60*1000L) | |||||
{ | |||||
return Color.parseColor("#df3d00"); | |||||
} | |||||
//longer than four weeks | |||||
else | |||||
{ | |||||
return Color.parseColor("#f70000"); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
return Color.parseColor("#f70000"); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Request read external storage permission, so that we can get saved images from external storage. | * Request read external storage permission, so that we can get saved images from external storage. | ||||
* The result of the permission request is handled by a callback, | * The result of the permission request is handled by a callback, |
package com.example.meinwald.ui.task; | package com.example.meinwald.ui.task; | ||||
import android.content.Context; | |||||
import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||
import android.location.Location; | import android.location.Location; | ||||
import android.media.Image; | import android.media.Image; | ||||
import org.json.JSONException; | import org.json.JSONException; | ||||
import org.json.JSONObject; | import org.json.JSONObject; | ||||
import java.io.File; | |||||
import java.io.FileNotFoundException; | |||||
import java.io.FileOutputStream; | |||||
import java.io.IOException; | |||||
import java.util.Date; | import java.util.Date; | ||||
public class OwnTask | public class OwnTask | ||||
public void setPathImage(String pathImage) { this.pathImage = pathImage; } | public void setPathImage(String pathImage) { this.pathImage = pathImage; } | ||||
public String saveImageToExternalStorage(Context context){ | |||||
File path = null; | |||||
try { | |||||
path = new File(context.getFilesDir(), "meinWald" + File.separator + "Images"); | |||||
if(!path.exists()){ | |||||
path.mkdirs(); | |||||
} | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(this.getClass().getSimpleName(), "Image file path: " + path); | |||||
} | |||||
File outFile = new File(path, this.id + ".jpeg"); | |||||
if (!outFile.exists()) | |||||
{ | |||||
FileOutputStream outputStream = new FileOutputStream(outFile); | |||||
this.image.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); | |||||
outputStream.close(); | |||||
} | |||||
} catch (FileNotFoundException e) { | |||||
Log.e(this.getClass().getSimpleName(), "Saving received message failed with", e); | |||||
} catch (IOException e) { | |||||
Log.e(this.getClass().getSimpleName(), "Saving received message failed with", e); | |||||
} | |||||
return path.toString(); | |||||
} | |||||
/** | |||||
* Delete OwnArea object textfile from external storage. | |||||
*/ | |||||
public void deleteFromExternalStorage(Context context) | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "deleteFromExternalStorage()"); | |||||
} | |||||
// Find the root of the external storage. | |||||
File root = android.os.Environment.getExternalStorageDirectory(); | |||||
//delete file if exists | |||||
File file = new File(context.getFilesDir(), "meinWald" + File.pathSeparator + "Images" + File.pathSeparator + this.getId() + ".txt"); | |||||
if(!file.exists()){ | |||||
file.delete(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "Delete image file: " + file.getPath()); | |||||
} | |||||
} | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return "OwnTask{" + | return "OwnTask{" + |
import android.content.Context; | import android.content.Context; | ||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.graphics.Rect; | import android.graphics.Rect; | ||||
import android.os.Build; | |||||
import android.util.Log; | import android.util.Log; | ||||
import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||
import android.view.View; | import android.view.View; | ||||
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.AreaAdapter; | |||||
import com.example.meinwald.ui.area.OwnArea; | import com.example.meinwald.ui.area.OwnArea; | ||||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import androidx.annotation.RequiresApi; | |||||
import androidx.appcompat.widget.AlertDialogLayout; | import androidx.appcompat.widget.AlertDialogLayout; | ||||
import androidx.appcompat.widget.LinearLayoutCompat; | import androidx.appcompat.widget.LinearLayoutCompat; | ||||
import androidx.constraintlayout.widget.ConstraintLayout; | import androidx.constraintlayout.widget.ConstraintLayout; | ||||
public class TaskAdapter extends BaseAdapter | public class TaskAdapter extends BaseAdapter | ||||
{ | { | ||||
private final static String TAG = TaskAdapter.class.getSimpleName(); | |||||
List<OwnTask> taskList; | List<OwnTask> taskList; | ||||
LayoutInflater inflater; | LayoutInflater inflater; | ||||
Context context; | Context context; | ||||
final TextView title = (TextView) view.findViewById(R.id.taskInfoTitle); | final TextView title = (TextView) view.findViewById(R.id.taskInfoTitle); | ||||
final TextView notice = (TextView) view.findViewById(R.id.taskInfoNotice); | final TextView notice = (TextView) view.findViewById(R.id.taskInfoNotice); | ||||
final ImageView icon = (ImageView) view.findViewById(R.id.taskIcon); | final ImageView icon = (ImageView) view.findViewById(R.id.taskIcon); | ||||
final ImageView manageTask = (ImageView) view.findViewById(R.id.taskManageTask); | |||||
context = view.getContext(); | context = view.getContext(); | ||||
} | } | ||||
}); | }); | ||||
manageTask.setOnClickListener(new View.OnClickListener() { | |||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) | |||||
@Override | |||||
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 gps = viewInflated.findViewById(R.id.areaManageGPSPoints); | |||||
ImageView image = (ImageView) viewInflated.findViewById(R.id.areaManageImage); | |||||
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(taskList.get(i).getTitle()); | |||||
notice.setText(taskList.get(i).getNotice()); | |||||
if (taskList.get(i).getLocation() != null) | |||||
{ | |||||
gps.setText(String.valueOf(taskList.get(i).getLocation())); | |||||
} | |||||
else | |||||
{ | |||||
gps.setText("Kein Standort gespeichert!"); | |||||
} | |||||
if (taskList.get(i).getImage() != null) | |||||
{ | |||||
image.setImageBitmap(taskList.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) { | |||||
taskList.get(i).setNotice(noticeView.getText().toString()); | |||||
notice.setText(taskList.get(i).getNotice()); | |||||
dialog.dismiss(); | |||||
} | |||||
}); | |||||
newbuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
newbuilder.show(); | |||||
}}); | |||||
deleteArea.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) { | |||||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||||
newbuilder.setTitle("Das Grundstück wirklich löschen?"); | |||||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
taskList.get(i).deleteFromExternalStorage(context); | |||||
taskList.remove(i); | |||||
notifyDataSetChanged(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
for (OwnTask task: taskList) | |||||
{ | |||||
Log.d(TAG, "areaList item: " + task.toString()); | |||||
} | |||||
} | |||||
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) { | |||||
if (taskList.size()-1 > i && taskList.get(i) != null) | |||||
{ | |||||
taskList.get(i).deleteFromExternalStorage(context); | |||||
taskList.get(i).saveImageToExternalStorage(context); | |||||
} | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
for (OwnTask task: taskList) | |||||
{ | |||||
Log.d(TAG, "areaList item: " + task.toString()); | |||||
} | |||||
} | |||||
dialog.dismiss(); | |||||
} | |||||
}); | |||||
builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
builder.show(); | |||||
} | |||||
}); | |||||
icon.setOnClickListener(new View.OnClickListener() { | icon.setOnClickListener(new View.OnClickListener() { | ||||
@Override | @Override | ||||
public void onClick(View v) | public void onClick(View v) | ||||
final ConstraintLayout imageViewLayout = viewInflated.findViewById(R.id.taskLargeImageLayout); | final ConstraintLayout imageViewLayout = viewInflated.findViewById(R.id.taskLargeImageLayout); | ||||
final ImageView imageView = viewInflated.findViewById(R.id.taskLargeImage); | final ImageView imageView = viewInflated.findViewById(R.id.taskLargeImage); | ||||
//ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(taskList.get(i).getImage().getWidth(),5 * taskList.get(i).getImage().getHeight()); | |||||
//imageViewLayout.setLayoutParams(layoutParams); | |||||
Log.d("TaskAdapter", String.valueOf(taskList.get(i).getImage().getHeight())); | |||||
//ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(taskList.get(i).getImage().getWidth(), taskList.get(i).getImage().getHeight()); | |||||
//layoutParams.width = taskList.get(i).getImage().getWidth(); | |||||
//layoutParams.height = taskList.get(i).getImage().getHeight(); | |||||
//imageView.setLayoutParams(layoutParams); | |||||
imageView.setImageBitmap(taskList.get(i).getImage()); | imageView.setImageBitmap(taskList.get(i).getImage()); | ||||
builder.setNegativeButton("Zurück", new DialogInterface.OnClickListener() { | builder.setNegativeButton("Zurück", new DialogInterface.OnClickListener() { |
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.content.Intent; | import android.content.Intent; | ||||
import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||
import android.database.DataSetObserver; | |||||
import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||
import android.graphics.BitmapFactory; | import android.graphics.BitmapFactory; | ||||
import android.graphics.Color; | import android.graphics.Color; | ||||
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.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.CameraUpdateFactory; | import com.google.android.gms.maps.CameraUpdateFactory; | ||||
//save and display location | //save and display location | ||||
newTask.setLocation(mLastKnownLocation); | newTask.setLocation(mLastKnownLocation); | ||||
locationText.setText("Lat: " +String.valueOf(mLastKnownLocation.getLatitude()) + " Lng: " + String.valueOf(mLastKnownLocation.getLongitude())); | |||||
locationText.setText("Auf " + newTask.getLocation().getAccuracy() + " Meter genau!"); | |||||
} | } | ||||
}); | }); | ||||
//save user input | //save user input | ||||
newTask.setTitle(String.valueOf(titleView.getText())); | newTask.setTitle(String.valueOf(titleView.getText())); | ||||
newTask.setNotice(String.valueOf(noticeView.getText())); | newTask.setNotice(String.valueOf(noticeView.getText())); | ||||
newTask.setPathImage(newTask.saveImageToExternalStorage(getContext())); | |||||
boolean result = allTasks.add(newTask); | boolean result = allTasks.add(newTask); | ||||
{ | { | ||||
Log.d(TAG, "new Task: " + newTask.toString()); | Log.d(TAG, "new Task: " + newTask.toString()); | ||||
Log.d(TAG, "add new task result: " + result); | Log.d(TAG, "add new task result: " + result); | ||||
/** | |||||
for (OwnTask task: allTasks) | |||||
{ | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, task.toString()); | |||||
} | |||||
} | |||||
**/ | |||||
} | } | ||||
instantiateTaskList(); | instantiateTaskList(); | ||||
{ | { | ||||
//save image to external storage and save path | //save image to external storage and save path | ||||
String path = saveReceivedImage(task.getImage(), task.getId()); | |||||
String path = task.saveImageToExternalStorage(getContext()); | |||||
task.setPathImage(path); | task.setPathImage(path); | ||||
if (BuildConfig.DEBUG) { | if (BuildConfig.DEBUG) { | ||||
} | } | ||||
} | } | ||||
private String saveReceivedImage(Bitmap bitmap, String imageName){ | |||||
File path = null; | |||||
try { | |||||
path = new File(getContext().getFilesDir(), "meinWald" + File.separator + "Images"); | |||||
if(!path.exists()){ | |||||
path.mkdirs(); | |||||
} | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "Image file path: " + path); | |||||
} | |||||
File outFile = new File(path, imageName + ".jpeg"); | |||||
if (!outFile.exists()) | |||||
{ | |||||
FileOutputStream outputStream = new FileOutputStream(outFile); | |||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); | |||||
outputStream.close(); | |||||
} | |||||
} catch (FileNotFoundException e) { | |||||
Log.e(TAG, "Saving received message failed with", e); | |||||
} catch (IOException e) { | |||||
Log.e(TAG, "Saving received message failed with", e); | |||||
} | |||||
return path.toString(); | |||||
} | |||||
/** | /** | ||||
* Reads tasks saved in preferences as jsonStrings | * Reads tasks saved in preferences as jsonStrings | ||||
* | * | ||||
public void instantiateTaskList() | public void instantiateTaskList() | ||||
{ | { | ||||
final TaskAdapter adapter = new TaskAdapter(getActivity().getApplicationContext(),allTasks); | final TaskAdapter adapter = new TaskAdapter(getActivity().getApplicationContext(),allTasks); | ||||
adapter.registerDataSetObserver(new DataSetObserver() { | |||||
@Override | |||||
public void onChanged() { | |||||
super.onChanged(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "onChanged"); | |||||
} | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "dataset size: " + taskList.getAdapter().getCount()); | |||||
} | |||||
if (taskList.getAdapter().getCount() > 0) | |||||
{ | |||||
allTasks = new ArrayList<>(); | |||||
for (int i = 0; i < taskList.getAdapter().getCount(); i++) | |||||
{ | |||||
allTasks.add((OwnTask) taskList.getAdapter().getItem(i)); | |||||
} | |||||
} | |||||
} | |||||
}); | |||||
taskList.setAdapter(adapter); | taskList.setAdapter(adapter); | ||||
//initialise onClickListeners | //initialise onClickListeners | ||||
{ | { | ||||
Bitmap photo = (Bitmap) data.getExtras().get("data"); | Bitmap photo = (Bitmap) data.getExtras().get("data"); | ||||
newTask.setImage(photo); | newTask.setImage(photo); | ||||
newTask.setPathImage(saveReceivedImage(photo,newTask.getId())); | |||||
if (imageToAdd != null && photo != null) | if (imageToAdd != null && photo != null) | ||||
{ | { |
android:focusable="false" | android:focusable="false" | ||||
android:textColor="@android:color/primary_text_light" | android:textColor="@android:color/primary_text_light" | ||||
android:textSize="22sp" | android:textSize="22sp" | ||||
android:textStyle="bold" | |||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" /> | app:layout_constraintTop_toTopOf="parent" /> | ||||
<TextView | <TextView | ||||
android:id="@+id/areaInfoNotice" | android:id="@+id/areaInfoNotice" | ||||
android:layout_width="0dp" | android:layout_width="0dp" | ||||
android:layout_height="wrap_content" | |||||
android:layout_height="0dp" | |||||
android:layout_gravity="left" | android:layout_gravity="left" | ||||
android:clickable="false" | android:clickable="false" | ||||
android:duplicateParentState="true" | |||||
android:focusable="false" | android:focusable="false" | ||||
android:focusableInTouchMode="false" | android:focusableInTouchMode="false" | ||||
android:textColor="@android:color/primary_text_light" | android:textColor="@android:color/primary_text_light" | ||||
android:textSize="12sp" | android:textSize="12sp" | ||||
android:visibility="visible" | android:visibility="visible" | ||||
app:layout_constraintEnd_toStartOf="@+id/taskIcon" | |||||
app:layout_constraintBottom_toTopOf="@+id/areaInfoArea" | |||||
app:layout_constraintEnd_toStartOf="@+id/areaIcon" | |||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" | |||||
android:duplicateParentState="true"/> | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<TextView | |||||
android:id="@+id/areaInfoAreatv" | |||||
android:layout_width="0dp" | |||||
android:layout_height="20dp" | |||||
android:layout_gravity="left" | |||||
android:layout_marginBottom="5dp" | |||||
android:clickable="false" | |||||
android:duplicateParentState="true" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:text="Fläche:" | |||||
android:textColor="@android:color/primary_text_light" | |||||
android:textSize="14sp" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" /> | |||||
<TextView | |||||
android:id="@+id/areaInfoArea" | |||||
android:layout_width="0dp" | |||||
android:layout_height="0dp" | |||||
android:layout_gravity="left" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginBottom="5dp" | |||||
android:clickable="false" | |||||
android:duplicateParentState="true" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:textColor="@android:color/primary_text_light" | |||||
android:textSize="14sp" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toStartOf="@+id/areaIcon" | |||||
app:layout_constraintStart_toEndOf="@+id/areaInfoAreatv" | |||||
app:layout_constraintTop_toTopOf="@+id/areaInfoAreatv" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:id="@+id/layout_area_root" | android:id="@+id/layout_area_root" | ||||
android:layout_width="fill_parent" | android:layout_width="fill_parent" | ||||
android:layout_height="fill_parent" | android:layout_height="fill_parent" | ||||
android:id="@+id/areaTitle" | android:id="@+id/areaTitle" | ||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="5dp" | |||||
android:text="Grundstück" | android:text="Grundstück" | ||||
android:textAppearance="?android:attr/textAppearanceLarge" /> | |||||
android:textAppearance="?android:attr/textAppearanceLarge" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<EditText | <EditText | ||||
android:id="@+id/areaTitleUserInput" | android:id="@+id/areaTitleUserInput" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:hint="Titel eingeben!"> | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:hint="Titel eingeben!" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaTitle"> | |||||
<requestFocus /> | <requestFocus /> | ||||
android:id="@+id/areaManagementNotice" | 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:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="15dp" | |||||
android:text="Beschreibung" | android:text="Beschreibung" | ||||
android:textAppearance="?android:attr/textAppearanceLarge" /> | |||||
android:textAppearance="?android:attr/textAppearanceLarge" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaTitleUserInput" /> | |||||
<EditText | <EditText | ||||
android:id="@+id/areaManagementNoticeUserInput" | android:id="@+id/areaManagementNoticeUserInput" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="150dp" | android:layout_height="150dp" | ||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:cursorVisible="true" | |||||
android:hint="Beschreibung eingeben!" | android:hint="Beschreibung eingeben!" | ||||
android:isScrollContainer="true"> | |||||
<requestFocus /> | |||||
android:isScrollContainer="true" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaManagementNotice"> | |||||
</EditText> | </EditText> | ||||
<Button | <Button | ||||
android:id="@+id/areaStartTracking" | android:id="@+id/areaStartTracking" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:text="Grundstücksaufnahme Starten!" /> | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="15dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:text="Grundstücksaufnahme Starten!" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaManagementNoticeUserInput" /> | |||||
<Button | <Button | ||||
android:id="@+id/areaStopTracking" | android:id="@+id/areaStopTracking" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="15dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:text="Grundstücksaufnahme Beenden!" | android:text="Grundstücksaufnahme Beenden!" | ||||
android:visibility="invisible"/> | |||||
android:visibility="invisible" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaManagementNoticeUserInput" /> | |||||
<Button | |||||
android:id="@+id/areaAddGPSPoint" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:text="Grenzpunkt hinzufügen" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaStartTracking" /> | |||||
</LinearLayout> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
android:layout_marginStart="5dp" | android:layout_marginStart="5dp" | ||||
android:layout_marginLeft="5dp" | android:layout_marginLeft="5dp" | ||||
android:layout_marginTop="15dp" | android:layout_marginTop="15dp" | ||||
android:text="Bild" | |||||
android:text="Zuletzt überprüft" | |||||
android:textSize="18sp" | android:textSize="18sp" | ||||
android:textStyle="bold" | android:textStyle="bold" | ||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toBottomOf="@+id/textView4" /> | app:layout_constraintTop_toBottomOf="@+id/textView4" /> | ||||
<TextView | |||||
android:id="@+id/textView7" | |||||
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/areaManagementLastChecked" /> | |||||
<TextView | |||||
android:id="@+id/areaManagementLastChecked" | |||||
android:layout_width="0dp" | |||||
android:layout_height="30dp" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:textSize="12sp" | |||||
app:layout_constraintEnd_toStartOf="@+id/areaManageNewDate" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/textView6" /> | |||||
<ImageView | <ImageView | ||||
android:id="@+id/areaManageImage" | android:id="@+id/areaManageImage" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_marginLeft="5dp" | android:layout_marginLeft="5dp" | ||||
android:layout_marginEnd="5dp" | android:layout_marginEnd="5dp" | ||||
android:layout_marginRight="5dp" | android:layout_marginRight="5dp" | ||||
android:src="@android:drawable/ic_menu_gallery" | |||||
android:visibility="visible" | |||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
app:layout_constraintHorizontal_bias="1.0" | |||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toBottomOf="@+id/textView6" | |||||
android:src="@android:drawable/ic_menu_gallery" | |||||
android:visibility="visible"/> | |||||
app:layout_constraintTop_toBottomOf="@+id/textView7" /> | |||||
<ImageView | <ImageView | ||||
android:id="@+id/areaManageNewDescription" | android:id="@+id/areaManageNewDescription" | ||||
app:layout_constraintEnd_toEndOf="@+id/areaManageGPSPoints" | app:layout_constraintEnd_toEndOf="@+id/areaManageGPSPoints" | ||||
android:src="@android:drawable/ic_popup_sync" /> | android:src="@android:drawable/ic_popup_sync" /> | ||||
<ImageView | |||||
android:id="@+id/areaManageNewDate" | |||||
android:layout_width="30dp" | |||||
android:layout_height="30dp" | |||||
android:src="@android:drawable/ic_popup_sync" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="@+id/areaManagementLastChecked" | |||||
app:layout_constraintEnd_toEndOf="@+id/areaManageGPSPoints" | |||||
app:tint="#1B5E20" /> | |||||
<ImageView | <ImageView | ||||
android:id="@+id/areaManageNewImage" | android:id="@+id/areaManageNewImage" | ||||
android:layout_width="30dp" | android:layout_width="30dp" | ||||
android:visibility="visible" | android:visibility="visible" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
/> | |||||
/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> |
<ImageView | <ImageView | ||||
android:id="@+id/taskLargeImage" | android:id="@+id/taskLargeImage" | ||||
android:layout_width="match_parent" | |||||
android:layout_height="575dp" | |||||
android:layout_width="0dp" | |||||
android:layout_height="500dp" | |||||
android:layout_marginStart="40dp" | |||||
android:layout_marginLeft="40dp" | |||||
android:layout_marginTop="60dp" | |||||
android:layout_marginEnd="40dp" | |||||
android:layout_marginRight="40dp" | |||||
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" |
<TextView | <TextView | ||||
android:id="@+id/taskInfoTitle" | android:id="@+id/taskInfoTitle" | ||||
android:layout_width="match_parent" | |||||
android:layout_height="30dp" | |||||
android:layout_width="0dp" | |||||
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: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_constraintEnd_toStartOf="@+id/taskManageTask" | |||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" /> | app:layout_constraintTop_toTopOf="parent" /> | ||||
<ImageView | |||||
android:id="@+id/taskManageTask" | |||||
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/taskInfoView" | android:id="@+id/taskInfoView" | ||||
android:layout_width="0dp" | android:layout_width="0dp" |
android:hint="Beschreibung eingeben!" | android:hint="Beschreibung eingeben!" | ||||
android:isScrollContainer="true"> | android:isScrollContainer="true"> | ||||
<requestFocus /> | |||||
</EditText> | </EditText> | ||||
<Button | <Button |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto"> | |||||
<TextView | |||||
android:id="@+id/taskManageTitle" | |||||
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/taskManageTitle" /> | |||||
<TextView | |||||
android:id="@+id/taskManageNotice" | |||||
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="Standort" | |||||
android:textSize="18sp" | |||||
android:textStyle="bold" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/taskManageNotice" /> | |||||
<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/taskManageGPSPoint" /> | |||||
<TextView | |||||
android:id="@+id/taskManageGPSPoint" | |||||
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/taskManageImage" | |||||
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/taskManageNewDescription" | |||||
android:layout_width="30dp" | |||||
android:layout_height="30dp" | |||||
app:tint="#1B5E20" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="@+id/taskManageNotice" | |||||
app:layout_constraintEnd_toEndOf="@+id/taskManageNotice" | |||||
android:src="@android:drawable/ic_popup_sync" /> | |||||
<ImageView | |||||
android:id="@+id/taskManageNewGPS" | |||||
android:layout_width="30dp" | |||||
android:layout_height="30dp" | |||||
app:tint="#1B5E20" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="@+id/taskManageGPSPoint" | |||||
app:layout_constraintEnd_toEndOf="@+id/taskManageGPSPoint" | |||||
android:src="@android:drawable/ic_popup_sync" /> | |||||
<ImageView | |||||
android:id="@+id/taskManageNewImage" | |||||
android:layout_width="30dp" | |||||
android:layout_height="30dp" | |||||
app:tint="#1B5E20" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="@+id/taskManageImage" | |||||
app:layout_constraintEnd_toEndOf="@+id/taskManageImage" | |||||
android:src="@android:drawable/ic_menu_camera" /> | |||||
<ImageView | |||||
android:id="@+id/taskManageDeleteTask" | |||||
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"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<resources> | <resources> | ||||
<color name="colorPrimary">#1B5E20</color> | <color name="colorPrimary">#1B5E20</color> | ||||
<color name="colorPrimaryDark">#3700B3</color> | |||||
<color name="colorPrimaryDark">#1B5E20</color> | |||||
<color name="colorAccent">#03DAC5</color> | <color name="colorAccent">#03DAC5</color> | ||||
<color name="selectionBackground">#c0edc3</color> | <color name="selectionBackground">#c0edc3</color> | ||||
<color name="colorArea1">#57a639</color> | |||||
<color name="colorArea2">#819b45</color> | |||||
<color name="colorArea3">#d3d30c</color> | |||||
<color name="colorArea4">#df9600</color> | |||||
<color name="colorArea5">#df3d00</color> | |||||
</resources> | </resources> |