<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -9,6 +9,7 @@ package org.appcelerator.titanium;
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.ResponseHandler;
@@ -41,9 +42,13 @@ public class TitaniumAnalyticsService extends Service
 	private final static String ANALYTICS_URL = &quot;https://api.appcelerator.net/p/v2/mobile-track&quot;;
 	//private final static String ANALYTICS_URL = &quot;http://192.168.123.102:8000/test&quot;;
 
-	private ConnectivityManager connectivityManager;
+	private static AtomicBoolean sending;
 
+	private ConnectivityManager connectivityManager;
 	public TitaniumAnalyticsService() {
+		if (sending == null) {
+			this.sending = new AtomicBoolean(false);
+		}
 	}
 
 	@Override
@@ -65,6 +70,10 @@ public class TitaniumAnalyticsService extends Service
 	public void onStart(Intent intent, final int startId) {
 		super.onStart(intent, startId);
 
+		if (!sending.compareAndSet(false, true)) {
+			Log.i(LCAT, &quot;Send already in progress, skipping intent&quot;);
+		}
+
 		final TitaniumAnalyticsService self = this;
 
 		Thread t = new Thread(new Runnable(){
@@ -140,6 +149,7 @@ public class TitaniumAnalyticsService extends Service
 
 							events.clear();
 						} else {
+							Log.i(LCAT, &quot;Network unavailable, can't send analytics&quot;);
 							//TODO reset alarm?
 							break;
 						}
@@ -150,6 +160,10 @@ public class TitaniumAnalyticsService extends Service
 				} catch (Throwable t) {
 					Log.e(LCAT, &quot;Unhandle exception in analytics thread: &quot;, t);
 					stopSelf(startId);
+				} finally {
+					if (!sending.compareAndSet(true, false)) {
+						Log.w(LCAT, &quot;Expected to be in a sending state. Sending was already false.&quot;);
+					}
 				}
 			}
 		});
@@ -164,7 +178,12 @@ public class TitaniumAnalyticsService extends Service
 		//int subType = netInfo.getSubType();
 		// TODO change defaults based on implied speed of network
 
-		NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
+		NetworkInfo netInfo = null;
+		try {
+			netInfo = connectivityManager.getActiveNetworkInfo();
+		} catch (SecurityException e) {
+			Log.e(LCAT, &quot;Connectivity permissions have been removed from AndroidManifest.xml: &quot; + e.getMessage());
+		}
 		if (netInfo != null &amp;&amp; netInfo.isConnected() &amp;&amp; !netInfo.isRoaming()) {
 			result = true;
 		}</diff>
      <filename>android/titanium/src/org/appcelerator/titanium/TitaniumAnalyticsService.java</filename>
    </modified>
    <modified>
      <diff>@@ -91,12 +91,17 @@ public class TitaniumApplication
 			Log.e(LCAT, &quot;Error loading tiapp.xml&quot;, e);
 		}
 
-		analyticsIntent = new Intent(this, TitaniumAnalyticsService.class);
-
 		TitaniumPlatformHelper.initialize(this);
-		analyticsModel = new TitaniumAnalyticsModel(this);
 
-		needsEnrollEvent = analyticsModel.needsEnrollEvent();
+		if (appInfo.collectAnalytics()) {
+			analyticsIntent = new Intent(this, TitaniumAnalyticsService.class);
+			analyticsModel = new TitaniumAnalyticsModel(this);
+			needsEnrollEvent = analyticsModel.needsEnrollEvent();
+		} else {
+			needsEnrollEvent = false;
+			needsStartEvent = false;
+			Log.i(LCAT, &quot;Analytics have been disabled&quot;);
+		}
 	}
 
 	@Override
@@ -202,6 +207,12 @@ public class TitaniumApplication
 
 	public synchronized void postAnalyticsEvent(TitaniumAnalyticsEvent event)
 	{
+		if (!appInfo.collectAnalytics()) {
+			if (DBG) {
+				Log.i(LCAT, &quot;Analytics are disabled, ignoring postAnalyticsEvent&quot;);
+			}
+			return;
+		}
 
 		if (DBG) {
 			StringBuilder sb = new StringBuilder();
@@ -244,8 +255,10 @@ public class TitaniumApplication
 	}
 
 	public void sendAnalytics() {
-		if (startService(analyticsIntent) == null) {
-			Log.w(LCAT, &quot;Analytics service not found.&quot;);
+		if (analyticsIntent != null) {
+			if (startService(analyticsIntent) == null) {
+				Log.w(LCAT, &quot;Analytics service not found.&quot;);
+			}
 		}
 	}
 </diff>
      <filename>android/titanium/src/org/appcelerator/titanium/TitaniumApplication.java</filename>
    </modified>
    <modified>
      <diff>@@ -82,6 +82,7 @@ public class TiAppXmlHandler extends DefaultHandler
 		} else {
 			if (&quot;id&quot;.compareTo(localName) == 0 || &quot;name&quot;.compareTo(localName) == 0 ||
 				&quot;version&quot;.compareTo(localName) == 0 || &quot;icon&quot;.compareTo(localName) == 0 ||
+				&quot;analytics&quot;.compareTo(localName) == 0 ||
 				/* Properties unsupported on Android */
 				&quot;persistent-wifi&quot;.compareTo(localName) == 0 ||
 				&quot;prerendered-icon&quot;.compareTo(localName) == 0 ||
@@ -193,7 +194,9 @@ public class TiAppXmlHandler extends DefaultHandler
 				tai.setAppCopyright(getTextAndClear());
 			} else if (&quot;url&quot;.compareTo(localName) == 0) {
 				tai.setAppURL(getTextAndClear());
-			} else if (&quot;property&quot;.compareTo(localName) == 0) {
+			} else if( &quot;analytics&quot;.compareTo(localName) == 0) {
+				tai.setCollectAnalytics(getTextAndClear());
+ 			} else if (&quot;property&quot;.compareTo(localName) == 0) {
 				if (currentPropertyName == null) {
 					Log.e(LCAT, &quot;property element missing name attribute value: &quot; + currentText.toString());
 					clearText();</diff>
      <filename>android/titanium/src/org/appcelerator/titanium/config/TiAppXmlHandler.java</filename>
    </modified>
    <modified>
      <diff>@@ -50,6 +50,7 @@ public class TitaniumAppInfo
 	protected String appCopyright;
 	protected String appGUID;
 	protected String appPublisher;
+	protected boolean appCollectAnalytics;
 
 	protected HashMap&lt;String, TitaniumWindowInfo&gt; windows;
 	protected ArrayList&lt;TitaniumModuleInfo&gt; modules;
@@ -91,6 +92,8 @@ public class TitaniumAppInfo
 		String versionString = systemProperties.getString(&quot;ti.version&quot;, &quot;0.0.0&quot;);
 		systemProperties.setString(PROP_NETWORK_USER_AGENT, NETWORK_USER_AGENT + &quot; Titanium/&quot; + versionString);
 
+		appCollectAnalytics = true;
+
 		if (DBG) {
 			Log.d(LCAT, &quot;Default Titanium system properties loaded.&quot;);
 		}
@@ -197,6 +200,16 @@ public class TitaniumAppInfo
 		return this.appURL;
 	}
 
+	public boolean collectAnalytics() {
+		return appCollectAnalytics;
+	}
+
+	public void setCollectAnalytics(String collectAnalytics) {
+		if (collectAnalytics != null) {
+			appCollectAnalytics = Boolean.parseBoolean(collectAnalytics);
+		}
+	}
+
 	public ArrayList&lt;TitaniumWindowInfo&gt; getWindows() {
 		ArrayList&lt;TitaniumWindowInfo&gt; ws = new ArrayList&lt;TitaniumWindowInfo&gt;(windows.values());
 		Collections.sort(ws);</diff>
      <filename>android/titanium/src/org/appcelerator/titanium/config/TitaniumAppInfo.java</filename>
    </modified>
    <modified>
      <diff>@@ -41,6 +41,12 @@ public class TitaniumAnalytics extends TitaniumBaseModule implements ITitaniumAn
 
 	public void addEvent (String type, String event, String data)
 	{
-		app.postAnalyticsEvent(TitaniumAnalyticsEventFactory.createEvent(type, event, data));
+		if (app.getAppInfo().collectAnalytics()) {
+			app.postAnalyticsEvent(TitaniumAnalyticsEventFactory.createEvent(type, event, data));
+		} else {
+			if (DBG) {
+				Log.i(LCAT, &quot;Ignoring addEvent, analytics have been disabled&quot;);
+			}
+		}
 	}
 }
\ No newline at end of file</diff>
      <filename>android/titanium/src/org/appcelerator/titanium/module/TitaniumAnalytics.java</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,6 @@
 &lt;url&gt;appcelerator.com&lt;/url&gt;
 &lt;copyright&gt;2009 by nwright&lt;/copyright&gt;
 	&lt;description&gt;Mobile Unit Test App&lt;/description&gt;
-
 &lt;icon&gt;appicon.png&lt;/icon&gt;
     &lt;windows&gt;
         &lt;window&gt;</diff>
      <filename>demos/KitchenSink/tiapp.xml</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>173a64ca7e03ddfe17f34643603d5abf97b500b7</id>
    </parent>
  </parents>
  <author>
    <name>donthorp</name>
    <email>don@donthorp.net</email>
  </author>
  <url>http://github.com/appcelerator/titanium_mobile/commit/fbdc59d9b2c9597b64b04710b96962a877ffc161</url>
  <id>fbdc59d9b2c9597b64b04710b96962a877ffc161</id>
  <committed-date>2009-11-15T12:36:59-08:00</committed-date>
  <authored-date>2009-11-15T12:36:59-08:00</authored-date>
  <message>[#246 state:resolved] Added ability to turn off analytics via tiapp.xml</message>
  <tree>2ee437782829bad1e67179b917ce74939f47c3c7</tree>
  <committer>
    <name>donthorp</name>
    <email>don@donthorp.net</email>
  </committer>
</commit>
