* 2.0.2
*
+- Android Console:
+ - Updated ACRA library: now crash reports are sent via e-mail (will use the app installed on device to send mail)
+ - Fixed bug in action bar commands: disconnect and exit sometimes wasn't working
+- Android Agent:
+ - Updated ACRA library: now crash reports are sent via e-mail (will use the app installed on device to send mail)
- Fixed issues: #1042, #1049
*
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
- <classpathentry kind="lib" path="libs/acra-4.4.0.jar"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="lib" path="libs/android-support-v4.jar"/>
<classpathentry kind="lib" path="libs/netxms-base-2.0.1.jar"/>
<classpathentry kind="lib" path="libs/netxms-mobile-agent-2.0.1.jar"/>
+ <classpathentry kind="lib" path="libs/acra-4.7.0.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:enabled="true" android:id="@android:id/home" android:title="@string/home" android:visible="true" android:checkable="false" android:checked="false" android:icon="@android:drawable/ic_menu_myplaces" android:showAsAction="ifRoom"></item>
- <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@drawable/ic_menu_preferences" android:showAsAction="ifRoom"></item>
+ <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@android:drawable/ic_menu_preferences" android:showAsAction="ifRoom"></item>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:enabled="true" android:id="@android:id/home" android:title="@string/home" android:visible="true" android:checkable="false" android:checked="false" android:icon="@android:drawable/ic_menu_myplaces" android:showAsAction="ifRoom"></item>
- <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@drawable/ic_menu_preferences" android:showAsAction="ifRoom"></item>
+ <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@android:drawable/ic_menu_preferences"></item>
</menu>
<string name="version">Version</string>
<string name="reconnect">Reconnect</string>
<string name="ok">OK</string>
-
+ <string name="crash_toast_text">NetXMS Agent crashed and needs to send a report to developers</string>
+
<string name="main_title">Home</string>
<string name="home">Home</string>
package org.netxms.agent.android;
import org.acra.ACRA;
+import org.acra.ReportField;
+import org.acra.ReportingInteractionMode;
import org.acra.annotation.ReportsCrashes;
import android.app.Application;
-@ReportsCrashes(formKey = "dGJ5RFRpbmg2ZVRvT2tERU9seHVlTWc6MQ")
+@ReportsCrashes(
+ mailTo = "acra@netxms.org",
+ customReportContent = { ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.CUSTOM_DATA, ReportField.STACK_TRACE, ReportField.LOGCAT },
+ mode = ReportingInteractionMode.TOAST,
+ resToastText = R.string.crash_toast_text)
public class NXApplication extends Application
{
private static boolean activityVisible;
<classpathentry exported="true" kind="lib" path="libs/simple-xml-2.6.4.jar"/>
<classpathentry exported="true" kind="lib" path="libs/achartengine-1.0.0.jar"/>
<classpathentry kind="lib" path="libs/android-support-v4.jar"/>
- <classpathentry kind="lib" path="libs/acra-4.4.0.jar"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="lib" path="libs/netxms-base-2.0.1.jar"/>
<classpathentry kind="lib" path="libs/netxms-client-2.0.1.jar"/>
+ <classpathentry kind="lib" path="libs/acra-4.7.0.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@drawable/ic_menu_preferences" android:showAsAction="ifRoom"></item>
+ <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@android:drawable/ic_menu_preferences" android:showAsAction="ifRoom"></item>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<item android:enabled="true" android:id="@android:id/home" android:title="@string/home" android:visible="true" android:checkable="false" android:checked="false" android:icon="@android:drawable/ic_menu_myplaces" android:showAsAction="ifRoom" tools:targetApi="11"></item>
- <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@drawable/ic_menu_preferences" android:showAsAction="ifRoom"></item>
+ <item android:enabled="true" android:id="@+id/settings" android:title="@string/settings" android:visible="true" android:checkable="false" android:checked="false" android:icon="@android:drawable/ic_menu_preferences"></item>
</menu>
<string name="no_items">No items to show…</string>
<string name="warning">Warning</string>
<string name="long_time_execution">This task could take a long time to execute. Would you like to proceed anyway?</string>
+ <string name="crash_toast_text">NetXMS Client crashed and needs to send a report to developers</string>
<string name="progress_gathering_data">Gathering data…</string>
<string name="progress_processing_data">Processing data…</string>
package org.netxms.ui.android;
import org.acra.ACRA;
+import org.acra.ReportField;
+import org.acra.ReportingInteractionMode;
import org.acra.annotation.ReportsCrashes;
import android.app.Application;
-@ReportsCrashes(formKey = "dEhRMG50MjhWTXBWSU5jaDVubzlxT1E6MQ")
+@ReportsCrashes(
+ mailTo = "acra@netxms.org",
+ customReportContent = { ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.CUSTOM_DATA, ReportField.STACK_TRACE, ReportField.LOGCAT },
+ mode = ReportingInteractionMode.TOAST,
+ resToastText = R.string.crash_toast_text)
public class NXApplication extends Application
{
private static boolean activityVisible;
static public String getLabel(int type, int mul)
{
- String labels[][] =
- {
+ String labels[][] = {
{ "", "", "", "", "", "", "", "" }, // No multiplier
{ "K", "M", "G", "T", "P", "E", "Z", "Y" }, // Decimal multiplier
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" } // Binary multiplier
static public double getValue(int type, int mul)
{
- double values[][] =
- {
+ double values[][] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1E3, 1E6, 1E9, 1E12, 1E15, 1E18, 1E21, 1E24 },
{
1024. * 1024 * 1024 * 1024 * 1024,
1024. * 1024 * 1024 * 1024 * 1024 * 1024,
1024. * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
- 1024. * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024
- },
- };
- return values[type][mul];
+ 1024. * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 }, };
+ if (type > 0 && type < values.length && mul > 0 && mul < values[type].length)
+ return values[type][mul];
+ else
+ return 1;
}
}
import org.netxms.ui.android.R;
import org.netxms.ui.android.main.adapters.ActivityListAdapter;
import org.netxms.ui.android.main.fragments.AlarmBrowserFragment;
+import org.netxms.ui.android.service.ClientConnectorService;
import org.netxms.ui.android.service.ClientConnectorService.ConnectionStatus;
import android.annotation.SuppressLint;
public static final int ACTIVITY_ENTIRENETWORK = 4;
public static final int ACTIVITY_GRAPHS = 5;
public static final int ACTIVITY_MACADDRESS = 6;
- public static final String INTENTIONAL_EXIT_KEY = "IntentionalExit";
private ActivityListAdapter adapter;
private TextView statusText;
{
if (service != null)
service.shutdown();
- setIntentionalExit(true);// Avoid autorestart on change connectivity status for intentional exit
+ else
+ setIntentionalExit(true);// Avoid autorestart on change connectivity status for intentional exit (shutdown will do itself)
moveTaskToBack(true);
System.exit(0);
}
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean(INTENTIONAL_EXIT_KEY, flag);
+ editor.putBoolean(ClientConnectorService.INTENTIONAL_EXIT_KEY, flag);
editor.commit();
}
}
case DISABLED:
return R.drawable.status_disabled;
case TESTING:
- return R.drawable.status_unknown; // TODO: 2014Oct10 Implement corresponding settings section
+ return R.drawable.status_unknown;
}
return R.drawable.status_unknown;
}
package org.netxms.ui.android.receivers;
-import org.netxms.ui.android.main.activities.HomeScreen;
import org.netxms.ui.android.service.ClientConnectorService;
import android.content.BroadcastReceiver;
public void onReceive(Context context, Intent intent)
{
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- if (!sp.getBoolean(HomeScreen.INTENTIONAL_EXIT_KEY, false))
+ if (!sp.getBoolean(ClientConnectorService.INTENTIONAL_EXIT_KEY, false))
if (intent.getExtras() != null)
{
if (!sp.getBoolean("global.scheduler.enable", false)) // Try to connect only when the scheduler is disabled
public static final String ACTION_ALARM_RESOLVE = "org.netxms.ui.android.ACTION_ALARM_RESOLVE";
public static final String ACTION_ALARM_TERMINATE = "org.netxms.ui.android.ACTION_ALARM_TERMINATE";
public static final String ACTION_EXIT = "org.netxms.ui.android.ACTION_EXIT";
+ public static final String INTENTIONAL_EXIT_KEY = "IntentionalExit";
+
private static final String TAG = "nxclient/ClientConnectorService";
private static final String LASTALARM_KEY = "LastALarmIdNotified";
-
private static final int NOTIFY_ALARM = 1;
private static final int NOTIFY_STATUS = 2;
private static final int NOTIFY_STATUS_NEVER = 0;
public int onStartCommand(Intent intent, int flags, int startId)
{
if ((intent != null) && (intent.getAction() != null))
+ {
+ Log.d(TAG, "onStartCommand: " + intent.getAction());
if (intent.getAction().equals(ACTION_CONNECT))
reconnect(false);
else if (intent.getAction().equals(ACTION_FORCE_CONNECT))
}
else if (intent.getAction().equals(ACTION_EXIT))
exitApp();
+ }
return super.onStartCommand(intent, flags, startId);
}
{
cancelSchedule();
clearNotifications();
- savePreferences();
+ saveSatusOnExit();
unregisterReceiver(receiver);
stopSelf();
}
/**
- *
+ * Save status for intentional exit from app
*/
- public void savePreferences()
+ public void saveSatusOnExit()
{
SharedPreferences.Editor editor = sp.edit();
editor.putInt(LASTALARM_KEY, (int)lastAlarmIdNotified);
+ editor.putBoolean(ClientConnectorService.INTENTIONAL_EXIT_KEY, true);
editor.commit();
}
*/
private boolean hasToReconnect()
{
- // TODO: cleanup alarm icon on change settings
- // TODO: check reconnect on new flags added (vibration, led,...)
boolean needsToReconnect = enabled != sp.getBoolean("global.scheduler.enable", false);
needsToReconnect |= !server.equalsIgnoreCase(sp.getString("connection.server", ""));
needsToReconnect |= port != SafeParser.parseInt(sp.getString("connection.port", "4701"), 4701);
{
try
{
- session.syncObjectSet(new long[] { objectId }, false, NXCSession.OBJECT_SYNC_NOTIFY);
+ if (session != null)
+ session.syncObjectSet(new long[] { objectId }, false, NXCSession.OBJECT_SYNC_NOTIFY);
}
catch (Exception e)
{
}
/**
- * Exit from App
+ * Exit intentionally from App
*/
private void exitApp()
{
}
});
}
+ else // Home app is no more running
+ shutdown();
}
/**
int short_gap = 100;// Length of Gap Between dots/dashes (real is 200)
int medium_gap = 250;// Length of Gap Between Letters (real is 500)
//int long_gap = 500;// Length of Gap Between Words (real is 1000)
- long[] pattern = { 0, // Start immediately
- dot, short_gap, dot, short_gap, dot, // s
- medium_gap, dash, short_gap, dash, short_gap, dash, // o
- medium_gap, dot, short_gap, dot, short_gap, dot// s
+ long[] pattern = {
+ 0, // Start immediately
+ dot,
+ short_gap,
+ dot,
+ short_gap,
+ dot, // s
+ medium_gap,
+ dash,
+ short_gap,
+ dash,
+ short_gap,
+ dash, // o
+ medium_gap,
+ dot,
+ short_gap,
+ dot,
+ short_gap,
+ dot// s
};
return pattern;
}
{
try
{
- session.acknowledgeAlarm(id, sticky, 0);
+ if (session != null)
+ session.acknowledgeAlarm(id, sticky, 0);
}
catch (Exception e)
{
{
try
{
- session.resolveAlarm(id);
+ if (session != null)
+ session.resolveAlarm(id);
}
catch (Exception e)
{
{
try
{
- session.terminateAlarm(id);
+ if (session != null)
+ session.terminateAlarm(id);
}
catch (Exception e)
{
{
try
{
- session.setObjectManaged(id, state);
+ if (session != null)
+ session.setObjectManaged(id, state);
}
catch (Exception e)
{
if (cal.getTimeInMillis() < next)
{
cal.setTimeInMillis(next);
- return " " + getString(R.string.notify_next_connection_schedule, DateFormat.getDateTimeInstance().format(cal));
+ return " " + getString(R.string.notify_next_connection_schedule, DateFormat.getDateTimeInstance().format(cal.getTime()));
}
}
return "";