diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index 0b803370d..935810c29 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -57,7 +57,7 @@ jobs:
# Run Instrumentation Tests in Firebase Test Lab
- name: Run Instrumentation Tests in Firebase Test Lab
- run: gcloud firebase test android run --type instrumentation --app ${{ env.module_app }}/build/outputs/apk/debug/${{ env.module_app }}-debug.apk --test ${{ env.module_app }}/build/outputs/apk/androidTest/debug/${{ env.module_app }}-debug-androidTest.apk --device model=oriole,version=31,locale=en,orientation=portrait
+ run: gcloud firebase test android run --type instrumentation --app ${{ env.module_app }}/build/outputs/apk/debug/${{ env.module_app }}-debug.apk --test ${{ env.module_app }}/build/outputs/apk/androidTest/debug/${{ env.module_app }}-debug-androidTest.apk --device model=akita,version=34,locale=en,orientation=portrait
##########################################
diff --git a/app/build.gradle b/app/build.gradle
index 1793a984e..4affd9652 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,14 +2,16 @@ apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.crashlytics'
android {
- compileSdkVersion 34
+ compileSdk 34
useLibrary 'org.apache.http.legacy'
defaultConfig {
applicationId "org.glpi.inventory.agent"
minSdkVersion 21
targetSdkVersion 34
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ multiDexEnabled true
}
testOptions {
@@ -28,19 +30,10 @@ android {
}
}
- dexOptions {
- preDexLibraries true
- maxProcessCount 8
- }
-
namespace 'org.glpi.inventory.agent'
lint {
abortOnError false
}
-
- defaultConfig {
- multiDexEnabled true
- }
}
dependencies {
@@ -63,8 +56,8 @@ dependencies {
androidTestImplementation 'tools.fastlane:screengrab:2.1.1'
- testImplementation 'org.mockito:mockito-core:2.18.3'
- androidTestImplementation 'org.mockito:mockito-android:2.18.3'
+ testImplementation 'org.mockito:mockito-android:5.5.0' // Use the latest version
+ androidTestImplementation 'org.mockito:mockito-android:5.5.0'
implementation 'androidx.test.espresso:espresso-idling-resource:3.6.1'
implementation fileTree(dir: 'libs', include: ['*.jar'])
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index eaaae5d1a..372a35889 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,10 +1,11 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ android:versionCode="39413"
+ android:versionName="">
+
@@ -30,9 +31,6 @@ android:versionName="">
-
-
-
@@ -56,12 +54,6 @@ android:versionName="">
-
-
-
-
-
-
@@ -72,21 +64,19 @@ android:versionName="">
-
-
-
-
-
+
+
-
-
@@ -96,4 +86,4 @@ android:versionName="">
-
+
\ No newline at end of file
diff --git a/app/src/main/java/org/glpi/inventory/agent/broadcast/BootStartAgent.java b/app/src/main/java/org/glpi/inventory/agent/broadcast/BootStartAgent.java
index 1315fa1a5..f173c667a 100644
--- a/app/src/main/java/org/glpi/inventory/agent/broadcast/BootStartAgent.java
+++ b/app/src/main/java/org/glpi/inventory/agent/broadcast/BootStartAgent.java
@@ -38,53 +38,16 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Build;
-import android.preference.PreferenceManager;
-import android.widget.Toast;
-
-import org.flyve.inventory.InventoryLog;
-import org.glpi.inventory.agent.service.InventoryService;
import org.glpi.inventory.agent.ui.ActivityMain;
-import org.glpi.inventory.agent.utils.AgentLog;
public class BootStartAgent extends BroadcastReceiver {
- TimeAlarm alarm = new TimeAlarm();
-
- /**
- * It sets an alarm after the user has finished booting
- * @param context in which the receiver is running
- * @param intent being received
- */
@Override
public void onReceive(Context context, Intent intent) {
-
- String action = intent.getAction();
- if(action==null) {
- return;
+ if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ Intent activityIntent = new Intent(context, ActivityMain.class);
+ activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(activityIntent);
}
-
- SharedPreferences customSharedPreference = PreferenceManager.getDefaultSharedPreferences(context);
- if (customSharedPreference.getBoolean("boot", false)) {
- try {
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- Intent myIntent = new Intent(context, InventoryService.class);
- context.startForegroundService(myIntent);
- } else {
- Intent myIntent = new Intent(context, ActivityMain.class);
- myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(myIntent);
- }
- }catch(Exception ex) {
- Toast.makeText(context, ex.getMessage(), Toast.LENGTH_LONG).show();
- }
- }
-
- if(customSharedPreference.getBoolean("autoStartInventory", false)){
- alarm.setAlarm(context);
- }
-
}
}
diff --git a/app/src/main/java/org/glpi/inventory/agent/broadcast/InventoryJobScheduler.java b/app/src/main/java/org/glpi/inventory/agent/broadcast/InventoryJobScheduler.java
new file mode 100644
index 000000000..4172d2295
--- /dev/null
+++ b/app/src/main/java/org/glpi/inventory/agent/broadcast/InventoryJobScheduler.java
@@ -0,0 +1,204 @@
+/**
+ * ---------------------------------------------------------------------
+ * GLPI Android Inventory Agent
+ * Copyright (C) 2019 Teclib.
+ *
+ * https://glpi-project.org
+ *
+ * Based on Flyve MDM Inventory Agent For Android
+ * Copyright © 2018 Teclib. All rights reserved.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * LICENSE
+ *
+ * This file is part of GLPI Android Inventory Agent.
+ *
+ * GLPI Android Inventory Agent is a subproject of GLPI.
+ *
+ * GLPI Android Inventory Agent is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * GLPI Android Inventory Agent is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * ---------------------------------------------------------------------
+ * @copyright Copyright © 2019 Teclib. All rights reserved.
+ * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
+ * @link https://github.com/glpi-project/android-inventory-agent
+ * @link https://glpi-project.org/glpi-network/
+ * ---------------------------------------------------------------------
+ */
+
+package org.glpi.inventory.agent.broadcast;
+
+import android.annotation.SuppressLint;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+
+import androidx.core.app.NotificationCompat;
+
+import org.flyve.inventory.InventoryTask;
+import org.glpi.inventory.agent.R;
+import org.glpi.inventory.agent.schema.ServerSchema;
+import org.glpi.inventory.agent.ui.ActivityMain;
+import org.glpi.inventory.agent.utils.AgentLog;
+import org.glpi.inventory.agent.utils.Helpers;
+import org.glpi.inventory.agent.utils.HttpInventory;
+import org.glpi.inventory.agent.utils.LocalPreferences;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+
+@SuppressLint("SpecifyJobSchedulerIdRange")
+public class InventoryJobScheduler extends JobService {
+
+ public static final int INVENTORY_JOB_ID = 4492015;
+ private static final String NOTIFICATION_CHANNEL_ID = "org.glpi.inventory.agent";
+
+ @Override
+ public boolean onStartJob(final JobParameters params) {
+ HandlerThread handlerThread = new HandlerThread("SomeOtherThread");
+ handlerThread.start();
+
+ Handler handler = new Handler(handlerThread.getLooper());
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Run task" + Calendar.getInstance().getTime());
+ doInventory();
+ jobFinished(params, true);
+ }
+ });
+
+ return true;
+ }
+
+ private void doInventory() {
+ Context context = getApplicationContext();
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Launch inventory from JobScheduler " + Calendar.getInstance().getTime());
+
+ // check if autoStartInventory is deactivated
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ if (!sharedPreferences.getBoolean("autoStartInventory", false)) {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : The inventory will not be send, is deactivated");
+ return;
+ }
+
+ showPersistentNotification();
+
+ final InventoryTask inventory = new InventoryTask(context.getApplicationContext(), Helpers.getAgentDescription(context), true);
+ final HttpInventory httpInventory = new HttpInventory(context.getApplicationContext());
+ ArrayList serverArray = new LocalPreferences(context).loadServer();
+ if (!serverArray.isEmpty()) {
+ for (final String serverName : serverArray) {
+ final ServerSchema model = httpInventory.setServerModel(serverName);
+ inventory.setTag(model.getTag());
+ inventory.setAssetItemtype(model.getItemtype());
+ inventory.getXML(new InventoryTask.OnTaskCompleted() {
+ @Override
+ public void onTaskSuccess(String data) {
+ ServerSchema model = httpInventory.setServerModel(serverName);
+ if(!model.getSerial().trim().isEmpty()) {
+ data = data.replaceAll("(.*)","" + model.getSerial() + "");
+ }
+ httpInventory.sendInventory(data, model, new HttpInventory.OnTaskCompleted() {
+ @Override
+ public void onTaskSuccess(String data) {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Inventory Success");
+ Helpers.sendToNotificationBar(context.getApplicationContext(), context.getResources().getString(R.string.inventory_notification_sent));
+ //Helpers.sendAnonymousData(context.getApplicationContext(), inventory);
+ }
+
+ @Override
+ public void onTaskError(String error) {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Inventory error");
+ Helpers.sendToNotificationBar(context.getApplicationContext(), context.getResources().getString(R.string.inventory_notification_fail));
+ AgentLog.e(error);
+ }
+ });
+ }
+
+ @Override
+ public void onTaskError(Throwable error) {
+ AgentLog.e(error.getMessage());
+ Helpers.sendToNotificationBar(context, context.getResources().getString(R.string.inventory_notification_fail));
+ }
+ });
+ }
+ } else {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : " + context.getResources().getString(R.string.inventory_no_server));
+ }
+ }
+
+ @Override
+ public boolean onStopJob(final JobParameters params) {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : onStopJob() was called");
+ return true;
+ }
+
+ private void showPersistentNotification() {
+ NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // create channel if needed
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+ NotificationChannel chan = null;
+ chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, getString(R.string.app_is_running), NotificationManager.IMPORTANCE_DEFAULT);
+ chan.setLightColor(Color.BLUE);
+ chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
+ manager.createNotificationChannel(chan);
+ }
+
+ // create intent to redirect to notification to settings
+ Intent notificationIntent;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ notificationIntent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+ notificationIntent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
+ notificationIntent.putExtra(Settings.EXTRA_CHANNEL_ID, NOTIFICATION_CHANNEL_ID);
+ notificationIntent.putExtra("app_package", getPackageName());
+ notificationIntent.putExtra("app_uid", getApplicationInfo().uid);
+ notificationIntent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
+ } else {
+ notificationIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ notificationIntent.setData(Uri.parse("package:" + getPackageName()));
+ }
+ PendingIntent notificationPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
+
+
+ Intent appIntent = new Intent(this, ActivityMain.class);
+ appIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ PendingIntent appIntentRedirect = PendingIntent.getActivity(this, 0, appIntent, PendingIntent.FLAG_IMMUTABLE);
+
+ // create notification
+ NotificationCompat.Builder notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
+ notification.setOngoing(false);
+ notification.setSmallIcon(R.drawable.ic_stat);
+ notification.setContentTitle(getString(R.string.app_is_running));
+ notification.setContentText(getString(R.string.agent_description));
+ notification.setCategory(Notification.CATEGORY_EVENT);
+ notification.setPriority(NotificationCompat.PRIORITY_DEFAULT);
+ notification.setStyle(new NotificationCompat.BigTextStyle().bigText(getString(R.string.app_is_running_extend)));
+ notification.setContentIntent(appIntentRedirect);
+ notification.addAction(R.drawable.ic_stat, getString(R.string.disable_notification), notificationPendingIntent);
+
+ // notify
+ manager.notify(1, notification.build());
+ }
+}
diff --git a/app/src/main/java/org/glpi/inventory/agent/broadcast/TimeAlarm.java b/app/src/main/java/org/glpi/inventory/agent/broadcast/TimeAlarm.java
deleted file mode 100644
index 360d92aba..000000000
--- a/app/src/main/java/org/glpi/inventory/agent/broadcast/TimeAlarm.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * ---------------------------------------------------------------------
- * GLPI Android Inventory Agent
- * Copyright (C) 2019 Teclib.
- *
- * https://glpi-project.org
- *
- * Based on Flyve MDM Inventory Agent For Android
- * Copyright © 2018 Teclib. All rights reserved.
- *
- * ---------------------------------------------------------------------
- *
- * LICENSE
- *
- * This file is part of GLPI Android Inventory Agent.
- *
- * GLPI Android Inventory Agent is a subproject of GLPI.
- *
- * GLPI Android Inventory Agent is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * GLPI Android Inventory Agent is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * ---------------------------------------------------------------------
- * @copyright Copyright © 2019 Teclib. All rights reserved.
- * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
- * @link https://github.com/glpi-project/android-inventory-agent
- * @link https://glpi-project.org/glpi-network/
- * ---------------------------------------------------------------------
- */
-
-package org.glpi.inventory.agent.broadcast;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Build;
-import android.os.PowerManager;
-import android.preference.PreferenceManager;
-
-import androidx.annotation.RequiresApi;
-
-import org.flyve.inventory.InventoryTask;
-import org.glpi.inventory.agent.R;
-import org.glpi.inventory.agent.schema.ServerSchema;
-import org.glpi.inventory.agent.utils.AgentLog;
-import org.glpi.inventory.agent.utils.Helpers;
-import org.glpi.inventory.agent.utils.HttpInventory;
-import org.glpi.inventory.agent.utils.LocalPreferences;
-
-import java.util.ArrayList;
-
-public class TimeAlarm extends BroadcastReceiver {
-
- /**
- * If the success XML is created, it sends the inventory
- * @param context in which the receiver is running
- * @param intent being received
- */
- @Override
- public void onReceive(final Context context, Intent intent) {
-
- // check if is deactivated
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- Boolean val = sharedPreferences.getBoolean("autoStartInventory", false);
- if (!val) {
- AgentLog.d("The inventory will not be send, is deactivated");
- return;
- }
-
- AgentLog.d("Launch inventory from alarm");
-
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
- wl.acquire();
-
- final InventoryTask inventory = new InventoryTask(context.getApplicationContext(), Helpers.getAgentDescription(context), true);
- final HttpInventory httpInventory = new HttpInventory(context.getApplicationContext());
- ArrayList serverArray = new LocalPreferences(context).loadServer();
- if (!serverArray.isEmpty()) {
- for (final String serverName : serverArray) {
- final ServerSchema model = httpInventory.setServerModel(serverName);
- inventory.setTag(model.getTag());
- inventory.setAssetItemtype(model.getItemtype());
- inventory.getXML(new InventoryTask.OnTaskCompleted() {
- @Override
- public void onTaskSuccess(String data) {
- ServerSchema model = httpInventory.setServerModel(serverName);
- if(!model.getSerial().trim().isEmpty()) {
- data = data.replaceAll("(.*)","" + model.getSerial() + "");
- }
- httpInventory.sendInventory(data, model, new HttpInventory.OnTaskCompleted() {
- @Override
- public void onTaskSuccess(String data) {
- Helpers.sendToNotificationBar(context.getApplicationContext(), context.getResources().getString(R.string.inventory_notification_sent));
- //Helpers.sendAnonymousData(context.getApplicationContext(), inventory);
- }
-
- @Override
- public void onTaskError(String error) {
- Helpers.sendToNotificationBar(context.getApplicationContext(), context.getResources().getString(R.string.inventory_notification_fail));
- AgentLog.e(error);
- }
- });
- }
-
- @Override
- public void onTaskError(Throwable error) {
- AgentLog.e(error.getMessage());
- Helpers.sendToNotificationBar(context, context.getResources().getString(R.string.inventory_notification_fail));
- }
- });
- }
- } else {
- AgentLog.e(context.getResources().getString(R.string.inventory_no_server));
- }
-
- wl.release();
- }
-
- /**
- * Schedules the alarm
- * @param context
- */
- @RequiresApi(api = Build.VERSION_CODES.M)
- public void setAlarm(Context context) {
-
- AgentLog.d("Set Alarm");
-
- AlarmManager am =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
- Intent i = new Intent(context, TimeAlarm.class);
- i.setAction("org.glpi.inventory.agent.ALARM");
- PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_IMMUTABLE);
-
- SharedPreferences customSharedPreference = PreferenceManager.getDefaultSharedPreferences(context);
- String timeInventory = customSharedPreference.getString("timeInventory", "Week");
-
- int time = 60 * 1000;
-
- if (timeInventory.equals("Day")) {
- time = 24 * 60 * 60 * 1000;
- AgentLog.d("Alarm Daily");
- } else if(timeInventory.equals("Week")) {
- time = 7 * 24 * 60 * 60 * 1000;
- AgentLog.d("Alarm Weekly");
- } else if(timeInventory.equals("Month")) {
- time = 30 * 24 * 60 * 60 * 1000;
- AgentLog.d("Alarm Monthly");
- }
-
- try {
- am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), time, pi);
- } catch (NullPointerException ex) {
- AgentLog.e(ex.getMessage());
- }
- }
-
- /**
- * Removes the alarm with a matching argument
- * @param context
- */
- public void cancelAlarm(Context context) {
- Intent intent = new Intent(context, TimeAlarm.class);
- PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
- AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- alarmManager.cancel(sender);
- }
-}
diff --git a/app/src/main/java/org/glpi/inventory/agent/core/home/Home.java b/app/src/main/java/org/glpi/inventory/agent/core/home/Home.java
index bf30bead0..81cfbc314 100644
--- a/app/src/main/java/org/glpi/inventory/agent/core/home/Home.java
+++ b/app/src/main/java/org/glpi/inventory/agent/core/home/Home.java
@@ -54,14 +54,12 @@ interface Presenter {
void showError(String message);
// Models
- void doBindService(Activity activity);
void setupList(Activity activity, ListView lst);
void clickItem(final Activity activity, HomeSchema homeSchema);
List getListItems();
}
interface Model {
- void doBindService(Activity activity);
void setupList(Activity activity, ListView lst);
void clickItem(final Activity activity, HomeSchema homeSchema);
List getListItems();
diff --git a/app/src/main/java/org/glpi/inventory/agent/core/home/HomeModel.java b/app/src/main/java/org/glpi/inventory/agent/core/home/HomeModel.java
index b4b89e3e8..d6635ce6c 100644
--- a/app/src/main/java/org/glpi/inventory/agent/core/home/HomeModel.java
+++ b/app/src/main/java/org/glpi/inventory/agent/core/home/HomeModel.java
@@ -36,22 +36,15 @@
package org.glpi.inventory.agent.core.home;
import android.app.Activity;
-import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
-import android.os.Build;
-import android.util.Log;
import android.widget.ListView;
import org.glpi.inventory.agent.R;
import org.glpi.inventory.agent.adapter.HomeAdapter;
import org.glpi.inventory.agent.preference.GlobalParametersPreference;
import org.glpi.inventory.agent.preference.InventoryParametersPreference;
-import org.glpi.inventory.agent.service.InventoryService;
import org.glpi.inventory.agent.ui.ActivityInventoryReport;
import org.glpi.inventory.agent.ui.DialogListServers;
-import org.glpi.inventory.agent.utils.AgentLog;
import java.util.ArrayList;
import java.util.List;
@@ -65,53 +58,6 @@ public HomeModel(Home.Presenter presenter) {
this.presenter = presenter;
}
- public void doBindService(Activity activity) {
- // Establish a connection with the service. We use an explicit
- // class name because we want a specific service implementation that
- // we know will be running in our own process (and thus won't be
- // supporting component replacement by other applications).
- InventoryService inventoryService = new InventoryService();
- Intent mServiceIntent = new Intent(activity, inventoryService.getClass());
- ComponentName result;
-
- if (!isMyServiceRunning(activity, inventoryService.getClass())) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- result = activity.startForegroundService(mServiceIntent);
- } else {
- result = activity.startService(mServiceIntent);
- }
-
- if (result != null) {
- AgentLog.log(this, " Agent started ", Log.INFO);
- } else {
- AgentLog.log(this, " Agent fail", Log.ERROR);
- }
- } else {
- AgentLog.log(this, " Agent already started ", Log.ERROR);
- }
- }
-
- /**
- * Check if the service is running
- * @param serviceClass Class
- * @return boolean
- */
- private boolean isMyServiceRunning(Activity activity, Class> serviceClass) {
- try {
- ActivityManager manager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
- for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
- if (serviceClass.getName().equals(service.service.getClassName())) {
- return true;
- }
- }
- } catch (Exception ex) {
- AgentLog.e(ex.getMessage());
- }
-
- return false;
- }
-
-
@Override
public void setupList(Activity activity, ListView lst) {
arrHome = new ArrayList<>();
diff --git a/app/src/main/java/org/glpi/inventory/agent/core/home/HomePresenter.java b/app/src/main/java/org/glpi/inventory/agent/core/home/HomePresenter.java
index afc2b2d2d..f443a5f76 100644
--- a/app/src/main/java/org/glpi/inventory/agent/core/home/HomePresenter.java
+++ b/app/src/main/java/org/glpi/inventory/agent/core/home/HomePresenter.java
@@ -57,11 +57,6 @@ public void showError(String message) {
}
}
- @Override
- public void doBindService(Activity activity) {
- model.doBindService(activity);
- }
-
@Override
public void setupList(Activity activity, ListView lst) {
model.setupList(activity, lst);
diff --git a/app/src/main/java/org/glpi/inventory/agent/core/main/MainModel.java b/app/src/main/java/org/glpi/inventory/agent/core/main/MainModel.java
index d3001291e..b9e99aad9 100644
--- a/app/src/main/java/org/glpi/inventory/agent/core/main/MainModel.java
+++ b/app/src/main/java/org/glpi/inventory/agent/core/main/MainModel.java
@@ -46,6 +46,7 @@
import org.glpi.inventory.agent.R;
import org.glpi.inventory.agent.adapter.DrawerAdapter;
+import org.glpi.inventory.agent.ui.ActivityMain;
import org.glpi.inventory.agent.ui.FragmentAbout;
import org.glpi.inventory.agent.ui.FragmentHelp;
import org.glpi.inventory.agent.ui.FragmentHome;
@@ -70,30 +71,9 @@ public MainModel(Main.Presenter presenter) {
@Override
public void setupInventoryAlarm(Context context) {
- LocalStorage cache = new LocalStorage(context);
- if (cache.getDataBoolean("changeSchedule")) {
- Calendar calendar = Calendar.getInstance();
-
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- String timeInventory = sharedPreferences.getString("timeInventory", "week");
-
- // week by default
- if (timeInventory.equalsIgnoreCase("week")) {
- calendar.add(Calendar.DATE, 7);
- }
-
- if (timeInventory.equalsIgnoreCase("day")) {
- calendar.add(Calendar.DATE, 1);
- }
-
- if (timeInventory.equalsIgnoreCase("month")) {
- calendar.add(Calendar.DATE, 30);
- }
-
- long dateTime = calendar.getTime().getTime();
-
- cache.setDataLong("data", dateTime);
- cache.setDataBoolean("changeSchedule", false);
+ if (context instanceof ActivityMain) {
+ ActivityMain activity = (ActivityMain) context;
+ activity.scheduleJob();
}
}
diff --git a/app/src/main/java/org/glpi/inventory/agent/preference/InventoryParametersPreference.java b/app/src/main/java/org/glpi/inventory/agent/preference/InventoryParametersPreference.java
index 72f771084..ca04e7f70 100644
--- a/app/src/main/java/org/glpi/inventory/agent/preference/InventoryParametersPreference.java
+++ b/app/src/main/java/org/glpi/inventory/agent/preference/InventoryParametersPreference.java
@@ -73,15 +73,16 @@ public void onClick(View v) {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
-
if ("timeInventory".equals(s)) {
Intent intent = new Intent("timeAlarmChanged");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
- AgentLog.d("Preference "+ s +" changed -> " + sharedPreferences.getString(s, "Week"));
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Preference "+ s +" changed -> " + sharedPreferences.getString(s, "Week"));
}
if("autoStartInventory".equals(s)){
- AgentLog.d("Preference "+ s +" changed -> " + sharedPreferences.getBoolean(s, false));
+ Intent intent = new Intent("timeAlarmChanged");
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Preference "+ s +" changed -> " + sharedPreferences.getBoolean(s, false));
}
}
}
diff --git a/app/src/main/java/org/glpi/inventory/agent/service/InventoryService.java b/app/src/main/java/org/glpi/inventory/agent/service/InventoryService.java
deleted file mode 100644
index c7e1e223a..000000000
--- a/app/src/main/java/org/glpi/inventory/agent/service/InventoryService.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/**
- * ---------------------------------------------------------------------
- * GLPI Android Inventory Agent
- * Copyright (C) 2019 Teclib.
- *
- * https://glpi-project.org
- *
- * Based on Flyve MDM Inventory Agent For Android
- * Copyright © 2018 Teclib. All rights reserved.
- *
- * ---------------------------------------------------------------------
- *
- * LICENSE
- *
- * This file is part of GLPI Android Inventory Agent.
- *
- * GLPI Android Inventory Agent is a subproject of GLPI.
- *
- * GLPI Android Inventory Agent is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * GLPI Android Inventory Agent is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * ---------------------------------------------------------------------
- * @copyright Copyright © 2019 Teclib. All rights reserved.
- * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
- * @link https://github.com/glpi-project/android-inventory-agent
- * @link https://glpi-project.org/glpi-network/
- * ---------------------------------------------------------------------
- */
-
-package org.glpi.inventory.agent.service;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.Color;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.PowerManager;
-import android.preference.PreferenceManager;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.core.app.NotificationCompat;
-import android.util.Log;
-import android.util.Xml;
-
-import org.flyve.inventory.InventoryTask;
-import org.glpi.inventory.agent.R;
-import org.glpi.inventory.agent.schema.ServerSchema;
-import org.glpi.inventory.agent.ui.ActivityMain;
-import org.glpi.inventory.agent.utils.AgentLog;
-import org.glpi.inventory.agent.utils.Helpers;
-import org.glpi.inventory.agent.utils.HttpInventory;
-import org.glpi.inventory.agent.utils.LocalPreferences;
-import org.glpi.inventory.agent.utils.LocalStorage;
-import org.glpi.inventory.agent.utils.Utils;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.TimeUnit;
-
-public class InventoryService extends Service {
-
- public static final String TIMER_RECEIVER = "org.glpi.inventory.service.timer";
-
- private Handler mHandler;
- Calendar calendar;
- long longDate;
- Date dateCurrent, dateDiff;
- LocalStorage cache;
-
- private Timer mTimer = null;
- public static final long NOTIFY_INTERVAL = 1000;
- Intent intent;
-
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
-
- mHandler = new Handler();
-
- cache = new LocalStorage(getApplicationContext());
- calendar = Calendar.getInstance();
-
- mTimer = new Timer();
- mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
- intent = new Intent(TIMER_RECEIVER);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- startMyOwnForeground();
- }
-
- }
-
- @RequiresApi(api = Build.VERSION_CODES.O)
- private void startMyOwnForeground(){
- String NOTIFICATION_CHANNEL_ID = "org.glpi.inventory.agent";
- String channelName = getApplicationContext().getResources().getString(R.string.app_is_running);
- NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
- chan.setLightColor(Color.BLUE);
- chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
- NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- assert manager != null;
- manager.createNotificationChannel(chan);
-
- //create intent to redirect user to app on click
- Intent appIntent = new Intent(getApplicationContext(), ActivityMain.class);
- appIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
- PendingIntent appIntentRedirect = PendingIntent.getActivity(getApplicationContext(), 0, appIntent, PendingIntent.FLAG_MUTABLE);
-
-
- //create inent to invite user to disable notification
- Intent notificationIntent = new Intent();
- notificationIntent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
- notificationIntent.putExtra("app_package", getPackageName());
- notificationIntent.putExtra("app_uid", getApplicationInfo().uid);
- notificationIntent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
- PendingIntent notificationIntentRedirect = PendingIntent.getActivity(getApplicationContext(), 0,
- notificationIntent, PendingIntent.FLAG_MUTABLE);
-
- //create notification
- NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
- Notification notification = notificationBuilder.setOngoing(true)
- .setSmallIcon(R.drawable.ic_stat)
- .setContentTitle(getApplicationContext().getResources().getString(R.string.app_is_running))
- .setPriority(NotificationManager.IMPORTANCE_MIN)
- .setCategory(Notification.CATEGORY_SERVICE)
- .setStyle(new NotificationCompat.BigTextStyle()
- .bigText(getApplicationContext().getResources().getString(R.string.app_is_running_extend)))
- .setContentIntent(appIntentRedirect)
- .addAction(R.drawable.ic_about, getApplicationContext().getResources().getString(R.string.disable_notification), notificationIntentRedirect)
- .build();
- startForeground(2, notification);
- }
-
- class TimeDisplayTimerTask extends TimerTask {
- @Override
- public void run() {
- mHandler.post(new Runnable() {
-
- @Override
- public void run() {
- calendar = Calendar.getInstance();
- longDate = calendar.getTime().getTime();
- Log.i("strDate", String.valueOf(longDate));
- twoDatesBetweenTime();
- }
-
- });
- }
- }
-
- private void twoDatesBetweenTime() {
-
- try {
- dateCurrent = new Date(longDate);
- } catch (Exception ex) {
- AgentLog.e(ex.getMessage());
- }
-
- try {
- dateDiff = new Date(cache.getDataLong("data"));
- } catch (Exception ex) {
- AgentLog.e(ex.getMessage());
- }
-
- try {
- long diff = dateDiff.getTime() - dateCurrent.getTime();
-
- long days = TimeUnit.MILLISECONDS.toDays(diff);
- diff -= TimeUnit.DAYS.toMillis(days);
-
- long hours = TimeUnit.MILLISECONDS.toHours(diff);
- diff -= TimeUnit.HOURS.toMillis(hours);
-
- long minutes = TimeUnit.MILLISECONDS.toMinutes(diff);
- diff -= TimeUnit.MINUTES.toMillis(minutes);
-
- long seconds = TimeUnit.MILLISECONDS.toSeconds(diff);
-
- if (seconds + hours + minutes + days > 0) {
- String strTesting;
- if (days != 0)
- strTesting = days + " days " + hours + ":" + minutes + ":" + seconds;
- else
- strTesting = hours + ":" + minutes + ":" + seconds;
- updateTime(strTesting);
- } else {
- sendInventory();
- setupInventorySchedule();
- }
- } catch (Exception e) {
- mTimer.cancel();
- mTimer.purge();
- }
-
- }
-
- private void setupInventorySchedule() {
- calendar = Calendar.getInstance();
-
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- String timeInventory = sharedPreferences.getString("timeInventory", "week");
-
- // week by default
- if (timeInventory.equalsIgnoreCase("week")) {
- calendar.add(Calendar.DATE, 7);
- }
-
- if(timeInventory.equalsIgnoreCase("day")) {
- calendar.add(Calendar.DATE, 1);
- }
-
- if(timeInventory.equalsIgnoreCase("month")) {
- calendar.add(Calendar.DATE, 30);
- }
-
- long dateTime = calendar.getTime().getTime();
-
- cache = new LocalStorage(getApplicationContext());
- cache.setDataLong("data", dateTime);
- }
-
- private void sendInventory() {
- final Context context = getApplicationContext();
-
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- Boolean autoStartInventory = sharedPreferences.getBoolean("autoStartInventory", false);
- if(!autoStartInventory) { return; }
-
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "android:inventory:agent");
- wl.acquire();
-
- final InventoryTask inventory = new InventoryTask(context.getApplicationContext(), Helpers.getAgentDescription(context), true);
- final HttpInventory httpInventory = new HttpInventory(context.getApplicationContext());
- ArrayList serverArray = new LocalPreferences(context).loadServer();
- if (!serverArray.isEmpty()) {
- for (String serverName : serverArray) {
- final ServerSchema model = httpInventory.setServerModel(serverName);
- inventory.setTag(model.getTag());
- inventory.setAssetItemtype(model.getItemtype());
- inventory.getXML(new InventoryTask.OnTaskCompleted() {
- @Override
- public void onTaskSuccess(String data) {
- if(!model.getSerial().trim().isEmpty()) {
- data = data.replaceAll("(.*)","" + model.getSerial() + "");
- }
- httpInventory.sendInventory(data, model, new HttpInventory.OnTaskCompleted() {
- @Override
- public void onTaskSuccess(String data) {
- Helpers.sendToNotificationBar(context.getApplicationContext(), context.getResources().getString(R.string.inventory_notification_sent));
- //Helpers.sendAnonymousData(context.getApplicationContext(), inventory);
- }
-
- @Override
- public void onTaskError(String error) {
- Helpers.sendToNotificationBar(context.getApplicationContext(), error);
- AgentLog.e(error);
- }
- });
- }
-
- @Override
- public void onTaskError(Throwable error) {
- AgentLog.e(error.getMessage());
- Helpers.sendToNotificationBar(context, context.getResources().getString(R.string.inventory_notification_fail));
- }
- });
- }
- } else {
- Helpers.sendToNotificationBar(context.getApplicationContext(), context.getResources().getString(R.string.no_servers_added));
- AgentLog.e(context.getResources().getString(R.string.no_servers_added));
- }
-
- wl.release();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- Log.e("Service finish", "Finish");
- getApplicationContext().startService(new Intent(getApplicationContext(), InventoryService.class));
- }
-
- private void updateTime(String strTime) {
- intent.putExtra("time", strTime);
- sendBroadcast(intent);
- }
-}
diff --git a/app/src/main/java/org/glpi/inventory/agent/ui/ActivityMain.java b/app/src/main/java/org/glpi/inventory/agent/ui/ActivityMain.java
index a78c87e3d..4f921df09 100644
--- a/app/src/main/java/org/glpi/inventory/agent/ui/ActivityMain.java
+++ b/app/src/main/java/org/glpi/inventory/agent/ui/ActivityMain.java
@@ -36,7 +36,10 @@
package org.glpi.inventory.agent.ui;
import android.Manifest;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -45,7 +48,6 @@
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
-import android.os.Environment;
import android.os.Parcelable;
import android.preference.PreferenceManager;
@@ -53,14 +55,13 @@
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.enterprise.feedback.KeyedAppState;
import androidx.enterprise.feedback.KeyedAppStatesReporter;
-import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-import android.provider.Settings;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -70,28 +71,25 @@
import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import org.flyve.inventory.InventoryTask;
import org.glpi.inventory.agent.R;
-import org.glpi.inventory.agent.core.detailserver.DetailServer;
-import org.glpi.inventory.agent.core.detailserver.DetailServerPresenter;
+import org.glpi.inventory.agent.broadcast.InventoryJobScheduler;
import org.glpi.inventory.agent.core.main.Main;
import org.glpi.inventory.agent.core.main.MainPresenter;
import org.glpi.inventory.agent.preference.GlobalParametersPreference;
import org.glpi.inventory.agent.preference.InventoryParametersPreference;
-import org.glpi.inventory.agent.schema.ServerSchema;
-import org.glpi.inventory.agent.service.InventoryService;
import org.glpi.inventory.agent.utils.AgentLog;
import org.glpi.inventory.agent.utils.Helpers;
-import org.glpi.inventory.agent.utils.HttpInventory;
import org.glpi.inventory.agent.utils.LocalPreferences;
import org.glpi.inventory.agent.utils.LocalStorage;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
public class ActivityMain extends AppCompatActivity
implements Main.View, SharedPreferences.OnSharedPreferenceChangeListener {
@@ -107,18 +105,7 @@ public class ActivityMain extends AppCompatActivity
private Boolean isOpen;
private Animation fab_open, fab_close, fab_clock, fab_anticlock;
private TextView textview_settings, textview_scheduler;
-
- private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String strTime = intent.getStringExtra("time");
- if (sharedPreferences.getBoolean("autoStartInventory", false)) {
- toolbar.setSubtitle(strTime);
- } else {
- toolbar.setSubtitle("");
- }
- }
- };
+ InventoryJobScheduler alarm = new InventoryJobScheduler();
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
@@ -129,23 +116,45 @@ public void onReceive(Context context, Intent intent) {
};
private BroadcastReceiver appRestrictionChange = null;
- private KeyedAppStatesReporter appRestrictionChangeReporter = null;
@Override
protected void onStart() {
super.onStart();
- IntentFilter restrictionsFilter =
- new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
-
+ IntentFilter restrictionsFilter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
BroadcastReceiver appRestrictionChange = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
resolveRestrictions();
}
};
- registerReceiver(appRestrictionChange, restrictionsFilter);
+ if (Build.VERSION.SDK_INT >= 34) {
+ registerReceiver(appRestrictionChange, restrictionsFilter, RECEIVER_EXPORTED);
+ } else {
+ registerReceiver(appRestrictionChange, restrictionsFilter);
+ }
+
+ if (sharedPreferences.getBoolean("autoStartInventory", false)) {
+ String label = getString(R.string.schedule_inventory_each);
+ String frequency = "weekly";
+ switch(sharedPreferences.getString("timeInventory", "Week")){
+ case "Day":
+ frequency = "daily";
+ break;
+ case "Month":
+ frequency = "monthly";
+ break;
+ default:
+ frequency = "weekly";
+ break;
+ }
+
+ toolbar.setSubtitle(label + ' ' + frequency);
+ } else {
+ toolbar.setSubtitle("Scheduled inventory not configured");
+ }
}
+
@Override
protected void onStop() {
super.onStop();
@@ -155,136 +164,52 @@ protected void onStop() {
}
}
- public static void enterpriseFeedback(Context context,
- String key,
- String message,
- String data,
- int severity) {
- KeyedAppStatesReporter keyedAppStatesReporter = KeyedAppStatesReporter.create(context);
- KeyedAppState keyedAppStateMessage = KeyedAppState.builder()
- .setSeverity(severity)
- .setKey(key)
- .setMessage(message)
- .setData(data)
- .build();
- List list = new ArrayList<>();
- list.add(keyedAppStateMessage);
- keyedAppStatesReporter.setStates(list);
+ @Override
+ protected void onResume() {
+ super.onResume();
+ resolveRestrictions();
}
- private void resolveRestrictions() {
- AgentLog.e("EMM - START resolve restrictions");
- RestrictionsManager myRestrictionsMgr = null;
- myRestrictionsMgr = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
- Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
+ @Override
+ protected void onPause() {
+ super.onPause();
+ //unregisterReceiver(broadcastReceiver);
+ }
- SharedPreferences customSharedPreference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- SharedPreferences.Editor editor = customSharedPreference.edit();
+ private void checkPermissions() {
+ List permissionsList = new ArrayList<>(Arrays.asList(
+ Manifest.permission.READ_PHONE_STATE,
+ Manifest.permission.CAMERA
+ ));
- if (appRestrictions.containsKey("automatic_inventory")) {
- editor.putBoolean("autoStartInventory", appRestrictions.getBoolean("automatic_inventory"));
- enterpriseFeedback(getApplicationContext(), "automatic_inventory", "automatic_inventory option set successfully", appRestrictions.getBoolean("automatic_inventory") ? "true" : "false", KeyedAppState.SEVERITY_INFO);
- AgentLog.e("EMM - set automatic inventory to " + appRestrictions.getBoolean("automatic_inventory"));
- editor.apply();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ permissionsList.add(Manifest.permission.POST_NOTIFICATIONS);
}
- if (appRestrictions.containsKey("frequency")) {
- editor.putString("timeInventory", appRestrictions.getString("frequency"));
- enterpriseFeedback(getApplicationContext(), "frequency", "frequency option set successfully", appRestrictions.getString("frequency"), KeyedAppState.SEVERITY_INFO);
- AgentLog.e("EMM - set frequency to " + appRestrictions.getString("frequency"));
- editor.apply();
- }
+ String[] permissions = permissionsList.toArray(new String[0]);
- if (appRestrictions.containsKey("auto_start_on_boot")) {
- editor.putBoolean("boot", appRestrictions.getBoolean("auto_start_on_boot"));
- enterpriseFeedback(getApplicationContext(), "auto_start_on_boot", "auto_start_on_boot option set successfully", appRestrictions.getBoolean("auto_start_on_boot") ? "true" : "false", KeyedAppState.SEVERITY_INFO);
- AgentLog.e("EMM - set auto start on boot to " + appRestrictions.getBoolean("auto_start_on_boot"));
- editor.apply();
- }
-
- Parcelable[] parcelables = appRestrictions.getParcelableArray("server_configuration_list");
- if (parcelables != null && parcelables.length > 0) {
- final Context context = getApplicationContext();
- for (int i = 0; i < parcelables.length; i++) {
- Bundle serverConfig = (Bundle) parcelables[i];
- JSONObject jsonServerConfig = new JSONObject();
- LocalPreferences preferences = new LocalPreferences(context);
-
- if (serverConfig.getString("server_url").isEmpty()) {
- enterpriseFeedback(getApplicationContext(), "server_url", "Error server URL is mandatory -> ", serverConfig.getString("server_url"), KeyedAppState.SEVERITY_ERROR);
- AgentLog.e("EMM - server url is mandatory");
- continue;
- }
-
- try {
- jsonServerConfig.put("address", serverConfig.getString("server_url"));
- jsonServerConfig.put("tag", serverConfig.getString("server_tag"));
- jsonServerConfig.put("login", serverConfig.getString("server_login"));
- jsonServerConfig.put("pass", serverConfig.getString("server_password"));
- jsonServerConfig.put("itemtype", serverConfig.getString("server_itemtype"));
- jsonServerConfig.put("serial", serverConfig.getString("server_custom_asset_serial"));
-
- AgentLog.e("EMM - Receive the following configuration '" + jsonServerConfig.toString());
-
- JSONObject local_server = preferences.loadJSONObject(serverConfig.getString("server_url"));
- AgentLog.e("EMM - Try to load '" + serverConfig.getString("server_url") + "' server if exist");
- AgentLog.e("EMM - Found '" + local_server.toString() + "'");
- AgentLog.e("EMM - Exist ? -> '" + !local_server.toString().equals("{}") + "'");
-
- if (local_server.toString().equals("{}")) {
- ArrayList serverArray = preferences.loadServer();
- serverArray.add(serverConfig.getString("server_url"));
- preferences.saveServer(serverArray);
- preferences.saveJSONObject(serverConfig.getString("server_url"), jsonServerConfig);
- enterpriseFeedback(getApplicationContext(), "server_url", "server_url added successfully", serverConfig.getString("server_url"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_tag", "server_tag added successfully", serverConfig.getString("server_tag"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_login", "server_login added successfully", serverConfig.getString("server_login"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_password", "server_password added successfully", "***", KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_itemtype", "server_itemtype added successfully", serverConfig.getString("server_itemtype"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_custom_asset_serial", "server_custom_asset_serial added successfully", serverConfig.getString("server_custom_asset_serial"), KeyedAppState.SEVERITY_INFO);
- AgentLog.e("EMM - Server added successfully");
- } else {
- preferences.deletePreferences(serverConfig.getString("server_url"));
- preferences.saveJSONObject(serverConfig.getString("server_url"), jsonServerConfig);
- enterpriseFeedback(getApplicationContext(), "server_url", "server_url updated successfully", serverConfig.getString("server_url"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_tag", "server_tag updated successfully", serverConfig.getString("server_tag"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_login", "server_login updated successfully", serverConfig.getString("server_login"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_password", "server_password updated successfully", "***", KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_itemtype", "server_itemtype updated successfully", serverConfig.getString("server_itemtype"), KeyedAppState.SEVERITY_INFO);
- enterpriseFeedback(getApplicationContext(), "server_custom_asset_serial", "server_custom_asset_serial updated successfully", serverConfig.getString("server_custom_asset_serial"), KeyedAppState.SEVERITY_INFO);
- AgentLog.e("EMM - Server updated successfully");
- }
-
- } catch (JSONException e) {
- enterpriseFeedback(getApplicationContext(), "server_url", "error while adding/updating server -> " + e.getMessage(), serverConfig.getString("server_url"), KeyedAppState.SEVERITY_ERROR);
- AgentLog.e("EMM - error while adding/updating server");
- AgentLog.e("EMM - " + e.getMessage());
- }
+ List permissionsToRequest = new ArrayList<>();
+ for (String permission : permissions) {
+ if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
+ permissionsToRequest.add(permission);
}
- } else {
- AgentLog.e("EMM - 'server_configuration_list' key is empty");
}
- AgentLog.e("EMM - END resolve restrictions");
- }
- @Override
- protected void onResume() {
- super.onResume();
- registerReceiver(broadcastReceiver,new IntentFilter(InventoryService.TIMER_RECEIVER));
- resolveRestrictions();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- unregisterReceiver(broadcastReceiver);
+ if (!permissionsToRequest.isEmpty()) {
+ ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), 0);
+ }
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- //Fabric.with(this, new Crashlytics());
+
+ checkPermissions();
+
setContentView(R.layout.activity_main);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
+ }
ActivityCompat.requestPermissions(ActivityMain.this,
new String[]{
@@ -297,6 +222,8 @@ protected void onCreate(Bundle savedInstanceState) {
loadCategories();
}
+ scheduleJob();
+
// Menu list
ListView lst = findViewById(R.id.lst);
@@ -386,11 +313,6 @@ public void onClick(View view) {
ActivityMain.this.startActivity(miIntent);
}
});
-
- //app restriction change
- KeyedAppStatesReporter appRestrictionChangeReporter = KeyedAppStatesReporter.create(getApplicationContext());
-
-
}
private void disableFab(){
@@ -470,20 +392,195 @@ public void onBackPressed() {
}
@Override
- public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- switch (requestCode) {
- case 1: {
+ boolean allGranted = true;
+ for (int result : grantResults) {
+ if (result != PackageManager.PERMISSION_GRANTED) {
+ allGranted = false;
+ break;
+ }
+ }
- // If request is cancelled, the result arrays are empty.
- if (grantResults.length > 0
- && grantResults[0] == PackageManager.PERMISSION_GRANTED
- && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
- } else {
- String message = getResources().getString(R.string.permission_error_result);
- Helpers.snackClose(ActivityMain.this, message, getString(R.string.permission_snack_ok), true);
+ if (!allGranted) {
+ String message = getResources().getString(R.string.permission_error_result);
+ Helpers.snackClose(ActivityMain.this, message, getString(R.string.permission_snack_ok), true);
+ }
+ }
+
+ public static void enterpriseFeedback(Context context,
+ String key,
+ String message,
+ String data,
+ int severity) {
+ KeyedAppStatesReporter keyedAppStatesReporter = KeyedAppStatesReporter.create(context);
+ KeyedAppState keyedAppStateMessage = KeyedAppState.builder()
+ .setSeverity(severity)
+ .setKey(key)
+ .setMessage(message)
+ .setData(data)
+ .build();
+ List list = new ArrayList<>();
+ list.add(keyedAppStateMessage);
+ keyedAppStatesReporter.setStates(list);
+ }
+
+ private void resolveRestrictions() {
+ AgentLog.e("EMM - START resolve restrictions");
+ RestrictionsManager myRestrictionsMgr = null;
+ myRestrictionsMgr = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
+ Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
+
+ SharedPreferences customSharedPreference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ SharedPreferences.Editor editor = customSharedPreference.edit();
+
+ if (appRestrictions.containsKey("automatic_inventory")) {
+ editor.putBoolean("autoStartInventory", appRestrictions.getBoolean("automatic_inventory"));
+ enterpriseFeedback(getApplicationContext(), "automatic_inventory", "automatic_inventory option set successfully", appRestrictions.getBoolean("automatic_inventory") ? "true" : "false", KeyedAppState.SEVERITY_INFO);
+ AgentLog.e("EMM - set automatic inventory to " + appRestrictions.getBoolean("automatic_inventory"));
+ editor.apply();
+ }
+
+ if (appRestrictions.containsKey("frequency")) {
+ editor.putString("timeInventory", appRestrictions.getString("frequency"));
+ enterpriseFeedback(getApplicationContext(), "frequency", "frequency option set successfully", appRestrictions.getString("frequency"), KeyedAppState.SEVERITY_INFO);
+ AgentLog.e("EMM - set frequency to " + appRestrictions.getString("frequency"));
+ editor.apply();
+ }
+
+ if (appRestrictions.containsKey("auto_start_on_boot")) {
+ editor.putBoolean("boot", appRestrictions.getBoolean("auto_start_on_boot"));
+ enterpriseFeedback(getApplicationContext(), "auto_start_on_boot", "auto_start_on_boot option set successfully", appRestrictions.getBoolean("auto_start_on_boot") ? "true" : "false", KeyedAppState.SEVERITY_INFO);
+ AgentLog.e("EMM - set auto start on boot to " + appRestrictions.getBoolean("auto_start_on_boot"));
+ editor.apply();
+ }
+
+ Parcelable[] parcelables = appRestrictions.getParcelableArray("server_configuration_list");
+ if (parcelables != null && parcelables.length > 0) {
+ final Context context = getApplicationContext();
+ for (int i = 0; i < parcelables.length; i++) {
+ Bundle serverConfig = (Bundle) parcelables[i];
+ JSONObject jsonServerConfig = new JSONObject();
+ LocalPreferences preferences = new LocalPreferences(context);
+
+ if (serverConfig.getString("server_url").isEmpty()) {
+ enterpriseFeedback(getApplicationContext(), "server_url", "Error server URL is mandatory -> ", serverConfig.getString("server_url"), KeyedAppState.SEVERITY_ERROR);
+ AgentLog.e("EMM - server url is mandatory");
+ continue;
+ }
+
+ try {
+ jsonServerConfig.put("address", serverConfig.getString("server_url"));
+ jsonServerConfig.put("tag", serverConfig.getString("server_tag"));
+ jsonServerConfig.put("login", serverConfig.getString("server_login"));
+ jsonServerConfig.put("pass", serverConfig.getString("server_password"));
+ jsonServerConfig.put("itemtype", serverConfig.getString("server_itemtype"));
+ jsonServerConfig.put("serial", serverConfig.getString("server_custom_asset_serial"));
+
+ AgentLog.e("EMM - Receive the following configuration '" + jsonServerConfig.toString());
+
+ JSONObject local_server = preferences.loadJSONObject(serverConfig.getString("server_url"));
+ AgentLog.e("EMM - Try to load '" + serverConfig.getString("server_url") + "' server if exist");
+ AgentLog.e("EMM - Found '" + local_server.toString() + "'");
+ AgentLog.e("EMM - Exist ? -> '" + !local_server.toString().equals("{}") + "'");
+
+ if (local_server.toString().equals("{}")) {
+ ArrayList serverArray = preferences.loadServer();
+ serverArray.add(serverConfig.getString("server_url"));
+ preferences.saveServer(serverArray);
+ preferences.saveJSONObject(serverConfig.getString("server_url"), jsonServerConfig);
+ enterpriseFeedback(getApplicationContext(), "server_url", "server_url added successfully", serverConfig.getString("server_url"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_tag", "server_tag added successfully", serverConfig.getString("server_tag"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_login", "server_login added successfully", serverConfig.getString("server_login"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_password", "server_password added successfully", "***", KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_itemtype", "server_itemtype added successfully", serverConfig.getString("server_itemtype"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_custom_asset_serial", "server_custom_asset_serial added successfully", serverConfig.getString("server_custom_asset_serial"), KeyedAppState.SEVERITY_INFO);
+ AgentLog.e("EMM - Server added successfully");
+ } else {
+ preferences.deletePreferences(serverConfig.getString("server_url"));
+ preferences.saveJSONObject(serverConfig.getString("server_url"), jsonServerConfig);
+ enterpriseFeedback(getApplicationContext(), "server_url", "server_url updated successfully", serverConfig.getString("server_url"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_tag", "server_tag updated successfully", serverConfig.getString("server_tag"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_login", "server_login updated successfully", serverConfig.getString("server_login"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_password", "server_password updated successfully", "***", KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_itemtype", "server_itemtype updated successfully", serverConfig.getString("server_itemtype"), KeyedAppState.SEVERITY_INFO);
+ enterpriseFeedback(getApplicationContext(), "server_custom_asset_serial", "server_custom_asset_serial updated successfully", serverConfig.getString("server_custom_asset_serial"), KeyedAppState.SEVERITY_INFO);
+ AgentLog.e("EMM - Server updated successfully");
+ }
+
+ } catch (JSONException e) {
+ enterpriseFeedback(getApplicationContext(), "server_url", "error while adding/updating server -> " + e.getMessage(), serverConfig.getString("server_url"), KeyedAppState.SEVERITY_ERROR);
+ AgentLog.e("EMM - error while adding/updating server");
+ AgentLog.e("EMM - " + e.getMessage());
}
}
+ } else {
+ AgentLog.e("EMM - 'server_configuration_list' key is empty");
}
+ AgentLog.e("EMM - END resolve restrictions");
+ }
+
+ public void scheduleJob() {
+ SharedPreferences customSharedPreference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ String timeInventory = customSharedPreference.getString("timeInventory", "Week");
+
+ final JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ final ComponentName name = new ComponentName(this, InventoryJobScheduler.class);
+ final JobInfo jobInfo = getJobInfo(InventoryJobScheduler.INVENTORY_JOB_ID, timeInventory, name);
+
+ if(customSharedPreference.getBoolean("autoStartInventory", false)) {
+ if (!isAlreadyScheduled(jobScheduler, jobInfo)) {
+ if (jobScheduler.schedule(jobInfo) == JobScheduler.RESULT_SUCCESS) {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Scheduled job successfully!");
+ }
+ } else {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Scheduled job already initialized");
+ }
+ } else {
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : autoStartInventory disabled, cancel JobScheduler");
+ if (isAlreadyScheduled(jobScheduler, jobInfo)) {
+ jobScheduler.cancel(InventoryJobScheduler.INVENTORY_JOB_ID);
+ }
+ }
+ }
+
+ private boolean isAlreadyScheduled(JobScheduler jobScheduler, JobInfo jobInfo) {
+ boolean jobAlreadyScheduled = false;
+ for (JobInfo existingJob: jobScheduler.getAllPendingJobs()) {
+ // check if scheduler exist with same ID and same minimum latency
+ if (existingJob.getId() == jobInfo.getId()
+ && existingJob.getMinLatencyMillis() == jobInfo.getMinLatencyMillis()) {
+ jobAlreadyScheduled = true;
+ break;
+ }
+ }
+ return jobAlreadyScheduled;
+ }
+
+ private JobInfo getJobInfo(final int id, final String timeInventory, final ComponentName name) {
+
+ //default week
+ long interval = TimeUnit.DAYS.toMillis(7);
+ if (timeInventory.equals("Day")) {
+ interval = TimeUnit.DAYS.toMillis(1);
+ } else if (timeInventory.equals("Week")) {
+ interval = TimeUnit.DAYS.toMillis(7);
+ } else if (timeInventory.equals("Month")) {
+ interval = TimeUnit.DAYS.toMillis(30);
+ }
+
+ AgentLog.d("GLPI-AGENT-JOBSCHEDULER : Alarm scheduled each " + timeInventory);
+
+ JobInfo.Builder builder = new JobInfo.Builder(id, name)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .setPersisted(true);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ builder.setMinimumLatency(interval);
+ } else {
+ builder.setPeriodic(interval);
+ }
+
+ return builder.build();
}
}
diff --git a/app/src/main/java/org/glpi/inventory/agent/ui/FragmentHome.java b/app/src/main/java/org/glpi/inventory/agent/ui/FragmentHome.java
index dc2da5c92..8ae5ecba2 100644
--- a/app/src/main/java/org/glpi/inventory/agent/ui/FragmentHome.java
+++ b/app/src/main/java/org/glpi/inventory/agent/ui/FragmentHome.java
@@ -67,8 +67,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
presenter = new HomePresenter(this);
- presenter.doBindService(FragmentHome.this.getActivity());
-
Button btn_run = v.findViewById(R.id.btn_run_inventory);
btn_run.setOnClickListener(new View.OnClickListener() {
@Override
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fcbc8140b..cec1fd94b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -52,6 +52,7 @@
No server found
Crash report is disable, please enable to test it
Select the format to share
+ Inventory is scheduled
- XML
- JSON