diff --git a/.idea/misc.xml b/.idea/misc.xml
index 1af431a..90fb734 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,6 +7,7 @@
+
diff --git a/app/build.gradle b/app/build.gradle
index a8b9649..5358535 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,7 +8,7 @@ android {
defaultConfig {
applicationId "it.danieleverducci.ojo"
- minSdkVersion 17
+ minSdkVersion 21
targetSdkVersion 30
versionCode 3
versionName "0.0.3"
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
index 5346148..358fea4 100644
--- a/app/release/output-metadata.json
+++ b/app/release/output-metadata.json
@@ -10,8 +10,8 @@
{
"type": "SINGLE",
"filters": [],
- "versionCode": 1,
- "versionName": "0.0.1",
+ "versionCode": 2,
+ "versionName": "0.0.2",
"outputFile": "app-release.apk"
}
]
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1edacc3..aa10715 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,8 +14,8 @@
-
+ android:theme="@style/Theme.Ojo"
+ android:configChanges="orientation|screenSize">
diff --git a/app/src/main/java/it/danieleverducci/ojo/Settings.java b/app/src/main/java/it/danieleverducci/ojo/CamerasSettings.java
similarity index 90%
rename from app/src/main/java/it/danieleverducci/ojo/Settings.java
rename to app/src/main/java/it/danieleverducci/ojo/CamerasSettings.java
index 84dcad3..eca7fe0 100644
--- a/app/src/main/java/it/danieleverducci/ojo/Settings.java
+++ b/app/src/main/java/it/danieleverducci/ojo/CamerasSettings.java
@@ -13,27 +13,26 @@ import java.io.ObjectOutputStream;
import java.io.Serializable;
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 implements Serializable {
+public class CamerasSettings implements Serializable {
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) {
+ public static CamerasSettings fromDisk(Context context) {
String filePath = context.getFilesDir() + File.separator + FILENAME;
- Settings s = new Settings();
+ CamerasSettings s = new CamerasSettings();
try {
FileInputStream fin = new FileInputStream(filePath);
ObjectInputStream ois = new ObjectInputStream(fin);
- s = (Settings) ois.readObject();
+ s = (CamerasSettings) ois.readObject();
} catch (FileNotFoundException e) {
Log.d(TAG, "No saved settings found, will create a new one");
} catch (IOException e) {
diff --git a/app/src/main/java/it/danieleverducci/ojo/SharedPreferencesManager.java b/app/src/main/java/it/danieleverducci/ojo/SharedPreferencesManager.java
new file mode 100644
index 0000000..02ab136
--- /dev/null
+++ b/app/src/main/java/it/danieleverducci/ojo/SharedPreferencesManager.java
@@ -0,0 +1,18 @@
+package it.danieleverducci.ojo;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class SharedPreferencesManager {
+ private static final String SP_ROTATION_ENABLED = "rot_en";
+
+ public static void saveRotationEnabled(Context ctx, boolean enabled) {
+ SharedPreferences sharedPref = ctx.getSharedPreferences(SP_ROTATION_ENABLED, Context.MODE_PRIVATE);
+ sharedPref.edit().putBoolean(SP_ROTATION_ENABLED, enabled).apply();
+ }
+
+ public static boolean loadRotationEnabled(Context ctx) {
+ SharedPreferences sharedPref = ctx.getSharedPreferences(SP_ROTATION_ENABLED, Context.MODE_PRIVATE);
+ return sharedPref.getBoolean(SP_ROTATION_ENABLED, false);
+ }
+}
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/InfoFragment.java b/app/src/main/java/it/danieleverducci/ojo/ui/InfoFragment.java
new file mode 100644
index 0000000..6394b64
--- /dev/null
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/InfoFragment.java
@@ -0,0 +1,18 @@
+package it.danieleverducci.ojo.ui;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.fragment.app.Fragment;
+
+import it.danieleverducci.ojo.databinding.FragmentInfoBinding;
+
+
+public class InfoFragment extends Fragment {
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ return FragmentInfoBinding.inflate(inflater, container, false).getRoot();
+ }
+}
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 157826c..50d4d8b 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/MainActivity.java
@@ -1,5 +1,6 @@
package it.danieleverducci.ojo.ui;
+import android.content.pm.ActivityInfo;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
@@ -11,6 +12,7 @@ import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import it.danieleverducci.ojo.R;
+import it.danieleverducci.ojo.SharedPreferencesManager;
import it.danieleverducci.ojo.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
@@ -18,11 +20,15 @@ public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private NavController navController;
+ private boolean rotationEnabledSetting;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ rotationEnabledSetting = SharedPreferencesManager.loadRotationEnabled(this);
+ this.setRequestedOrientation(this.rotationEnabledSetting ? ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@@ -58,4 +64,13 @@ public class MainActivity extends AppCompatActivity {
else
navController.navigate(actionId);
}
+
+ public boolean getRotationEnabledSetting() {
+ return this.rotationEnabledSetting;
+ }
+
+ public void toggleRotationEnabledSetting() {
+ this.rotationEnabledSetting = !this.rotationEnabledSetting;
+ this.setRequestedOrientation(this.rotationEnabledSetting ? ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ }
}
\ 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 a4b35d8..2acaf34 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/SettingsFragment.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/SettingsFragment.java
@@ -1,13 +1,14 @@
package it.danieleverducci.ojo.ui;
-import android.content.Context;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
-import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -20,7 +21,8 @@ import android.view.ViewGroup;
import java.util.List;
import it.danieleverducci.ojo.R;
-import it.danieleverducci.ojo.Settings;
+import it.danieleverducci.ojo.CamerasSettings;
+import it.danieleverducci.ojo.SharedPreferencesManager;
import it.danieleverducci.ojo.databinding.FragmentSettingsItemListBinding;
import it.danieleverducci.ojo.entities.Camera;
import it.danieleverducci.ojo.ui.adapters.SettingsRecyclerViewAdapter;
@@ -32,7 +34,7 @@ import it.danieleverducci.ojo.utils.ItemMoveCallback;
public class SettingsFragment extends Fragment {
private FragmentSettingsItemListBinding binding;
- private Settings settings;
+ private CamerasSettings camerasSettings;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -44,14 +46,28 @@ public class SettingsFragment extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- // Setup toolbar and register for item click
+ // Setup toolbar
+ binding.settingsToolbar.getOverflowIcon().setTint(Color.WHITE);
binding.settingsToolbar.inflateMenu(R.menu.settings_menu);
+ MenuItem rotMenuItem = binding.settingsToolbar.getMenu().findItem(R.id.menuitem_allow_rotation);
+ rotMenuItem.setTitle(((MainActivity)getActivity()).getRotationEnabledSetting() ? R.string.menuitem_deny_rotation : R.string.menuitem_allow_rotation);
+
+ // Register for item click
binding.settingsToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- if (item.getItemId() == R.id.menuitem_add_camera) {
- ((MainActivity)getActivity()).navigateToFragment(R.id.action_settingsToCameraUrl);
- return true;
+ switch (item.getItemId()) {
+ case R.id.menuitem_add_camera:
+ ((MainActivity)getActivity()).navigateToFragment(R.id.action_settingsToCameraUrl);
+ return true;
+ case R.id.menuitem_allow_rotation:
+ ((MainActivity)getActivity()).toggleRotationEnabledSetting();
+ SharedPreferencesManager.saveRotationEnabled(getContext(), ((MainActivity)getActivity()).getRotationEnabledSetting());
+ item.setTitle(((MainActivity)getActivity()).getRotationEnabledSetting() ? R.string.menuitem_deny_rotation : R.string.menuitem_allow_rotation);
+ return true;
+ case R.id.menuitem_info:
+ ((MainActivity)getActivity()).navigateToFragment(R.id.action_SettingsToInfoFragment);
+ return true;
}
return false;
}
@@ -63,8 +79,8 @@ public class SettingsFragment extends Fragment {
super.onResume();
// Load cameras
- settings = Settings.fromDisk(getContext());
- List cams = settings.getCameras();
+ camerasSettings = CamerasSettings.fromDisk(getContext());
+ List cams = camerasSettings.getCameras();
// Set the adapter
RecyclerView recyclerView = binding.list;
@@ -93,7 +109,7 @@ public class SettingsFragment extends Fragment {
// Save cameras
List cams = ((SettingsRecyclerViewAdapter)binding.list.getAdapter()).getItems();
- this.settings.setCameras(cams);
- this.settings.save();
+ this.camerasSettings.setCameras(cams);
+ this.camerasSettings.save();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/it/danieleverducci/ojo/ui/StreamUrlFragment.java b/app/src/main/java/it/danieleverducci/ojo/ui/StreamUrlFragment.java
index 75a2a27..c0a1ea5 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/StreamUrlFragment.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/StreamUrlFragment.java
@@ -13,7 +13,7 @@ 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.CamerasSettings;
import it.danieleverducci.ojo.databinding.FragmentAddStreamBinding;
import it.danieleverducci.ojo.entities.Camera;
@@ -21,7 +21,7 @@ public class StreamUrlFragment extends Fragment {
public static final String ARG_CAMERA = "arg_camera";
private FragmentAddStreamBinding binding;
- private Settings settings;
+ private CamerasSettings camerasSettings;
private Integer selectedCamera = null;
@Override
@@ -29,7 +29,7 @@ public class StreamUrlFragment extends Fragment {
super.onCreate(savedInstanceState);
// Load existing settings (if any)
- settings = Settings.fromDisk(getContext());
+ camerasSettings = CamerasSettings.fromDisk(getContext());
}
@Override
@@ -45,7 +45,7 @@ public class StreamUrlFragment extends Fragment {
if (args != null && args.containsKey(ARG_CAMERA)) {
this.selectedCamera = args.getInt(ARG_CAMERA);
- Camera c = settings.getCameras().get(this.selectedCamera);
+ Camera c = camerasSettings.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());
@@ -74,16 +74,16 @@ public class StreamUrlFragment extends Fragment {
if (StreamUrlFragment.this.selectedCamera != null) {
// Update camera
- Camera c = settings.getCameras().get(StreamUrlFragment.this.selectedCamera);
+ Camera c = camerasSettings.getCameras().get(StreamUrlFragment.this.selectedCamera);
c.setName(name);
c.setRtspUrl(url);
} else {
// Add stream to list
- settings.addCamera(new Camera(name, url));
+ camerasSettings.addCamera(new Camera(name, url));
}
// Save
- if (!settings.save()) {
+ if (!camerasSettings.save()) {
Snackbar.make(view, R.string.add_stream_error_saving, Snackbar.LENGTH_LONG).show();
return;
}
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 88e66bf..753ddc2 100644
--- a/app/src/main/java/it/danieleverducci/ojo/ui/SurveillanceFragment.java
+++ b/app/src/main/java/it/danieleverducci/ojo/ui/SurveillanceFragment.java
@@ -28,7 +28,7 @@ import java.util.Arrays;
import java.util.List;
import it.danieleverducci.ojo.R;
-import it.danieleverducci.ojo.Settings;
+import it.danieleverducci.ojo.CamerasSettings;
import it.danieleverducci.ojo.databinding.FragmentSurveillanceBinding;
import it.danieleverducci.ojo.entities.Camera;
import it.danieleverducci.ojo.utils.DpiUtils;
@@ -123,7 +123,7 @@ public class SurveillanceFragment extends Fragment {
private void addAllCameras() {
- Settings settings = Settings.fromDisk(getContext());
+ CamerasSettings settings = CamerasSettings.fromDisk(getContext());
List cc = settings.getCameras();
int elemsPerSide = calcGridSideElements(cc.size());
diff --git a/app/src/main/res/layout/fragment_add_stream.xml b/app/src/main/res/layout/fragment_add_stream.xml
index ae7db5d..1d48507 100644
--- a/app/src/main/res/layout/fragment_add_stream.xml
+++ b/app/src/main/res/layout/fragment_add_stream.xml
@@ -57,48 +57,6 @@
android:layout_marginTop="30dp"
android:text="@string/add_stream_save"/>
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_info.xml b/app/src/main/res/layout/fragment_info.xml
new file mode 100644
index 0000000..318a66b
--- /dev/null
+++ b/app/src/main/res/layout/fragment_info.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_settings_item_list.xml b/app/src/main/res/layout/fragment_settings_item_list.xml
index df78bee..cc757cc 100644
--- a/app/src/main/res/layout/fragment_settings_item_list.xml
+++ b/app/src/main/res/layout/fragment_settings_item_list.xml
@@ -11,13 +11,14 @@
android:layout_height="wrap_content"
android:id="@+id/settingsToolbar"
app:title="@string/app_name"
- style="@style/ToolBarStyle"/>
+ style="@style/ToolBarStyle" />
\ 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 9ee6946..42a12ed 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -36,5 +36,12 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index c0d3625..142cb26 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -10,13 +10,15 @@
rtsp://username:password@192.168.1.123:554
Nome della IP Camera
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
+ 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.
+ Allow screen rotation
+ Landscape only
+ Info
+ Aggiungi
Informazioni su Ojo
Creato da Daniele Verducci.
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 08ba789..e222c51 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -9,13 +9,15 @@
rtsp://username:password@192.168.1.123:554
Camera name
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
+ 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.
+ Allow screen rotation
+ Landscape only
+ Info
+ Add
About Ojo
Created by Daniele Verducci.
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 5e96b3c..19c3f4a 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -12,9 +12,11 @@
- @color/purple_500
- @color/purple_700
- @color/white
+
+ - @color/white
-