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" | ||||
<meta-data | <meta-data | ||||
android:name="com.google.android.geo.API_KEY" | android:name="com.google.android.geo.API_KEY" | ||||
android:value="@string/google_maps_key" /> | android:value="@string/google_maps_key" /> | ||||
<service | |||||
android:name=".ui.area.LocationTrack" | |||||
android:exported="false"> | |||||
</service> | |||||
</application> | </application> | ||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> | <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> | ||||
<uses-permission android:name="android.permission.CAMERA" /> | |||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | |||||
</manifest> | </manifest> |
package com.example.meinwald; | package com.example.meinwald; | ||||
import android.content.Context; | |||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import com.google.android.material.bottomnavigation.BottomNavigationView; | import com.google.android.material.bottomnavigation.BottomNavigationView; | ||||
public class MainActivity extends AppCompatActivity { | public class MainActivity extends AppCompatActivity { | ||||
private static Context context; | |||||
@Override | @Override | ||||
protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
context = getApplicationContext(); | |||||
setContentView(R.layout.activity_main); | setContentView(R.layout.activity_main); | ||||
BottomNavigationView navView = findViewById(R.id.nav_view); | BottomNavigationView navView = findViewById(R.id.nav_view); | ||||
// Passing each menu ID as a set of Ids because each | // Passing each menu ID as a set of Ids because each | ||||
NavigationUI.setupWithNavController(navView, navController); | NavigationUI.setupWithNavController(navView, navController); | ||||
} | } | ||||
public static Context getAppContext() { | |||||
return context; | |||||
} | |||||
} | } |
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; | |||||
} | |||||
} |
package com.example.meinwald.ui.area; | |||||
import android.app.AlertDialog; | |||||
import android.content.Context; | |||||
import android.content.DialogInterface; | |||||
import android.graphics.Rect; | |||||
import android.util.Log; | |||||
import android.view.LayoutInflater; | |||||
import android.view.View; | |||||
import android.view.ViewGroup; | |||||
import android.widget.BaseAdapter; | |||||
import android.widget.ImageView; | |||||
import android.widget.TextView; | |||||
import com.example.meinwald.BuildConfig; | |||||
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.List; | |||||
import androidx.appcompat.widget.AlertDialogLayout; | |||||
import androidx.appcompat.widget.LinearLayoutCompat; | |||||
import androidx.constraintlayout.widget.ConstraintLayout; | |||||
import static java.security.AccessController.getContext; | |||||
public class AreaAdapter extends BaseAdapter | |||||
{ | |||||
List<OwnArea> areaList; | |||||
LayoutInflater inflater; | |||||
Context context; | |||||
public AreaAdapter(Context applicationContext, List<OwnArea> areaList) | |||||
{ | |||||
this.areaList = new ArrayList<>(); | |||||
this.areaList = areaList; | |||||
this.context = applicationContext; | |||||
inflater = LayoutInflater.from(applicationContext); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d("AreaAdapter","size: " + areaList.size()); | |||||
} | |||||
} | |||||
@Override | |||||
public View getView(final int i, View view, final ViewGroup viewGroup) { | |||||
view = inflater.inflate(R.layout.area_element, null); | |||||
final ConstraintLayout elementView = view.findViewById(R.id.areaInfoView); | |||||
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); | |||||
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()); | |||||
} | |||||
title.setText(areaList.get(i).getTitle()); | |||||
notice.setText(areaList.get(i).getNotice()); | |||||
icon.setImageBitmap(areaList.get(i).getImage()); | |||||
title.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) | |||||
{ | |||||
} | |||||
}); | |||||
notice.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) | |||||
{ | |||||
} | |||||
}); | |||||
icon.setOnClickListener(new View.OnClickListener() { | |||||
@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.image_large, viewGroup, false); | |||||
builder.setView(viewInflated); | |||||
final ConstraintLayout imageViewLayout = viewInflated.findViewById(R.id.taskLargeImageLayout); | |||||
final ImageView imageView = viewInflated.findViewById(R.id.taskLargeImage); | |||||
imageView.setImageBitmap(areaList.get(i).getImage()); | |||||
builder.setNegativeButton("Zurück", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
builder.show(); | |||||
} | |||||
}); | |||||
view.setOnLongClickListener(new View.OnLongClickListener() { | |||||
@Override | |||||
public boolean onLongClick(View v) { | |||||
// TODO Auto-generated method stub | |||||
return true; | |||||
} | |||||
}); | |||||
return view; | |||||
} | |||||
@Override | |||||
public int getCount() { | |||||
return areaList.size(); | |||||
} | |||||
@Override | |||||
public Object getItem(int i) { | |||||
return areaList.get(i); | |||||
} | |||||
@Override | |||||
public long getItemId(int i) { | |||||
return i; | |||||
} | |||||
} | |||||
package com.example.meinwald.ui.area; | package com.example.meinwald.ui.area; | ||||
import android.Manifest; | |||||
import android.annotation.SuppressLint; | |||||
import android.app.AlertDialog; | |||||
import android.content.ComponentName; | |||||
import android.content.DialogInterface; | |||||
import android.content.ServiceConnection; | |||||
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.preference.PreferenceManager; | |||||
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.AdapterView; | |||||
import android.widget.Button; | |||||
import android.widget.ListView; | |||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import android.widget.Toast; | |||||
import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
import androidx.core.app.ActivityCompat; | |||||
import androidx.core.content.ContextCompat; | |||||
import androidx.fragment.app.Fragment; | import androidx.fragment.app.Fragment; | ||||
import androidx.lifecycle.Observer; | import androidx.lifecycle.Observer; | ||||
import androidx.lifecycle.ViewModelProviders; | |||||
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.LocationServices; | |||||
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.JSONException; | |||||
import org.json.JSONObject; | |||||
import org.json.JSONStringer; | |||||
import java.io.BufferedReader; | |||||
import java.io.File; | |||||
import java.io.FileNotFoundException; | |||||
import java.io.FileOutputStream; | |||||
import java.io.FileReader; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.io.InputStreamReader; | |||||
import java.io.PrintWriter; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import static android.content.Context.POWER_SERVICE; | |||||
public class AreaFragment extends Fragment { | public class AreaFragment extends Fragment { | ||||
private DashboardViewModel dashboardViewModel; | |||||
private static final String TAG = TasksFragment.class.getSimpleName(); | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* AREA | |||||
*/ | |||||
private OwnArea newArea = new OwnArea(); | |||||
private List<OwnArea> allAreas; | |||||
private ListView areaList; | |||||
private static final String KEY_AREA_REFERENCES = "areaReferences"; | |||||
private List<AreaReference> areaReferences; | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* LOCATION | |||||
*/ | |||||
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; | |||||
/** | |||||
* The entry point to the Fused Location Provider. | |||||
*/ | |||||
private FusedLocationProviderClient mFusedLocationProviderClient; | |||||
private boolean mLocationPermissionGranted; | |||||
/** | |||||
* The geographical locations which were received from location tracking. | |||||
*/ | |||||
private List<LatLng> newPositions; | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* CAMERA | |||||
*/ | |||||
private static final int MY_CAMERA_PERMISSION_CODE = 100; | |||||
private boolean mCameraPermissionGranted; | |||||
private static final int CAMERA_REQUEST = 1888; | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* STORAGE | |||||
*/ | |||||
private static final int READ_EXTERNAL_STORAGE_CODE = 200; | |||||
private static final int WRITE_EXTERNAL_STORAGE_CODE = 201; | |||||
private boolean mReadStorageGranted; | |||||
private boolean mWriteStorageGranted; | |||||
PowerManager.WakeLock wakeLock; | |||||
LocationService gps; | |||||
@SuppressLint("InvalidWakeLockTag") | |||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | |||||
public View onCreateView(@NonNull LayoutInflater inflater, | |||||
ViewGroup container, Bundle savedInstanceState) { | |||||
dashboardViewModel = | |||||
ViewModelProviders.of(this).get(DashboardViewModel.class); | |||||
View root = inflater.inflate(R.layout.fragment_areas, container, false); | View root = inflater.inflate(R.layout.fragment_areas, container, false); | ||||
final TextView textView = root.findViewById(R.id.text_areas); | |||||
dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { | |||||
//construct a FusedLocationProviderClient. | |||||
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity()); | |||||
//get permissions | |||||
getLocationPermission(); | |||||
getReadStoragePermission(); | |||||
//instantiate area lists | |||||
areaList = (ListView) root.findViewById(R.id.areaListView); | |||||
allAreas = new ArrayList<>(); | |||||
areaReferences = new ArrayList<>(); | |||||
PowerManager powerManager = (PowerManager) getContext().getSystemService(POWER_SERVICE); | |||||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag"); | |||||
gps = new LocationService(getContext()); | |||||
//instantiate add button | |||||
final FloatingActionButton fab = root.findViewById(R.id.fab_areas); | |||||
fab.setOnClickListener(new View.OnClickListener() { | |||||
@Override | @Override | ||||
public void onChanged(@Nullable String s) { | |||||
textView.setText(s); | |||||
} | |||||
}); | |||||
public void onClick(View view) { | |||||
//permissions | |||||
getLocationPermission(); | |||||
getWriteStoragePPermission(); | |||||
//get saved areas | |||||
areaReferences = readAreaReferencesFromPreferences(); | |||||
allAreas = loadAreasFromPreferences(); | |||||
instantiateAreasList(); | |||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | |||||
newArea = new OwnArea(); | |||||
final View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.area_input, (ViewGroup) getView(), false); | |||||
builder.setView(viewInflated); | |||||
final Button startTracking = viewInflated.findViewById(R.id.areaStartTracking); | |||||
final Button stopTracking = viewInflated.findViewById(R.id.areaStopTracking); | |||||
startTracking.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View view) { | |||||
//start tracking | |||||
startLocationTracking(); | |||||
startTracking.setVisibility(View.INVISIBLE); | |||||
stopTracking.setVisibility(View.VISIBLE); | |||||
} | |||||
}); | |||||
stopTracking.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View view) { | |||||
//stop tracking | |||||
newPositions = gps.getPositions(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Received locations: " + newPositions.size()); | |||||
} | |||||
FloatingActionButton fab = root.findViewById(R.id.fab_areas); | |||||
newArea.setLocations(newPositions); | |||||
wakeLock.release(); | |||||
startTracking.setVisibility(View.VISIBLE); | |||||
stopTracking.setVisibility(View.INVISIBLE); | |||||
} | |||||
}); | |||||
builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
final TextView titleView = viewInflated.findViewById(R.id.areaTitleUserInput); | |||||
final TextView noticeView = viewInflated.findViewById(R.id.areaNoticeUserInput); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "new title: " + titleView.getText()); | |||||
} | |||||
if (titleView.getText().length()>0) | |||||
{ | |||||
//save user input | |||||
newArea.setTitle(String.valueOf(titleView.getText())); | |||||
newArea.setNotice(String.valueOf(noticeView.getText())); | |||||
boolean result = allAreas.add(newArea); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "new Task: " + newArea.toString()); | |||||
Log.d(TAG, "add new task result: " + result); | |||||
} | |||||
//stop tracking | |||||
//wakeLock.release(); | |||||
//save new area | |||||
allAreas.add(newArea); | |||||
writeAreaToExternalStorage(newArea); | |||||
//actuate list | |||||
instantiateAreasList(); | |||||
dialog.dismiss(); | |||||
//confirm added task | |||||
Toast toast = Toast.makeText(getActivity(), "Grundstück hinzugefügt!", Toast.LENGTH_SHORT); | |||||
TextView v = (TextView) toast.getView().findViewById(android.R.id.message); | |||||
if( v != null) | |||||
{ | |||||
//text align center | |||||
v.setGravity(Gravity.CENTER); | |||||
} | |||||
toast.show(); | |||||
} | |||||
else | |||||
{ | |||||
//title needed | |||||
Toast toast = Toast.makeText(getActivity(), "Grundstückstitel fehlt!", Toast.LENGTH_SHORT); | |||||
TextView v = (TextView) toast.getView().findViewById(android.R.id.message); | |||||
if( v != null) | |||||
{ | |||||
//text align center | |||||
v.setGravity(Gravity.CENTER); | |||||
} | |||||
toast.show(); | |||||
} | |||||
} | |||||
}); | |||||
builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
builder.show(); | |||||
}}); | |||||
return root; | return root; | ||||
} | } | ||||
/** | |||||
* Get all stored areas and save them temporary. | |||||
*/ | |||||
public void instantiateAreasList() | |||||
{ | |||||
final AreaAdapter adapter = new AreaAdapter(getActivity().getApplicationContext(), allAreas); | |||||
areaList.setAdapter(adapter); | |||||
//initialise onClickListeners | |||||
areaList.setOnItemClickListener(new AdapterView.OnItemClickListener() { | |||||
@Override | |||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { | |||||
//for (int j = 0; j < adapterView.getChildCount(); j++) | |||||
//adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT); | |||||
// change the background color of the selected element | |||||
//view.setBackgroundColor(Color.LTGRAY); | |||||
//adapterView.setSelection(i); | |||||
}}); | |||||
} | |||||
@Override | |||||
public void onPause() { | |||||
//save area references to shared preferences | |||||
emptyPreferencesAndSaveEpiColorsToPreferences(); | |||||
super.onPause(); | |||||
} | |||||
/** | |||||
* Get OwnAreas from a JSONString. | |||||
* @return | |||||
*/ | |||||
private List<OwnArea> loadAreasFromPreferences() | |||||
{ | |||||
List<OwnArea> areas = new ArrayList<>(); | |||||
for (AreaReference reference: areaReferences) | |||||
{ | |||||
String jsonString = readAreaFromExternalStorage(reference.getPath()); | |||||
areas.add(new OwnArea(jsonString)); | |||||
} | |||||
return areas; | |||||
} | |||||
/** | |||||
* Save OwnArea object in textfile on external storage. | |||||
* | |||||
* @param newArea OwnArea object to write to file. | |||||
* @return | |||||
*/ | |||||
private String writeAreaToExternalStorage(OwnArea newArea){ | |||||
// Find the root of the external storage. | |||||
File root = android.os.Environment.getExternalStorageDirectory(); | |||||
//create file if it does not exist | |||||
File path = new File (root.getAbsolutePath() + "meinWald" + File.pathSeparator + "areas"); | |||||
if(!path.exists()){ | |||||
path.mkdirs(); | |||||
} | |||||
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) { | |||||
e.printStackTrace(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return file.getPath(); | |||||
} | |||||
/** | |||||
* 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) | |||||
{ | |||||
//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) { | |||||
e.printStackTrace(); | |||||
} | |||||
return text.toString(); | |||||
} | |||||
/** | |||||
* Converts an OwnArea object into a JSONString object. | |||||
* | |||||
* @param area Area to convert into JSONString | |||||
* @return | |||||
*/ | |||||
public String areaToString(OwnArea area) | |||||
{ | |||||
JSONObject areaObject = newArea.toJSONObject(); | |||||
return areaObject.toString(); | |||||
} | |||||
/** | |||||
* Reads areaReferences saved in preferences as jsonStrings | |||||
* | |||||
* @return list of epiColorDtos | |||||
*/ | |||||
private List<AreaReference> 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++) { | |||||
areaReferences.add(new AreaReference(jsonObjects.getJSONObject(i))); | |||||
} | |||||
} | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(TAG, "Error while parsing epicolors as jsonObjects from preferences"); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
return areas; | |||||
} | |||||
/** | |||||
* Saves epicolors to preferences | |||||
*/ | |||||
private void emptyPreferencesAndSaveEpiColorsToPreferences() | |||||
{ | |||||
if (!areaReferences.isEmpty()) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "areaReferences not empty"); | |||||
} | |||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().remove(KEY_AREA_REFERENCES).commit(); | |||||
JSONArray writeObjects = new JSONArray(); | |||||
for (AreaReference reference: areaReferences) { | |||||
JSONObject object = reference.toJSONObject(); | |||||
writeObjects.put(object); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d("Color is ", object.toString()); | |||||
} | |||||
} | |||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_AREA_REFERENCES, writeObjects.toString()).commit(); | |||||
} | |||||
} | |||||
/** | |||||
* DOCU ME! | |||||
* TOOD: What are grant results etc for? | |||||
* @param requestCode | |||||
* @param permissions | |||||
* @param grantResults | |||||
*/ | |||||
@Override | |||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) | |||||
{ | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "onRequestPermissionResult Code: " + requestCode); | |||||
} | |||||
mLocationPermissionGranted = false; | |||||
switch (requestCode) { | |||||
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: { | |||||
// If request is cancelled, the result arrays are empty. | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) | |||||
{ | |||||
mLocationPermissionGranted = true; | |||||
} | |||||
} | |||||
case MY_CAMERA_PERMISSION_CODE: { | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
mCameraPermissionGranted = true; | |||||
} | |||||
} | |||||
case READ_EXTERNAL_STORAGE_CODE: { | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
mReadStorageGranted = true; | |||||
} | |||||
} | |||||
case WRITE_EXTERNAL_STORAGE_CODE: { | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
mWriteStorageGranted = true; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
public void getLocation(){ | |||||
wakeLock.acquire(); | |||||
gps = new LocationService(getContext()); | |||||
} | |||||
public void startLocationTracking(){ | |||||
final Runnable runnable= new Runnable() { | |||||
public void run() { | |||||
// do stuff here | |||||
getLocation(); | |||||
} | |||||
}; | |||||
runnable.run(); | |||||
} | |||||
/** | |||||
* Request location permission, so that we can get the location of the device. | |||||
* The result of the permission request is handled by a callback, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getLocationPermission() { | |||||
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), | |||||
android.Manifest.permission.ACCESS_FINE_LOCATION) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mLocationPermissionGranted = true; | |||||
} else { | |||||
ActivityCompat.requestPermissions(getActivity(), | |||||
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, | |||||
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); | |||||
} | |||||
} | |||||
/** | |||||
* 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, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getReadStoragePermission() { | |||||
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), | |||||
Manifest.permission.READ_EXTERNAL_STORAGE) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mReadStorageGranted = true; | |||||
} else { | |||||
ActivityCompat.requestPermissions(getActivity(), | |||||
new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, | |||||
READ_EXTERNAL_STORAGE_CODE); | |||||
} | |||||
} | |||||
/** | |||||
* 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, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getWriteStoragePPermission() { | |||||
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), | |||||
Manifest.permission.WRITE_EXTERNAL_STORAGE) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mWriteStorageGranted = true; | |||||
} else { | |||||
ActivityCompat.requestPermissions(getActivity(), | |||||
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, | |||||
WRITE_EXTERNAL_STORAGE_CODE); | |||||
} | |||||
} | |||||
} | } |
package com.example.meinwald.ui.area; | |||||
import android.util.Log; | |||||
import com.example.meinwald.BuildConfig; | |||||
import org.json.JSONException; | |||||
import org.json.JSONObject; | |||||
public class AreaReference | |||||
{ | |||||
private String id; | |||||
private String path; | |||||
public AreaReference(String id, String path) | |||||
{ | |||||
this.id = id; | |||||
this.path = path; | |||||
} | |||||
public String getId() { | |||||
return id; | |||||
} | |||||
public String getPath() { | |||||
return path; | |||||
} | |||||
/** | |||||
* Creates EpiColorDto from JSON-Representation | |||||
* | |||||
* @param jsonRepresentation epiColorDto values as jsonObject | |||||
*/ | |||||
public AreaReference(JSONObject jsonRepresentation) { | |||||
try { | |||||
this.id = jsonRepresentation.getString("id"); | |||||
this.path = jsonRepresentation.getString("path"); | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(this.getClass().getSimpleName(), | |||||
String.format("Error while parsing epiColorDto to JSONObject. Values of epiColorDto: %s", this.toString())); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Returns AreaReference as JSONObject. | |||||
* | |||||
* @return the mapped object or null, if parsing fails | |||||
*/ | |||||
public JSONObject toJSONObject() { | |||||
JSONObject object = new JSONObject(); | |||||
try { | |||||
object.put("id",this.id); | |||||
object.put("path",this.path); | |||||
return object; | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(this.getClass().getSimpleName(), | |||||
String.format("Error while parsing epiColorDto to JSONObject. Values of epiColorDto: %s", this.toString())); | |||||
} | |||||
return null; | |||||
} | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "AreaReference{" + | |||||
"id='" + id + '\'' + | |||||
", path='" + path + '\'' + | |||||
'}'; | |||||
} | |||||
} |
package com.example.meinwald.ui.area; | |||||
import androidx.lifecycle.LiveData; | |||||
import androidx.lifecycle.MutableLiveData; | |||||
import androidx.lifecycle.ViewModel; | |||||
public class DashboardViewModel extends ViewModel { | |||||
private MutableLiveData<String> mText; | |||||
public DashboardViewModel() { | |||||
mText = new MutableLiveData<>(); | |||||
mText.setValue("This is dashboard fragment"); | |||||
} | |||||
public LiveData<String> getText() { | |||||
return mText; | |||||
} | |||||
} |
package com.example.meinwald.ui.area; | |||||
import android.Manifest; | |||||
import android.app.AlertDialog; | |||||
import android.app.Service; | |||||
import android.content.Context; | |||||
import android.content.DialogInterface; | |||||
import android.content.Intent; | |||||
import android.content.pm.PackageManager; | |||||
import android.location.Location; | |||||
import android.location.LocationListener; | |||||
import android.location.LocationManager; | |||||
import android.os.Bundle; | |||||
import android.os.IBinder; | |||||
import android.provider.Settings; | |||||
import android.util.Log; | |||||
import com.example.meinwald.BuildConfig; | |||||
import com.google.android.gms.maps.model.LatLng; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import androidx.core.app.ActivityCompat; | |||||
import androidx.core.content.ContextCompat; | |||||
//import static com.name.name.MapsActivity.NOTIFICATION_ID; | |||||
public class LocationService extends Service implements LocationListener { | |||||
private static final String TAG = "LocationService"; | |||||
private final Context mContext; | |||||
// flag for GPS status | |||||
boolean isGPSEnabled = false; | |||||
// flag for network status | |||||
boolean isNetworkEnabled = false; | |||||
// flag for GPS status | |||||
boolean canGetLocation = false; | |||||
private boolean mLocationPermissionGranted; | |||||
Location location; // location | |||||
double latitude; // latitude | |||||
double longitude; // longitude | |||||
private List<LatLng> positions; | |||||
// The minimum distance to change Updates in meters | |||||
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 5 meters | |||||
// The minimum time between updates in milliseconds | |||||
private static final long MIN_TIME_BW_UPDATES = 1000 * 5 * 1; // 5 seconds | |||||
// Declaring a Location Manager | |||||
protected LocationManager mLocationManager; | |||||
public LocationService(Context context) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "LocationService(Context context)"); | |||||
} | |||||
this.mContext = context; | |||||
this.positions = new ArrayList<>(); | |||||
this.mLocationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE); | |||||
getLocationPermission(); | |||||
try { | |||||
// getting GPS status | |||||
isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); | |||||
if (!isGPSEnabled && !isNetworkEnabled) { | |||||
// no network provider is enabled | |||||
Log.d(TAG,"No permission to get location from any provider!"); | |||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
Log.d(TAG,"Permission to get location from any provider!"); | |||||
this.canGetLocation = true; | |||||
// First get location from Network Provider | |||||
if (isNetworkEnabled) { | |||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { | |||||
Log.d(TAG,"No permission to get location from network provider!"); | |||||
} | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "getLocation() requestLocationUpdates() from GPS"); | |||||
} | |||||
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); | |||||
if (mLocationManager != null) { | |||||
location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); | |||||
if (location != null) { | |||||
positions.add(new LatLng(location.getLatitude(), location.getLongitude())); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "getLocation() new location added"); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// if GPS Enabled get lat/long using GPS Services | |||||
if (isGPSEnabled && mLocationPermissionGranted) { | |||||
if (location == null) { | |||||
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { | |||||
Log.d(TAG,"No permission to get location from gps provider!"); | |||||
} | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "getLocation() requestLocationUpdates() from GPS"); | |||||
} | |||||
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); | |||||
if (mLocationManager != null) { | |||||
location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); | |||||
if (location != null) { | |||||
positions.add(new LatLng(location.getLatitude(), location.getLongitude())); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "getLocation() new location added"); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
public void getLocation() { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "getLocation()"); | |||||
} | |||||
} | |||||
/** | |||||
* Stop using GPS listener | |||||
* Calling this function will stop using GPS in your app | |||||
* */ | |||||
public void stopUsingGPS(){ | |||||
if(mLocationManager != null){ | |||||
mLocationManager.removeUpdates(LocationService.this); | |||||
} | |||||
} | |||||
/** | |||||
* Function to get latitude | |||||
* */ | |||||
public double getLatitude(){ | |||||
if(location != null){ | |||||
latitude = location.getLatitude(); | |||||
} | |||||
// return latitude | |||||
return latitude; | |||||
} | |||||
public List<LatLng> getPositions() | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "getPositions() count: " + this.positions.size()); | |||||
} | |||||
return this.positions; | |||||
} | |||||
/** | |||||
* Function to get longitude | |||||
* */ | |||||
public double getLongitude(){ | |||||
if(location != null){ | |||||
longitude = location.getLongitude(); | |||||
} | |||||
// return longitude | |||||
return longitude; | |||||
} | |||||
/** | |||||
* Function to check GPS/wifi enabled | |||||
* @return boolean | |||||
* */ | |||||
public boolean canGetLocation() { | |||||
return this.canGetLocation; | |||||
} | |||||
/** | |||||
* Function to show settings alert dialog | |||||
* On pressing Settings button will lauch Settings Options | |||||
* */ | |||||
public void showSettingsAlert(){ | |||||
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); | |||||
// Setting Dialog Title | |||||
alertDialog.setTitle("GPS is settings"); | |||||
// Setting Dialog Message | |||||
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?"); | |||||
// On pressing Settings button | |||||
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { | |||||
public void onClick(DialogInterface dialog,int which) { | |||||
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); | |||||
mContext.startActivity(intent); | |||||
} | |||||
}); | |||||
// on pressing cancel button | |||||
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
// Showing Alert Message | |||||
alertDialog.show(); | |||||
} | |||||
/** | |||||
* Request location permission, so that we can get the location of the device. | |||||
* The result of the permission request is handled by a callback, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getLocationPermission() { | |||||
if (ContextCompat.checkSelfPermission(mContext, | |||||
android.Manifest.permission.ACCESS_FINE_LOCATION) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mLocationPermissionGranted = true; | |||||
} | |||||
else | |||||
{ | |||||
mLocationPermissionGranted = false; | |||||
} | |||||
} | |||||
@Override | |||||
public void onLocationChanged(Location location) { | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "onLocationChanged(), new location: " + location.toString()); | |||||
} | |||||
positions.add(new LatLng(location.getLatitude(), getLongitude())); | |||||
} | |||||
@Override | |||||
public void onProviderDisabled(String provider) { | |||||
} | |||||
@Override | |||||
public void onProviderEnabled(String provider) { | |||||
} | |||||
@Override | |||||
public void onStatusChanged(String provider, int status, Bundle extras) { | |||||
} | |||||
@Override | |||||
public IBinder onBind(Intent arg0) { | |||||
return null; | |||||
} | |||||
} |
package com.example.meinwald.ui.area; | |||||
import android.graphics.Bitmap; | |||||
import android.location.Location; | |||||
import android.util.Log; | |||||
import com.example.meinwald.BuildConfig; | |||||
import com.google.android.gms.maps.model.LatLng; | |||||
import org.json.JSONException; | |||||
import org.json.JSONObject; | |||||
import java.sql.Time; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
public class OwnArea { | |||||
private String title; | |||||
private String notice; | |||||
private List<LatLng> locations; | |||||
private Bitmap image; | |||||
private String pathImage; | |||||
private String pathLocations; | |||||
private String id; | |||||
private Date time; | |||||
public void setImage(Bitmap image) { | |||||
this.image = image; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
this.id = generateAreaID(title); | |||||
} | |||||
public void setNotice(String notice) { | |||||
this.notice = notice; | |||||
} | |||||
public void setLocations(List<LatLng> locations) { | |||||
this.locations = locations; | |||||
} | |||||
public void setPathImage(String pathImage) { | |||||
this.pathImage = pathImage; | |||||
} | |||||
public void setPathLocations(String pathLocations) { | |||||
this.pathLocations = pathLocations; | |||||
} | |||||
public String getNotice() { | |||||
return notice; | |||||
} | |||||
public String getTitle() { | |||||
return title; | |||||
} | |||||
public Bitmap getImage() { | |||||
return image; | |||||
} | |||||
public List<LatLng> getLocations() { | |||||
return locations; | |||||
} | |||||
public String getId() { | |||||
return id; | |||||
} | |||||
public String getPathImage() { | |||||
return pathImage; | |||||
} | |||||
public String getPathLocations() { | |||||
return pathLocations; | |||||
} | |||||
public OwnArea() | |||||
{ | |||||
} | |||||
public OwnArea(String jsonString){ | |||||
try { | |||||
JSONObject areaObject = new JSONObject(jsonString); | |||||
this.title = areaObject.getString("title"); | |||||
this.notice = areaObject.getString("description"); | |||||
this.id = areaObject.getString("id"); | |||||
this.time = new Date(areaObject.getString("time")); | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(this.getClass().getSimpleName(), "earthquakeJSON " + jsonString); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
private String generateAreaID(String title) | |||||
{ | |||||
String id = title.replaceAll(" ", "_") + "_" + new Date().getTime(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "new ID: " + id); | |||||
} | |||||
return id; | |||||
} | |||||
/** | |||||
* Returns OwnArea as JSONObject. | |||||
* | |||||
* @return the mapped object or null, if parsing fails | |||||
*/ | |||||
public JSONObject toJSONObject() { | |||||
JSONObject object = new JSONObject(); | |||||
try { | |||||
object.put("title",this.title); | |||||
object.put("description",this.notice); | |||||
object.put("id",this.id); | |||||
if (this.time != null) | |||||
{ | |||||
object.put("time", this.time); | |||||
} | |||||
else | |||||
{ | |||||
object.put("time", new Date().getTime()); | |||||
} | |||||
JSONObject locations = new JSONObject(); | |||||
Long count = Long.valueOf(0); | |||||
//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()); | |||||
} | |||||
object.put("locations", locations.toString()); | |||||
return object; | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(this.getClass().getSimpleName(), | |||||
String.format("Error while parsing epiColorDto to JSONObject. Values of epiColorDto: %s", this.toString())); | |||||
} | |||||
return null; | |||||
} | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "OwnArea{" + | |||||
"title='" + title + '\'' + | |||||
", notice='" + notice + '\'' + | |||||
", pathImage='" + pathImage + '\'' + | |||||
", pathLocations='" + pathLocations + '\'' + | |||||
", id='" + id + '\'' + | |||||
'}'; | |||||
} | |||||
} |
package com.example.meinwald.ui.main.map; | package com.example.meinwald.ui.main.map; | ||||
import android.Manifest; | |||||
import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||
import android.graphics.Bitmap; | |||||
import android.graphics.BitmapFactory; | |||||
import android.location.Location; | import android.location.Location; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.os.IBinder; | |||||
import android.preference.PreferenceManager; | import android.preference.PreferenceManager; | ||||
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 android.view.ViewGroup; | import android.view.ViewGroup; | ||||
import android.widget.ListView; | |||||
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.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.CameraUpdateFactory; | import com.google.android.gms.maps.CameraUpdateFactory; | ||||
import com.google.android.gms.maps.GoogleMap; | import com.google.android.gms.maps.GoogleMap; | ||||
import com.google.android.gms.maps.OnMapReadyCallback; | import com.google.android.gms.maps.OnMapReadyCallback; | ||||
import com.google.android.gms.maps.SupportMapFragment; | import com.google.android.gms.maps.SupportMapFragment; | ||||
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.MarkerOptions; | |||||
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.JSONException; | |||||
import java.io.File; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
import androidx.core.app.ActivityCompat; | import androidx.core.app.ActivityCompat; | ||||
import androidx.core.content.ContextCompat; | import androidx.core.content.ContextCompat; | ||||
*/ | */ | ||||
private Location mLastKnownLocation; | private Location mLastKnownLocation; | ||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* TASKS | |||||
*/ | |||||
private List<OwnTask> allTasks; | |||||
private static final String KEY_ALL_TASKS = "allTasks"; | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* STORAGEE | |||||
*/ | |||||
private static final int READ_EXTERNAL_STORAGE_CODE = 200; | |||||
private static final int WRITE_EXTERNAL_STORAGE_CODE = 201; | |||||
private boolean mReadStorageGranted; | |||||
private boolean mWriteStorageGranted; | |||||
/** | /** | ||||
* 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 view to inflate | //get view to inflate | ||||
View root = inflater.inflate(fragment_map, container, false); | View root = inflater.inflate(fragment_map, container, false); | ||||
//get storage permission | |||||
getReadStoragePermission(); | |||||
//get tasks | |||||
allTasks = readTasksFromPreferences(); | |||||
//display map fragment | //display map fragment | ||||
SupportMapFragment mapFragment = new SupportMapFragment(); | SupportMapFragment mapFragment = new SupportMapFragment(); | ||||
FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); | FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); | ||||
mLocationPermissionGranted = true; | mLocationPermissionGranted = true; | ||||
} | } | ||||
} | } | ||||
case READ_EXTERNAL_STORAGE_CODE: { | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
mReadStorageGranted = true; | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
e.printStackTrace(); | e.printStackTrace(); | ||||
} | } | ||||
} | } | ||||
for (OwnTask task: allTasks) | |||||
{ | |||||
MarkerOptions marker = new MarkerOptions(); | |||||
//set options | |||||
marker.position(new LatLng(task.getLocation().getLatitude(), task.getLocation().getLongitude())); | |||||
marker.title(task.getTitle()); | |||||
mMap.addMarker(marker); | |||||
} | |||||
} | |||||
/** | |||||
* 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, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getReadStoragePermission() { | |||||
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), | |||||
Manifest.permission.READ_EXTERNAL_STORAGE) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mReadStorageGranted = true; | |||||
} else { | |||||
ActivityCompat.requestPermissions(getActivity(), | |||||
new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, | |||||
READ_EXTERNAL_STORAGE_CODE); | |||||
} | |||||
} | |||||
/** | |||||
* Reads tasks saved in preferences as jsonStrings | |||||
* | |||||
* @return list of OwnTask | |||||
*/ | |||||
private List<OwnTask> readTasksFromPreferences() { | |||||
List<OwnTask> tasks = new ArrayList<>(); | |||||
try { | |||||
String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_ALL_TASKS, "error"); | |||||
if(!"error".equalsIgnoreCase(jsonString)) { | |||||
JSONArray jsonObjects = new JSONArray(jsonString); | |||||
for (int i = 0; i<jsonObjects.length();i++) { | |||||
tasks.add(new OwnTask(jsonObjects.getJSONObject(i))); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "Task loaded from shared preferences: " + tasks.get(i).toString()); | |||||
} | |||||
Bitmap image = BitmapFactory.decodeFile(tasks.get(i).getPathImage() + File.separator + tasks.get(i).getId() + ".jpeg"); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "Image loaded from shared preferences: " + image.getByteCount()); | |||||
} | |||||
tasks.get(i).setImage(image); | |||||
} | |||||
} | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(TAG, "Error while parsing tasks as jsonObjects from preferences"); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
return tasks; | |||||
} | } | ||||
@Override | @Override |
package com.example.meinwald.ui.task; | |||||
import android.graphics.Bitmap; | |||||
import android.location.Location; | |||||
import android.media.Image; | |||||
import android.util.Log; | |||||
import com.example.meinwald.BuildConfig; | |||||
import com.google.android.gms.maps.model.LatLng; | |||||
import org.json.JSONException; | |||||
import org.json.JSONObject; | |||||
import java.util.Date; | |||||
public class OwnTask | |||||
{ | |||||
private String title; | |||||
private String notice; | |||||
private Location location; | |||||
private Bitmap image; | |||||
private String pathImage; | |||||
private String id; | |||||
public OwnTask(String JSONString){ | |||||
try { | |||||
JSONObject taskJSON = new JSONObject(JSONString); | |||||
this.title = taskJSON.getString("title"); | |||||
this.notice = taskJSON.getString("notice"); | |||||
this.location = new Location(""); | |||||
this.location.setLatitude(taskJSON.getDouble("lat")); | |||||
this.location.setLongitude(taskJSON.getDouble("lng")); | |||||
this.pathImage = taskJSON.getString("pathImage"); | |||||
this.id = taskJSON.getString("taskID"); | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(this.getClass().getSimpleName(), "taskJSON: " + JSONString); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
public OwnTask(JSONObject taskJSON){ | |||||
try { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(this.getClass().getSimpleName(), "JSONObject: " + taskJSON.toString()); | |||||
} | |||||
this.title = taskJSON.getString("title"); | |||||
this.notice = taskJSON.getString("notice"); | |||||
this.location = new Location(""); | |||||
this.location.setLatitude(taskJSON.getDouble("lat")); | |||||
this.location.setLongitude(taskJSON.getDouble("lng")); | |||||
this.id = taskJSON.getString("taskID"); | |||||
this.pathImage = taskJSON.getString("taskPATHIMAGE"); | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(this.getClass().getSimpleName(), "taskJSON: " + taskJSON.toString()); | |||||
Log.e(this.getClass().getSimpleName(), "taskJSON Error: " + e.toString()); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
public OwnTask() | |||||
{ | |||||
this.title = null; | |||||
this.notice = null; | |||||
this.location = null; | |||||
this.image = null; | |||||
this.pathImage = null; | |||||
this.id = null; | |||||
} | |||||
public OwnTask(String title, String notice, Location location, Bitmap image, String pathImage) | |||||
{ | |||||
this.title = title; | |||||
this.notice = notice; | |||||
this.location = location; | |||||
this.image = image; | |||||
this.pathImage = pathImage; | |||||
this.id = generateTaskID(title); | |||||
} | |||||
public String getTitle() { | |||||
return title; | |||||
} | |||||
public String getNotice() { | |||||
return notice; | |||||
} | |||||
public Location getLocation() { | |||||
return location; | |||||
} | |||||
public Bitmap getImage() { | |||||
return image; | |||||
} | |||||
public String getPathImage() { return pathImage; } | |||||
public String getId() { return id; } | |||||
public void setTitle(String title) | |||||
{ | |||||
this.id = generateTaskID(title); | |||||
this.title = title; | |||||
} | |||||
public void setNotice(String notice) { | |||||
this.notice = notice; | |||||
} | |||||
public void setLocation(Location location) { | |||||
this.location = location; | |||||
} | |||||
public void setImage(Bitmap image) { | |||||
this.image = image; | |||||
} | |||||
public void setPathImage(String pathImage) { this.pathImage = pathImage; } | |||||
@Override | |||||
public String toString() { | |||||
return "OwnTask{" + | |||||
"title='" + title + '\'' + | |||||
", notice='" + notice + '\'' + | |||||
", location=" + location + '\'' + | |||||
", pathImage=" + pathImage + '\'' + | |||||
", id=" + id + | |||||
'}'; | |||||
} | |||||
private String generateTaskID(String title) | |||||
{ | |||||
String id = title.replaceAll(" ", "_") + "_" + new Date().getTime(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(getClass().getSimpleName(), "new ID: " + id); | |||||
} | |||||
return id; | |||||
} | |||||
/** | |||||
* Returns task as JSONObject. | |||||
* | |||||
* @return the mapped object or null, if parsing fails | |||||
*/ | |||||
public JSONObject toJSONObject() { | |||||
JSONObject object = new JSONObject(); | |||||
try { | |||||
object.put("title",this.title); | |||||
object.put("notice",this.notice); | |||||
object.put("taskPATHIMAGE",this.pathImage); | |||||
object.put("taskID",this.id); | |||||
if (this.location != null) | |||||
{ | |||||
object.put("lat",this.location.getLatitude()); | |||||
object.put("lng",this.location.getLongitude()); | |||||
} | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(this.getClass().getSimpleName(), "JSONObject: " + object.toString()); | |||||
Log.d(this.getClass().getSimpleName(), "Task: " + this.toString()); | |||||
Log.d(this.getClass().getSimpleName(), "path: " + this.getPathImage()); | |||||
Log.d(this.getClass().getSimpleName(), "id: " + this.getId()); | |||||
} | |||||
return object; | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(this.getClass().getSimpleName(), String.format("Error while parsing OwnTask to JSONObject. Values of OwnTask: %s", this.toString())); | |||||
} | |||||
return null; | |||||
} | |||||
} | |||||
} | |||||
package com.example.meinwald.ui.task; | |||||
import android.app.AlertDialog; | |||||
import android.content.Context; | |||||
import android.content.DialogInterface; | |||||
import android.graphics.Rect; | |||||
import android.util.Log; | |||||
import android.view.LayoutInflater; | |||||
import android.view.View; | |||||
import android.view.ViewGroup; | |||||
import android.widget.BaseAdapter; | |||||
import android.widget.ImageView; | |||||
import android.widget.TextView; | |||||
import com.example.meinwald.BuildConfig; | |||||
import com.example.meinwald.R; | |||||
import com.example.meinwald.ui.area.OwnArea; | |||||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import androidx.appcompat.widget.AlertDialogLayout; | |||||
import androidx.appcompat.widget.LinearLayoutCompat; | |||||
import androidx.constraintlayout.widget.ConstraintLayout; | |||||
import static java.security.AccessController.getContext; | |||||
public class TaskAdapter extends BaseAdapter | |||||
{ | |||||
List<OwnTask> taskList; | |||||
LayoutInflater inflater; | |||||
Context context; | |||||
public TaskAdapter(Context applicationContext, List<OwnTask> taskList) | |||||
{ | |||||
this.taskList = new ArrayList<>(); | |||||
this.taskList = taskList; | |||||
this.context = applicationContext; | |||||
inflater = LayoutInflater.from(applicationContext); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
//Log.d("TaskAdapter",taskList.get(0).toString()); | |||||
Log.d("TaskAdapter","size: " + taskList.size()); | |||||
} | |||||
} | |||||
@Override | |||||
public View getView(final int i, View view, final ViewGroup viewGroup) { | |||||
view = inflater.inflate(R.layout.task_element, null); | |||||
final ConstraintLayout elementView = view.findViewById(R.id.taskInfoView); | |||||
final ConstraintLayout infovView = view.findViewById(R.id.taskInfoView); | |||||
final TextView title = (TextView) view.findViewById(R.id.taskInfoTitle); | |||||
final TextView notice = (TextView) view.findViewById(R.id.taskInfoNotice); | |||||
final ImageView icon = (ImageView) view.findViewById(R.id.taskIcon); | |||||
context = view.getContext(); | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d("TaskAdapter",taskList.get(i).toString()); | |||||
Log.d("TaskAdapter",taskList.get(i).getTitle()); | |||||
Log.d("TaskAdapter",taskList.get(i).getNotice()); | |||||
} | |||||
title.setText(taskList.get(i).getTitle()); | |||||
notice.setText(taskList.get(i).getNotice()); | |||||
icon.setImageBitmap(taskList.get(i).getImage()); | |||||
title.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) | |||||
{ | |||||
} | |||||
}); | |||||
notice.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) | |||||
{ | |||||
} | |||||
}); | |||||
icon.setOnClickListener(new View.OnClickListener() { | |||||
@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.image_large, viewGroup, false); | |||||
//viewInflated.setLayoutParams(new AlertDialogLayout.LayoutParams(taskList.get(i).getImage().getWidth(),5 * taskList.get(i).getImage().getHeight())); | |||||
builder.setView(viewInflated); | |||||
final ConstraintLayout imageViewLayout = viewInflated.findViewById(R.id.taskLargeImageLayout); | |||||
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); | |||||
imageView.setImageBitmap(taskList.get(i).getImage()); | |||||
builder.setNegativeButton("Zurück", new DialogInterface.OnClickListener() { | |||||
@Override | |||||
public void onClick(DialogInterface dialog, int which) { | |||||
dialog.cancel(); | |||||
} | |||||
}); | |||||
builder.show(); | |||||
} | |||||
}); | |||||
view.setOnLongClickListener(new View.OnLongClickListener() { | |||||
@Override | |||||
public boolean onLongClick(View v) { | |||||
// TODO Auto-generated method stub | |||||
return true; | |||||
} | |||||
}); | |||||
return view; | |||||
} | |||||
@Override | |||||
public int getCount() { | |||||
return taskList.size(); | |||||
} | |||||
@Override | |||||
public Object getItem(int i) { | |||||
return taskList.get(i); | |||||
} | |||||
@Override | |||||
public long getItemId(int i) { | |||||
return i; | |||||
} | |||||
} |
package com.example.meinwald.ui.task; | package com.example.meinwald.ui.task; | ||||
import android.Manifest; | |||||
import android.app.Activity; | |||||
import android.app.AlertDialog; | import android.app.AlertDialog; | ||||
import android.content.DialogInterface; | import android.content.DialogInterface; | ||||
import android.content.Intent; | |||||
import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||
import android.graphics.Bitmap; | |||||
import android.graphics.BitmapFactory; | |||||
import android.graphics.Color; | |||||
import android.location.Location; | import android.location.Location; | ||||
import android.media.Image; | import android.media.Image; | ||||
import android.os.Build; | |||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.os.Handler; | import android.os.Handler; | ||||
import android.preference.PreferenceManager; | |||||
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 android.view.View; | import android.view.View; | ||||
import android.view.ViewGroup; | import android.view.ViewGroup; | ||||
import android.widget.AdapterView; | |||||
import android.widget.Button; | import android.widget.Button; | ||||
import android.widget.ImageView; | |||||
import android.widget.ListView; | |||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import android.widget.Toast; | import android.widget.Toast; | ||||
import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
import androidx.annotation.RequiresApi; | |||||
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 com.google.android.material.floatingactionbutton.FloatingActionButton; | import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
import com.google.android.material.snackbar.Snackbar; | import com.google.android.material.snackbar.Snackbar; | ||||
import org.json.JSONArray; | |||||
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.lang.reflect.Array; | |||||
import java.nio.ByteBuffer; | |||||
import java.util.ArrayList; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
public class TasksFragment extends Fragment { | public class TasksFragment extends Fragment { | ||||
private static final String TAG = TasksFragment.class.getSimpleName(); | private static final String TAG = TasksFragment.class.getSimpleName(); | ||||
private View root; | |||||
private LayoutInflater layoutInflater; | |||||
private ImageView imageToAdd; | |||||
/** | /** | ||||
* ______________________________________________________________________________________________ | * ______________________________________________________________________________________________ | ||||
* LOCATION | * LOCATION | ||||
*/ | */ | ||||
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; | private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; | ||||
private static final String KEY_LOCATION = "location"; | |||||
/** | /** | ||||
* The entry point to the Fused Location Provider. | * The entry point to the Fused Location Provider. | ||||
*/ | */ | ||||
*/ | */ | ||||
private Location mLastKnownLocation; | private Location mLastKnownLocation; | ||||
private NotificationsViewModel notificationsViewModel; | |||||
public class OwnTask | |||||
{ | |||||
private String title; | |||||
private String notice; | |||||
private Location location; | |||||
private Image image; | |||||
public OwnTask() | |||||
{ | |||||
this.title = null; | |||||
this.notice = null; | |||||
this.location = null; | |||||
this.image = null; | |||||
} | |||||
public OwnTask(String title, String notice, Location location, Image image) | |||||
{ | |||||
this.title = title; | |||||
this.notice = notice; | |||||
this.location = location; | |||||
this.image = image; | |||||
} | |||||
public String getTitle() { | |||||
return title; | |||||
} | |||||
public String getNotice() { | |||||
return notice; | |||||
} | |||||
public Location getLocation() { | |||||
return location; | |||||
} | |||||
public Image getImage() { | |||||
return image; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
} | |||||
public void setNotice(String notice) { | |||||
this.notice = notice; | |||||
} | |||||
public void setLocation(Location location) { | |||||
this.location = location; | |||||
} | |||||
public void setImage(Image image) { | |||||
this.image = image; | |||||
} | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* TASKS | |||||
*/ | |||||
private OwnTask newTask = new OwnTask(); | |||||
private List<OwnTask> allTasks; | |||||
private ListView taskList; | |||||
private static final String KEY_ALL_TASKS = "allTasks"; | |||||
@Override | |||||
public String toString() { | |||||
return "OwnTask{" + | |||||
"title='" + title + '\'' + | |||||
", notice='" + notice + '\'' + | |||||
", location=" + location + | |||||
'}'; | |||||
} | |||||
} | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* CAMERA | |||||
*/ | |||||
private static final int MY_CAMERA_PERMISSION_CODE = 100; | |||||
private boolean mCameraPermissionGranted; | |||||
private static final int CAMERA_REQUEST = 1888; | |||||
OwnTask newTask = new OwnTask(); | |||||
/** | |||||
* ______________________________________________________________________________________________ | |||||
* STORAGE | |||||
*/ | |||||
private static final int READ_EXTERNAL_STORAGE_CODE = 200; | |||||
private static final int WRITE_EXTERNAL_STORAGE_CODE = 201; | |||||
private boolean mReadStorageGranted; | |||||
private boolean mWriteStorageGranted; | |||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||||
View root = inflater.inflate(R.layout.fragment_tasks, container, false); | |||||
layoutInflater = inflater; | |||||
root = inflater.inflate(R.layout.fragment_tasks, container, false); | |||||
taskList = (ListView) root.findViewById(R.id.taskListView); | |||||
//instance add button | |||||
//instantiate add button | |||||
FloatingActionButton fab = root.findViewById(R.id.fab_tasks); | FloatingActionButton fab = root.findViewById(R.id.fab_tasks); | ||||
allTasks = readTasksFromPreferences(); | |||||
instantiateTaskList(); | |||||
//construct a FusedLocationProviderClient. | //construct a FusedLocationProviderClient. | ||||
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity()); | mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity()); | ||||
//get read storage permission | |||||
getReadStoragePermission(); | |||||
//get location permission | //get location permission | ||||
getLocationPermission(); | getLocationPermission(); | ||||
public void onClick(View view) { | public void onClick(View view) { | ||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | ||||
newTask = new OwnTask(); | |||||
//check permissions | |||||
getDeviceLocation(); | getDeviceLocation(); | ||||
getCameraPPermission(); | |||||
getWriteStoragePPermission(); | |||||
final View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.task_input, (ViewGroup) getView(), false); | final View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.task_input, (ViewGroup) getView(), false); | ||||
builder.setView(viewInflated); | builder.setView(viewInflated); | ||||
imageToAdd = viewInflated.findViewById(R.id.taskImage); | |||||
//set location | //set location | ||||
final Button buttonSetLocation = viewInflated.findViewById(R.id.taskSetLocation); | final Button buttonSetLocation = viewInflated.findViewById(R.id.taskSetLocation); | ||||
final TextView locationText = viewInflated.findViewById(R.id.taskLocation); | final TextView locationText = viewInflated.findViewById(R.id.taskLocation); | ||||
buttonSetLocation.setOnClickListener(new View.OnClickListener() { | buttonSetLocation.setOnClickListener(new View.OnClickListener() { | ||||
public void onClick(View v) { | public void onClick(View v) { | ||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "add Location!"); | |||||
} | |||||
getLocationPermission(); | getLocationPermission(); | ||||
getDeviceLocation(); | getDeviceLocation(); | ||||
buttonAddPicture.setOnClickListener(new View.OnClickListener() { | buttonAddPicture.setOnClickListener(new View.OnClickListener() { | ||||
public void onClick(View v) { | public void onClick(View v) { | ||||
// Code here executes on main thread after user presses button | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "add Picture!"); | |||||
} | |||||
if (!mCameraPermissionGranted) | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Camera permission not granted!"); | |||||
} | |||||
getCameraPPermission(); | |||||
} | |||||
else | |||||
{ | |||||
if (BuildConfig.DEBUG) | |||||
{ | |||||
Log.d(TAG, "Camera permission granted!"); | |||||
} | |||||
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); | |||||
startActivityForResult(cameraIntent, CAMERA_REQUEST); | |||||
} | |||||
} | } | ||||
}); | }); | ||||
final TextView titleView = viewInflated.findViewById(R.id.taskTitleUserInput); | final TextView titleView = viewInflated.findViewById(R.id.taskTitleUserInput); | ||||
final TextView noticeView = viewInflated.findViewById(R.id.taskNoticeUserInput); | final TextView noticeView = viewInflated.findViewById(R.id.taskNoticeUserInput); | ||||
if (titleView.getText()!=null) | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "new title: " + titleView.getText()); | |||||
} | |||||
if (titleView.getText().length()>0) | |||||
{ | { | ||||
//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())); | ||||
boolean result = allTasks.add(newTask); | |||||
if (BuildConfig.DEBUG) | if (BuildConfig.DEBUG) | ||||
{ | { | ||||
Log.d(TAG, "new Task: " + newTask.toString()); | Log.d(TAG, "new Task: " + newTask.toString()); | ||||
Log.d(TAG, "add new task result: " + result); | |||||
/** | |||||
for (OwnTask task: allTasks) | |||||
{ | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, task.toString()); | |||||
} | |||||
} | |||||
**/ | |||||
} | } | ||||
instantiateTaskList(); | |||||
dialog.dismiss(); | dialog.dismiss(); | ||||
//confirm added task | //confirm added task | ||||
return root; | return root; | ||||
} | } | ||||
@Override | |||||
public void onPause() | |||||
{ | |||||
super.onPause(); | |||||
emptyPreferencesAndSaveTasksToPreferences(); | |||||
} | |||||
/** | |||||
* Saves tasks to preferences | |||||
*/ | |||||
private void emptyPreferencesAndSaveTasksToPreferences() { | |||||
if (!allTasks.isEmpty()) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "allTasks not empty!"); | |||||
for (OwnTask task: allTasks) | |||||
{ | |||||
Log.d(TAG, task.toString()); | |||||
} | |||||
} | |||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().remove(KEY_ALL_TASKS).commit(); | |||||
JSONArray writeObjects = new JSONArray(); | |||||
for (OwnTask task: allTasks) | |||||
{ | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, task.toString()); | |||||
} | |||||
} | |||||
for (OwnTask task: allTasks) | |||||
{ | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "save task: " + task.toString()); | |||||
} | |||||
if (task.getImage() != null) | |||||
{ | |||||
//save image to external storage and save path | |||||
String path = saveReceivedImage(task.getImage(), task.getId()); | |||||
task.setPathImage(path); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "saved image with path: " + task.getPathImage()); | |||||
} | |||||
} | |||||
JSONObject object = task.toJSONObject(); | |||||
writeObjects.put(object); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, object.toString()); | |||||
} | |||||
} | |||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_ALL_TASKS, writeObjects.toString()).commit(); | |||||
} | |||||
} | |||||
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 | |||||
* | |||||
* @return list of OwnTask | |||||
*/ | |||||
private List<OwnTask> readTasksFromPreferences() { | |||||
List<OwnTask> tasks = new ArrayList<>(); | |||||
try { | |||||
String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_ALL_TASKS, "error"); | |||||
if(!"error".equalsIgnoreCase(jsonString)) { | |||||
JSONArray jsonObjects = new JSONArray(jsonString); | |||||
for (int i = 0; i<jsonObjects.length();i++) { | |||||
tasks.add(new OwnTask(jsonObjects.getJSONObject(i))); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "Task loaded from shared preferences: " + tasks.get(i).toString()); | |||||
} | |||||
Bitmap image = BitmapFactory.decodeFile(tasks.get(i).getPathImage() + File.separator + tasks.get(i).getId() + ".jpeg"); | |||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "Image loaded from shared preferences: " + image.getByteCount()); | |||||
} | |||||
tasks.get(i).setImage(image); | |||||
} | |||||
} | |||||
} catch (JSONException e) { | |||||
if (BuildConfig.DEBUG) { | |||||
Log.e(TAG, "Error while parsing tasks as jsonObjects from preferences"); | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
return tasks; | |||||
} | |||||
/** | |||||
* Get all stored tasks and save them temporary. | |||||
*/ | |||||
public void instantiateTaskList() | |||||
{ | |||||
final TaskAdapter adapter = new TaskAdapter(getActivity().getApplicationContext(),allTasks); | |||||
taskList.setAdapter(adapter); | |||||
//initialise onClickListeners | |||||
taskList.setOnItemClickListener(new AdapterView.OnItemClickListener() { | |||||
@Override | |||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { | |||||
//for (int j = 0; j < adapterView.getChildCount(); j++) | |||||
//adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT); | |||||
// change the background color of the selected element | |||||
//view.setBackgroundColor(Color.LTGRAY); | |||||
//adapterView.setSelection(i); | |||||
}}); | |||||
} | |||||
/** | /** | ||||
* Request location permission, so that we can get the location of the device. | * Request location permission, so that we can get the location of the device. | ||||
* The result of the permission request is handled by a callback, | * The result of the permission request is handled by a callback, | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Request camera permission, so that we can get an image from the camera. | |||||
* The result of the permission request is handled by a callback, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getCameraPPermission() { | |||||
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), | |||||
Manifest.permission.CAMERA) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mCameraPermissionGranted = true; | |||||
} else { | |||||
ActivityCompat.requestPermissions(getActivity(), | |||||
new String[]{android.Manifest.permission.CAMERA}, | |||||
MY_CAMERA_PERMISSION_CODE); | |||||
} | |||||
} | |||||
/** | |||||
* 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, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getReadStoragePermission() { | |||||
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), | |||||
Manifest.permission.READ_EXTERNAL_STORAGE) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mReadStorageGranted = true; | |||||
} else { | |||||
ActivityCompat.requestPermissions(getActivity(), | |||||
new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, | |||||
READ_EXTERNAL_STORAGE_CODE); | |||||
} | |||||
} | |||||
/** | |||||
* 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, | |||||
* onRequestPermissionsResult. | |||||
* | |||||
*/ | |||||
private void getWriteStoragePPermission() { | |||||
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), | |||||
Manifest.permission.WRITE_EXTERNAL_STORAGE) | |||||
== PackageManager.PERMISSION_GRANTED) { | |||||
mWriteStorageGranted = true; | |||||
} else { | |||||
ActivityCompat.requestPermissions(getActivity(), | |||||
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, | |||||
WRITE_EXTERNAL_STORAGE_CODE); | |||||
} | |||||
} | |||||
/** | /** | ||||
* DOCU ME! | * DOCU ME! | ||||
* TOOD: What are grant results etc for? | * TOOD: What are grant results etc for? | ||||
@Override | @Override | ||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) | ||||
{ | { | ||||
if (BuildConfig.DEBUG) { | |||||
Log.d(TAG, "onRequestPermissionResult Code: " + requestCode); | |||||
} | |||||
mLocationPermissionGranted = false; | mLocationPermissionGranted = false; | ||||
switch (requestCode) { | switch (requestCode) { | ||||
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: { | case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: { | ||||
mLocationPermissionGranted = true; | mLocationPermissionGranted = true; | ||||
} | } | ||||
} | } | ||||
case MY_CAMERA_PERMISSION_CODE: { | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
mCameraPermissionGranted = true; | |||||
} | |||||
} | |||||
case READ_EXTERNAL_STORAGE_CODE: { | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
mReadStorageGranted = true; | |||||
} | |||||
} | |||||
case WRITE_EXTERNAL_STORAGE_CODE: { | |||||
if (grantResults.length > 0 | |||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||||
mWriteStorageGranted = true; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT) | |||||
@Override | |||||
public void onActivityResult(int requestCode, int resultCode, Intent data) | |||||
{ | |||||
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) | |||||
{ | |||||
Bitmap photo = (Bitmap) data.getExtras().get("data"); | |||||
newTask.setImage(photo); | |||||
newTask.setPathImage(saveReceivedImage(photo,newTask.getId())); | |||||
if (imageToAdd != null && photo != null) | |||||
{ | |||||
imageToAdd.setImageBitmap(photo); | |||||
} | |||||
} | } | ||||
} | } | ||||
<?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:id="@+id/areaElement" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
android:clickable="true" | |||||
android:focusable="true" | |||||
android:focusableInTouchMode="true" | |||||
android:longClickable="true" | |||||
android:orientation="horizontal"> | |||||
<TextView | |||||
android:id="@+id/areaInfoTitle" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="30dp" | |||||
android:layout_gravity="left" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:clickable="false" | |||||
android:focusable="false" | |||||
android:textColor="@android:color/primary_text_light" | |||||
android:textSize="22sp" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:id="@+id/areaInfoView" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:clickable="false" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:orientation="horizontal" | |||||
android:visibility="visible" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="1.0" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/areaInfoTitle" | |||||
tools:visibility="visible"> | |||||
<ImageView | |||||
android:id="@+id/areaIcon" | |||||
android:layout_width="150dp" | |||||
android:layout_height="150dp" | |||||
android:layout_marginBottom="5dp" | |||||
android:clickable="true" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:src="@android:drawable/ic_menu_camera" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:srcCompat="@android:drawable/ic_menu_camera" /> | |||||
<TextView | |||||
android:id="@+id/areaInfoNotice" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_gravity="left" | |||||
android:clickable="false" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:textColor="@android:color/primary_text_light" | |||||
android:textSize="12sp" | |||||
android:visibility="visible" | |||||
app:layout_constraintEnd_toStartOf="@+id/taskIcon" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
android:id="@+id/layout_area_root" | |||||
android:layout_width="fill_parent" | |||||
android:layout_height="fill_parent" | |||||
android:orientation="vertical" | |||||
android:padding="10dp" > | |||||
<TextView | |||||
android:id="@+id/areaTitle" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="Grundstück" | |||||
android:textAppearance="?android:attr/textAppearanceLarge" /> | |||||
<EditText | |||||
android:id="@+id/areaTitleUserInput" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:hint="Titel eingeben!"> | |||||
<requestFocus /> | |||||
</EditText> | |||||
<TextView | |||||
android:id="@+id/areaNotice" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="Beschreibung" | |||||
android:textAppearance="?android:attr/textAppearanceLarge" /> | |||||
<EditText | |||||
android:id="@+id/areaNoticeUserInput" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="149dp" | |||||
android:hint="Beschreibung eingeben!" | |||||
android:isScrollContainer="true"> | |||||
<requestFocus /> | |||||
</EditText> | |||||
<Button | |||||
android:id="@+id/areaStartTracking" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:text="Grundstücksaufnahme Starten!" /> | |||||
<Button | |||||
android:id="@+id/areaStopTracking" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:text="Grundstücksaufnahme Beenden!" | |||||
android:visibility="invisible"/> | |||||
</LinearLayout> |
android:layout_height="match_parent" | android:layout_height="match_parent" | ||||
tools:context=".ui.area.AreaFragment"> | tools:context=".ui.area.AreaFragment"> | ||||
<TextView | |||||
android:id="@+id/text_areas" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="8dp" | |||||
android:layout_marginTop="8dp" | |||||
android:layout_marginEnd="8dp" | |||||
android:textAlignment="center" | |||||
android:textSize="20sp" | |||||
<ListView | |||||
android:id="@+id/areaListView" | |||||
android:layout_width="0dp" | |||||
android:layout_height="0dp" | |||||
android:layout_marginStart="1dp" | |||||
android:layout_marginLeft="1dp" | |||||
android:layout_marginEnd="1dp" | |||||
android:layout_marginRight="1dp" | |||||
android:choiceMode="singleChoice" | |||||
android:listSelector="@color/selectionBackground" | |||||
app:layout_constraintBottom_toBottomOf="parent" | app:layout_constraintBottom_toBottomOf="parent" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" | |||||
android:gravity="center_horizontal" /> | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<com.google.android.material.floatingactionbutton.FloatingActionButton | <com.google.android.material.floatingactionbutton.FloatingActionButton | ||||
android:id="@+id/fab_areas" | android:id="@+id/fab_areas" |
android:layout_height="match_parent" | android:layout_height="match_parent" | ||||
tools:context=".ui.task.TasksFragment"> | tools:context=".ui.task.TasksFragment"> | ||||
<TextView | |||||
android:id="@+id/text_tasks" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="8dp" | |||||
android:layout_marginTop="8dp" | |||||
android:layout_marginEnd="8dp" | |||||
android:textAlignment="center" | |||||
android:layout_gravity="center_horizontal" | |||||
android:textSize="20sp" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<com.google.android.material.floatingactionbutton.FloatingActionButton | <com.google.android.material.floatingactionbutton.FloatingActionButton | ||||
android:id="@+id/fab_tasks" | android:id="@+id/fab_tasks" | ||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
app:rippleColor="#00000000" | app:rippleColor="#00000000" | ||||
app:srcCompat="@android:drawable/ic_menu_add" /> | app:srcCompat="@android:drawable/ic_menu_add" /> | ||||
<ListView | |||||
android:id="@+id/taskListView" | |||||
android:layout_width="0dp" | |||||
android:layout_height="0dp" | |||||
android:layout_marginStart="1dp" | |||||
android:layout_marginLeft="1dp" | |||||
android:layout_marginEnd="1dp" | |||||
android:layout_marginRight="1dp" | |||||
android:choiceMode="singleChoice" | |||||
android:listSelector="@color/selectionBackground" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | </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:id="@+id/taskLargeImageLayout" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintStart_toEndOf="parent" | |||||
android:layout_alignParentTop="true" | |||||
android:layout_alignParentBottom="true" | |||||
android:orientation="vertical"> | |||||
<ImageView | |||||
android:id="@+id/taskLargeImage" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:scaleType="fitXY" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="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" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:id="@+id/taskElement" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
android:clickable="true" | |||||
android:focusable="true" | |||||
android:focusableInTouchMode="true" | |||||
android:longClickable="true" | |||||
android:orientation="horizontal"> | |||||
<TextView | |||||
android:id="@+id/taskInfoTitle" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="30dp" | |||||
android:layout_gravity="left" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginTop="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:clickable="false" | |||||
android:focusable="false" | |||||
android:textColor="@android:color/primary_text_light" | |||||
android:textSize="22sp" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:id="@+id/taskInfoView" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:clickable="false" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:orientation="horizontal" | |||||
android:visibility="visible" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="1.0" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/taskInfoTitle" | |||||
tools:visibility="visible"> | |||||
<ImageView | |||||
android:id="@+id/taskIcon" | |||||
android:layout_width="150dp" | |||||
android:layout_height="150dp" | |||||
android:layout_marginBottom="5dp" | |||||
android:clickable="true" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:src="@android:drawable/ic_menu_camera" | |||||
android:visibility="visible" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:srcCompat="@android:drawable/ic_menu_camera" /> | |||||
<TextView | |||||
android:id="@+id/taskInfoNotice" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:layout_gravity="left" | |||||
android:clickable="false" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:textColor="@android:color/primary_text_light" | |||||
android:textSize="12sp" | |||||
android:visibility="visible" | |||||
app:layout_constraintEnd_toStartOf="@+id/taskIcon" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:text="Bild hinzufügen!" /> | android:text="Bild hinzufügen!" /> | ||||
<ImageView | |||||
android:id="@+id/taskImage" | |||||
android:layout_width="243dp" | |||||
android:layout_height="149dp" | |||||
android:layout_gravity="center" | |||||
android:baselineAlignBottom="true" | |||||
android:foregroundGravity="center_vertical|center_horizontal" | |||||
app:srcCompat="@android:drawable/ic_menu_camera" /> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="309dp" | |||||
android:layout_marginStart="5dp" | |||||
android:layout_marginLeft="0dp" | |||||
android:layout_marginTop="5dp" | |||||
android:layout_marginEnd="5dp" | |||||
android:layout_marginRight="5dp" | |||||
android:layout_marginBottom="5dp" | |||||
android:clickable="false" | |||||
android:focusable="false" | |||||
android:focusableInTouchMode="false" | |||||
android:isScrollContainer="true" | |||||
android:orientation="horizontal" | |||||
android:visibility="visible" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="1.0" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/taskInfoTitle"> | |||||
<ImageView | |||||
android:id="@+id/taskImage" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_gravity="center" | |||||
android:baselineAlignBottom="true" | |||||
android:foregroundGravity="center_vertical|center_horizontal" | |||||
android:scaleType="fitXY" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:srcCompat="@android:drawable/ic_menu_camera" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</LinearLayout> | </LinearLayout> |
<color name="colorPrimary">#1B5E20</color> | <color name="colorPrimary">#1B5E20</color> | ||||
<color name="colorPrimaryDark">#3700B3</color> | <color name="colorPrimaryDark">#3700B3</color> | ||||
<color name="colorAccent">#03DAC5</color> | <color name="colorAccent">#03DAC5</color> | ||||
<color name="selectionBackground">#c0edc3</color> | |||||
</resources> | </resources> |
<item name="colorAccent">@color/colorAccent</item> | <item name="colorAccent">@color/colorAccent</item> | ||||
</style> | </style> | ||||
<style name="ImageTheme" parent="android:Theme.Dialog"> | |||||
<item name="android:layout_width">match_parent</item> | |||||
<item name="android:layout_height">match_parent</item> | |||||
<item name="android:layout_marginTop">20dp</item> | |||||
<item name="android:layout_marginBottom">20dp</item> | |||||
<item name="android:layout_marginLeft">10dp</item> | |||||
<item name="android:layout_marginRight">10dp</item> | |||||
<!-- No backgrounds, titles or window float --> | |||||
<item name="android:windowNoTitle">true</item> | |||||
<item name="android:windowIsFloating">false</item> | |||||
</style> | |||||
</resources> | </resources> |