diff --git a/.idea/misc.xml b/.idea/misc.xml
index b82c61c..6395638 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,6 +4,7 @@
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 0000000..2e9b1d7
Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/it/danieleverducci/ojo/Settings.java b/app/src/main/java/it/danieleverducci/ojo/Settings.java
new file mode 100644
index 0000000..c0599a0
--- /dev/null
+++ b/app/src/main/java/it/danieleverducci/ojo/Settings.java
@@ -0,0 +1,74 @@
+package it.danieleverducci.ojo;
+
+import android.content.Context;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import it.danieleverducci.ojo.entities.Camera;
+
+/**
+ * Manages the settings persistence
+ */
+public class Settings {
+ private static final String FILENAME = "settings.bin";
+ private static final String TAG = "Settings";
+
+ private volatile String settingsFilePath;
+ private List cameras = new ArrayList<>();
+
+ public static Settings fromDisk(Context context) {
+ String filePath = context.getFilesDir() + File.separator + FILENAME;
+ Settings s = new Settings();
+ try {
+ FileInputStream fin = new FileInputStream(filePath);
+ ObjectInputStream ois = new ObjectInputStream(fin);
+ s = (Settings) ois.readObject();
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "No saved settings found, will create a new one");
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to load settings from disk: " + e.toString());
+ } catch (ClassNotFoundException e) {
+ Log.e(TAG, e.toString());
+ }
+ s.settingsFilePath = filePath;
+ return s;
+ }
+
+ public List getCameras() {
+ return cameras;
+ }
+
+ public void setCameras(List cameras) {
+ this.cameras = cameras;
+ }
+
+ public void addCamera(Camera camera) {
+ this.cameras.add(camera);
+ }
+
+ public boolean save() {
+ try {
+ FileOutputStream fout = new FileOutputStream(settingsFilePath);
+ ObjectOutputStream oos = new ObjectOutputStream(fout);
+ oos.writeObject(this);
+ fout.close();
+ oos.close();
+ return true;
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Unable to create file " + settingsFilePath + ": " + e.toString());
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to save settings: " + e.toString());
+ }
+ return false;
+ }
+}
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/AddStreamFragment.java b/app/src/main/java/it/danieleverducci/ojo/ui/AddStreamFragment.java
index 2da7994..d8e63cd 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/AddStreamFragment.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/AddStreamFragment.java
@@ -9,7 +9,12 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
+import com.google.android.material.snackbar.Snackbar;
+
+import it.danieleverducci.ojo.R;
+import it.danieleverducci.ojo.Settings;
import it.danieleverducci.ojo.databinding.FragmentAddStreamBinding;
+import it.danieleverducci.ojo.entities.Camera;
public class AddStreamFragment extends Fragment {
@@ -29,13 +34,32 @@ public class AddStreamFragment extends Fragment {
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
-// binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
-// @Override
-// public void onClick(View view) {
-// NavHostFragment.findNavController(AddStreamFragment.this)
-// .navigate(R.id.action_SecondFragment_to_FirstFragment);
-// }
-// });
+ binding.save.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ // Check the field is filled
+ String url = binding.streamUrl.getText().toString();
+ if (!url.startsWith("rtsp://")) {
+ Snackbar.make(view, R.string.add_stream_invalid_url, Snackbar.LENGTH_LONG)
+ .setAction(R.string.add_stream_invalid_url_dismiss, null).show();
+ return;
+ }
+
+ // Load existing settings (if any)
+ Settings settings = Settings.fromDisk(getContext());
+ // Add stream to list
+ settings.addCamera(new Camera("", url));
+ // Save
+ if (!settings.save()) {
+ Snackbar.make(view, R.string.add_stream_error_saving, Snackbar.LENGTH_LONG).show();
+ return;
+ }
+
+ // Back to first fragment
+ NavHostFragment.findNavController(AddStreamFragment.this)
+ .navigate(R.id.action_SecondFragment_to_FirstFragment);
+ }
+ });
}
@Override
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 4b9e923..1542681 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java
@@ -30,13 +30,19 @@ public class MainActivity extends AppCompatActivity {
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
+ // Show FAB only on first fragment
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
+ navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
+ if (destination.getId() == R.id.FirstFragment)
+ binding.fab.show();
+ else
+ binding.fab.hide();
+ });
binding.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
- .setAction("Action", null).show();
+ navController.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
}
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/SurveillanceFragment.java b/app/src/main/java/it/danieleverducci/ojo/ui/SurveillanceFragment.java
index 3c8f974..ac04e90 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/SurveillanceFragment.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/SurveillanceFragment.java
@@ -28,6 +28,7 @@ import java.util.Arrays;
import java.util.List;
import it.danieleverducci.ojo.R;
+import it.danieleverducci.ojo.Settings;
import it.danieleverducci.ojo.databinding.FragmentSurveillanceBinding;
import it.danieleverducci.ojo.entities.Camera;
@@ -70,18 +71,19 @@ public class SurveillanceFragment extends Fragment implements MediaPlayer.EventL
// Start stream on surface view 1
+ Settings settings = Settings.fromDisk(getContext());
+ List cc = settings.getCameras();
-
- List cc = new ArrayList<>();
- String rtspUrl = "rtsp://admin:Du4gdtPmXGCWT29@192.168.1.200:554/Streaming/Channels/101";
- Camera camera = new Camera("Camera 1", rtspUrl);
- cc.add(camera);
- rtspUrl = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
- camera = new Camera("Bunny", rtspUrl);
- cc.add(camera);
- rtspUrl = "rtsp://demo:demo@ipvmdemo.dyndns.org:5541/onvif-media/media.amp?profile=profile_1_h264&sessiontimeout=60&streamtype=unicast";
- camera = new Camera("Ipvm Demo", rtspUrl);
- cc.add(camera);
+// List cc = new ArrayList<>();
+// String rtspUrl = "rtsp://admin:Du4gdtPmXGCWT29@192.168.1.200:554/Streaming/Channels/101";
+// Camera camera = new Camera("Camera 1", rtspUrl);
+// cc.add(camera);
+// rtspUrl = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
+// camera = new Camera("Bunny", rtspUrl);
+// cc.add(camera);
+// rtspUrl = "rtsp://demo:demo@ipvmdemo.dyndns.org:5541/onvif-media/media.amp?profile=profile_1_h264&sessiontimeout=60&streamtype=unicast";
+// camera = new Camera("Ipvm Demo", rtspUrl);
+// cc.add(camera);
int elemsPerSide = calcGridSideElements(cc.size());
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 2b068d1..0000000
--- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index 07d5da9..0000000
--- a/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..8c276c2
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_add_stream.xml b/app/src/main/res/layout/fragment_add_stream.xml
index a2587d0..68b5ce4 100644
--- a/app/src/main/res/layout/fragment_add_stream.xml
+++ b/app/src/main/res/layout/fragment_add_stream.xml
@@ -1,28 +1,23 @@
-
-
-
+ android:text="@string/add_stream_placeholder_url"/>
-
\ No newline at end of file
+ android:layout_marginTop="50dp"
+ android:text="@string/add_stream_save"/>
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index eca70cf..7353dbd 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index eca70cf..7353dbd 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index a571e60..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index 61da551..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index c41dd28..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index db5080a..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 6dba46d..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index da31a87..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 15ac681..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index b216f2d..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index f25a419..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index e96783c..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..68aeafa
--- /dev/null
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #6200EE
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7011e51..a0c5b63 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -7,6 +7,9 @@
Next
Previous
- Hello first fragment
- Hello second fragment. Arg: %1$s
+ rtsp://username:password@192.168.1.123:554
+ Save
+ Invalid RTSP url
+ Dismiss
+ An error has occurred while saving configuration
\ No newline at end of file