diff --git a/.idea/misc.xml b/.idea/misc.xml
index a52e9fd..b6581c9 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,10 +4,11 @@
diff --git a/app/src/main/java/it/danieleverducci/ojo/entities/Camera.java b/app/src/main/java/it/danieleverducci/ojo/entities/Camera.java
index 3a1512f..dbee900 100644
--- a/app/src/main/java/it/danieleverducci/ojo/entities/Camera.java
+++ b/app/src/main/java/it/danieleverducci/ojo/entities/Camera.java
@@ -11,6 +11,14 @@ public class Camera implements Serializable {
this.rtspUrl = rtspUrl;
}
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setRtspUrl(String rtspUrl) {
+ this.rtspUrl = rtspUrl;
+ }
+
public String getName() {
return name;
}
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java b/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java
index 1f4b5c8..157826c 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java
@@ -44,11 +44,18 @@ public class MainActivity extends AppCompatActivity {
}
public void navigateToFragment(int actionId) {
+ navigateToFragment(actionId, null);
+ }
+
+ public void navigateToFragment(int actionId, Bundle bundle) {
if (navController == null) {
Log.e(TAG, "Not initialized");
return;
}
- navController.navigate(actionId);
+ if (bundle != null)
+ navController.navigate(actionId, bundle);
+ else
+ navController.navigate(actionId);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/SettingsFragment.java b/app/src/main/java/it/danieleverducci/ojo/ui/SettingsFragment.java
index f542a94..ed4f8d8 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/SettingsFragment.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/SettingsFragment.java
@@ -3,6 +3,8 @@ package it.danieleverducci.ojo.ui;
import android.content.Context;
import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
@@ -10,6 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -17,6 +20,7 @@ import java.util.List;
import it.danieleverducci.ojo.R;
import it.danieleverducci.ojo.Settings;
+import it.danieleverducci.ojo.databinding.FragmentSettingsItemListBinding;
import it.danieleverducci.ojo.entities.Camera;
import it.danieleverducci.ojo.ui.adapters.SettingsRecyclerViewAdapter;
import it.danieleverducci.ojo.utils.ItemMoveCallback;
@@ -26,43 +30,51 @@ import it.danieleverducci.ojo.utils.ItemMoveCallback;
*/
public class SettingsFragment extends Fragment {
- public SettingsFragment() {
- }
-
- public static SettingsFragment newInstance() {
- SettingsFragment fragment = new SettingsFragment();
- return fragment;
- }
+ private FragmentSettingsItemListBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_settings_item_list, container, false);
+ binding = FragmentSettingsItemListBinding.inflate(inflater, container, false);
// Load cameras
Settings settings = Settings.fromDisk(getContext());
List cams = settings.getCameras();
// Set the adapter
- if (view instanceof RecyclerView) {
- Context context = view.getContext();
- RecyclerView recyclerView = (RecyclerView) view;
- recyclerView.setLayoutManager(new LinearLayoutManager(context));
- SettingsRecyclerViewAdapter adapter = new SettingsRecyclerViewAdapter(cams);
- ItemTouchHelper.Callback callback =
- new ItemMoveCallback(adapter);
- ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
- touchHelper.attachToRecyclerView(recyclerView);
- adapter.setOnDragListener(touchHelper::startDrag);
- recyclerView.setAdapter(adapter);
- // Onclick listener
- adapter.setOnClickListener(new SettingsRecyclerViewAdapter.OnClickListener() {
- @Override
- public void onItemClick(Camera c) {
- ((MainActivity)getActivity()).navigateToFragment(R.id.action_homeToSettings);
- }
- });
+ RecyclerView recyclerView = binding.list;
+ recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+ SettingsRecyclerViewAdapter adapter = new SettingsRecyclerViewAdapter(cams);
+ ItemTouchHelper.Callback callback =
+ new ItemMoveCallback(adapter);
+ ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
+ touchHelper.attachToRecyclerView(recyclerView);
+ adapter.setOnDragListener(touchHelper::startDrag);
+ recyclerView.setAdapter(adapter);
+ // Onclick listener
+ adapter.setOnClickListener(new SettingsRecyclerViewAdapter.OnClickListener() {
+ @Override
+ public void onItemClick(int pos) {
+ Bundle b = new Bundle();
+ b.putInt(StreamUrlFragment.ARG_CAMERA, pos);
+ ((MainActivity)getActivity()).navigateToFragment(R.id.action_settingsToCameraUrl, b);
+ }
+ });
+
+ return binding.getRoot();
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ binding.settingsToolbar.inflateMenu(R.menu.settings_menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ if (item.getItemId() == R.id.menuitem_add_camera) {
+ ((MainActivity)getActivity()).navigateToFragment(R.id.action_settingsToCameraUrl);
+ return true;
}
- return view;
+ return super.onOptionsItemSelected(item);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/AddStreamFragment.java b/app/src/main/java/it/danieleverducci/ojo/ui/StreamUrlFragment.java
similarity index 55%
rename from app/src/main/java/it/danieleverducci/ojo/ui/AddStreamFragment.java
rename to app/src/main/java/it/danieleverducci/ojo/ui/StreamUrlFragment.java
index 6a66925..75a2a27 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/AddStreamFragment.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/StreamUrlFragment.java
@@ -6,6 +6,7 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
@@ -16,9 +17,20 @@ import it.danieleverducci.ojo.Settings;
import it.danieleverducci.ojo.databinding.FragmentAddStreamBinding;
import it.danieleverducci.ojo.entities.Camera;
-public class AddStreamFragment extends Fragment {
+public class StreamUrlFragment extends Fragment {
+ public static final String ARG_CAMERA = "arg_camera";
private FragmentAddStreamBinding binding;
+ private Settings settings;
+ private Integer selectedCamera = null;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load existing settings (if any)
+ settings = Settings.fromDisk(getContext());
+ }
@Override
public View onCreateView(
@@ -27,6 +39,18 @@ public class AddStreamFragment extends Fragment {
) {
binding = FragmentAddStreamBinding.inflate(inflater, container, false);
+
+ // If passed an url, fill the details
+ Bundle args = getArguments();
+ if (args != null && args.containsKey(ARG_CAMERA)) {
+ this.selectedCamera = args.getInt(ARG_CAMERA);
+
+ Camera c = settings.getCameras().get(this.selectedCamera);
+ binding.streamName.setText(c.getName());
+ binding.streamName.setHint(getContext().getString(R.string.stream_list_default_camera_name).replace("{camNo}", (this.selectedCamera+1)+""));
+ binding.streamUrl.setText(c.getRtspUrl());
+ }
+
return binding.getRoot();
}
@@ -45,10 +69,19 @@ public class AddStreamFragment extends Fragment {
return;
}
- // Load existing settings (if any)
- Settings settings = Settings.fromDisk(getContext());
- // Add stream to list
- settings.addCamera(new Camera("", url));
+ // Name can be empty
+ String name = binding.streamName.getText().toString();
+
+ if (StreamUrlFragment.this.selectedCamera != null) {
+ // Update camera
+ Camera c = settings.getCameras().get(StreamUrlFragment.this.selectedCamera);
+ c.setName(name);
+ c.setRtspUrl(url);
+ } else {
+ // Add stream to list
+ settings.addCamera(new Camera(name, url));
+ }
+
// Save
if (!settings.save()) {
Snackbar.make(view, R.string.add_stream_error_saving, Snackbar.LENGTH_LONG).show();
@@ -56,7 +89,7 @@ public class AddStreamFragment extends Fragment {
}
// Back to first fragment
- NavHostFragment.findNavController(AddStreamFragment.this)
+ NavHostFragment.findNavController(StreamUrlFragment.this)
.popBackStack();
}
});
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/adapters/SettingsRecyclerViewAdapter.java b/app/src/main/java/it/danieleverducci/ojo/ui/adapters/SettingsRecyclerViewAdapter.java
index 0211aa3..c5dacbe 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/adapters/SettingsRecyclerViewAdapter.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/adapters/SettingsRecyclerViewAdapter.java
@@ -39,12 +39,6 @@ public class SettingsRecyclerViewAdapter extends RecyclerView.Adapter
+
+
+
+
-
\ No newline at end of file
+ android:orientation="vertical">
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_surveillance.xml b/app/src/main/res/layout/fragment_surveillance.xml
index a70f98e..513c984 100644
--- a/app/src/main/res/layout/fragment_surveillance.xml
+++ b/app/src/main/res/layout/fragment_surveillance.xml
@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- tools:context=".ui.AddStreamFragment"
+ tools:context=".ui.StreamUrlFragment"
android:background="@color/purple_500">
diff --git a/app/src/main/res/menu/settings_menu.xml b/app/src/main/res/menu/settings_menu.xml
new file mode 100644
index 0000000..d9ab9f2
--- /dev/null
+++ b/app/src/main/res/menu/settings_menu.xml
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index 11b6d44..9ee6946 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -17,7 +17,7 @@
First Fragment
Second Fragment
- Videocamera n°{camNo}
+ Videocamera senza nome n°{camNo}
rtsp://username:password@192.168.1.123:554
+ Nome della IP Camera
Inserisci l\'url dello stream RTSP della tua IP Camera. Nota che questo differisce tra un modello e l\'altro. Consulta il pannello di configurazione o il manuale della tua IP Camera.
Salva
L\'URL RTSP non è valido
Chiudi
Si è verificato un errore durante il salvataggio della configurazione.
+ Aggiungi
+
Informazioni su Ojo
Creato da Daniele Verducci.
Questa app è rilasciata sotto licenza GNU GENERAL PUBLIC LICENSE v3+. Puoi ottenerne una copia qui: https://raw.githubusercontent.com/penguin86/ojo/master/LICENSE
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a7bdbb7..6758831 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -4,15 +4,18 @@
First Fragment
Second Fragment
- Camera {camNo}
+ Unnamed camera {camNo}
rtsp://username:password@192.168.1.123:554
+ Camera name
Please insert your camera\'s RTSP stream. Note that the URL differs from camera to camera: you can find the complete URL in your camera\'s settings or user manual.
Save
Invalid RTSP url
Dismiss
An error has occurred while saving configuration
+ Add
+
About Ojo
Created by Daniele Verducci.
This application is licensed under the GNU GENERAL PUBLIC LICENSE v3+. You can obtain a copy here: https://raw.githubusercontent.com/penguin86/ojo/master/LICENSE
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 7ce18d5..31f47b3 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -14,4 +14,6 @@
- @color/white
+
+
\ No newline at end of file