I'm using beta 4 of google analytics V2 within my android app. For convenience I'm wrapping it in a separate class (singleton) like this:
private AnalyticsTracker(Context context) {
GAServiceManager.getInstance().setDispatchPeriod(5);
GoogleAnalytics googleAnalytics = GoogleAnalytics.getInstance(context);
googleAnalytics.setDebug(true);
tracker = googleAnalytics.getTracker(context.getString(R.string.ga_trackingId));
}
For further usage I use the EasyTracker for activity tracking and the tracker member variable for event tracking.
public void onActivityStart(Activity activity) {
EasyTracker.getInstance().activityStart(activity);
}
public void onActivityStop(Activity activity) {
EasyTracker.getInstance().activityStop(activity);
}
public void trackEvent(AnalyticsEvent event) {
tracker.sendEvent(event.category, event.action, event.label, 0L);
GAServiceManager.getInstance().dispatch();
}
The problem is that setDebug(true) in the constructor seems to be ignored as there is no output on LogCat and my interaction appears in the reports. I'm not setting the debug flag in the analytics.xml.
If I do so and set the flag to true in the xml file it works as expected and analytics logs the events to LogCat.
Any idea why it ignores the call from the code?
Thanks
Use <bool name="ga_debug">false</bool> in analytics.xml in values folder for enableing disabling debug.
analytics.xml:
<!-- Replace placeholder ID with your tracking ID -->
<string name="ga_trackingId">UA-123456-2</string>
<!-- Enable automatic activity tracking -->
<bool name="ga_autoActivityTracking">true</bool>
<!-- Enable automatic exception tracking -->
<bool name="ga_reportUncaughtExceptions">true</bool>
<!-- Enable debug -->
<bool name="ga_debug">false</bool>
<!-- The screen names that will appear in your reporting -->
<string name="com.example.myapp.MainActivity">any name</string>
<!--The inverval of time after all the collected data should be sent to the server, in seconds.-->
<integer name="ga_dispatchPeriod">30</integer>
Ref: link
Related
I created a separate layout for tablets in android studio, but I'm unable to run that particular layout, whenever I try to run it, it default runs the normal layout, which is for mobile
I have to agree with the user Ricardo but having said that, I need some more information. First of all how you load the layout, what is the layout name and where did you place these layouts.
Check this before https://developer.android.com/training/multiscreen/screensizes.html and you have to do something like this.
In your manifest
<resources>
<bool name="isTablet">true</bool>
</resources>
<resources>
<bool name="isTablet">false</bool>
</resources>
In your Mainactivity
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
// do something
} else {
// do something else
}
The problem is about creating an app that uses Watson chatbot.
Well, I used Vidyasagar Machupalli code the app worked but the part of chatbot didn't. Here is the logcat error:
(2019-04-28 07:36:02.927 4315-4372/com.example.vmac.chatbot D/OkHttp: <-- 404 Not Found https://gateway-lon.watsonplatform.net/assistant/api/v2/assistants/81d0c0e2-5c74-45c6-9f3b-63bcf1b0b281/sessions?version=2018-11-08 (662ms, 105-byte body)
2019-04-28 07:36:02.966 4315-4372/com.example.vmac.chatbot E/WatsonService: POST https://gateway-lon.watsonplatform.net/assistant/api/v2/assistants/81d0c0e2-5c74-45c6-9f3b-63bcf1b0b281/sessions?version=2018-11-08, status: 404, error: NotFound: No Agent definition found for id: 81d0c0e2-5c74-45c6-9f3b-63bcf1b0b281
2019-04-28 07:36:02.974 4315-4372/com.example.vmac.chatbot W/System.err: com.ibm.watson.developer_cloud.service.exception.NotFoundException: NotFound: No Agent definition found for id: 81d0c0e2-5c74-45c6-9f3b-63bcf1b0b281)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Watson Assistant service credentials-->
<!-- REPLACE `ASSISTANT_ID_HERE` with ID of the Assistant to use -->
<string name="assistant_id">####################################</string>
<!-- REPLACE `ASSISTANT_API_KEY_HERE` with Watson Assistant service API Key-->
<string name="assistant_apikey">##################################</string>
<!-- REPLACE `ASSISTANT_URL_HERE` with Watson Assistant service URL-->
<string name="assistant_url">https://gateway-lon.watsonplatform.net/assistant/api</string>
<!--Watson Speech To Text(STT) service credentials-->
<!-- REPLACE `STT_API_KEY_HERE` with Watson Speech to Text service API Key-->
<string name="STT_apikey">#############################</string>
<!-- REPLACE `STT_URL_HERE` with Watson Speech to Text service URL-->
<string name="STT_url">https://gateway-lon.watsonplatform.net/speech-to-text/api</string>
<!--Watson Text To Speech(TTS) service credentials-->
<!-- REPLACE `TTS_API_KEY_HERE` with Watson Text to Speech service API Key-->
<string name="TTS_apikey">############################</string>
<!-- REPLACE `TTS_URL_HERE` with Watson Text to Speech service URL-->
<string name="TTS_url">https://gateway-lon.watsonplatform.net/text-to-speech/api</string>d
The reason you are seeing the error is instead of Assistant ID you are passing Skill ID in your config.xml. Create an Assistant using the Skill you created and pass the Assistant ID in the config.xml
Here's how you can link your Skill to an Assistant
Also. never share your credentials in public forums.
Updated: Here's where you can find your Assistant ID by clicking Settings as shown in the image below and then API Details
I've added Google Analytics to my mobile application by using the google-services.json file.
Now I've enabled auto activity tracking and I want to provide a screen name for each activity.
Google documents say, I should add
<screenName name=".MyActivity">My activity</screenName>
to my XML configuration file. Where's this coming from? I don't have a xml config file, I have a google-services.json file.
Do I need to create a XML file inside res/xml/ ?
What values are necessary as I am currently using the android default R.xml.global_tracker ?
Or do I need to add these screen-name information to the json file and if yes, whats the structure then?
Thanks in advance.
You could create your own XML. Here is mine, remember to replace your tracking ID:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ga_trackingId" translatable="false">UA-99999999-1</string>
<!-- Enable automatic Activity measurement -->
<bool name="ga_autoActivityTracking">true</bool>
<!-- The screen names that will appear in reports -->
<screenName name="com.codylab.squats.MainActivity">MainActivity</screenName>
<screenName name="com.codylab.squats.SettingsActivity">SettingsActivity</screenName>
<screenName name="com.codylab.squats.BreakActivity">BreakActivity</screenName>
<screenName name="com.codylab.squats.FinishedActivity">FinishedActivity</screenName>
<screenName name="com.codylab.squats.InitialActivity">InitialActivity</screenName>
<screenName name="com.codylab.squats.WorkoutActivity">WorkoutActivity</screenName>
</resources>
Create an Application class:
public class YourNameApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Stetho.initializeWithDefaults(this);
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
// To enable debug logging use: adb shell setprop log.tag.GAv4 DEBUG
analytics.newTracker(R.xml.squats_tracker);
}
}
Add a name attribute of application tag in your AndroidMenifest.xml
...
<application
android:name=".YourNameApplication"
...>
...
</application>
I'm looking for a way to document a layout file to improve its reusability.
What I'd like is something that produces javadoc in generated R file like this.
I know it is possible to do so when using <declare-styleable>. This :
<declare-styleable name="myStyleable">
<!-- Some comment -->
<attr name="someAttr" format"color" />
</declare-styleable>
Produces this output i'd like to obtain for layout files without success :
public final class R {
/** Some comment */
public static final int someAttr...
}
Does someone know of the mean to achieve this ? I'm interrested in :
Documenting the layout file, so that documentation be available when using R.layout.my_layout
Documenting a particular element of the file, so that the documentation be available when finding it by id f.e. aView.findViewById(R.id.the_id_that_is_documented)
By the way, I found part of the response : for ids it is possible to add comments if the id is defined in a resource file (in res/values) :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- This is a comment -->
<item name="myId" type="id"></item>
</resources>
Will produce this result in R.class :
public final class R {
public static final class id {
/** This is a comment
*/
public static int myId=0x7f050007;
}
This won't work directly in the layout file if you use #+id/some_cute_id
Edit : and here's the answer for layout files. In fact it might work for everything (Found it browsing sdk sources in res/values/public.xml). This :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
* This layout contains a list that enables to choose a bluetooth device to pair with among paired ones -->
<public type="layout" name="devices_choose" id="0x7f030005" />
</resources>
Produces this output in R :
public final class R {
public static class layout {
/**
* This layout contains a list that enables to choose a bluetooth device to pair with among paired ones
*/
public static final int devices_choose=0x7f030005;
}
}
I am a little bit confused about the ComponentName class in Android.
There are different ways to get to a component name object, but I don't know when to use which... and why!
Example:
Application package is de.zordid.sampleapp
but widget provider class is de.zordid.sampleapp.widget.WidgetProvider
Using
ComponentName cn = new ComponentName("de.zordid.sampleapp.widget",
"WidgetProvider");
I got this component info: ComponentInfo{de.zordid.sampleapp.widget/WidgetProvider}, but I could not use this - the component is unknown!
But the JavaDoc says I should give the package and the class within that package - and that is what I did, didn't I??
Using
ComponentName cn = new ComponentName(context, WidgetProvider.class);
yields ComponentInfo{de.zordid.sampleapp/de.zordid.sampleapp.widget.WidgetProvider} - and that works fine!!
There is even another way to get a ComponentName - by context and a string.
Which one should be used where and when??
Thanks!
The ComponentName constructor taking two Strings can be used to refer to a component in another application. But, the first argument is not the package name of the class; it is the package name of the application---the package attribute of the manifest element in that application's AndroidManifest.xml. So your first example should be
ComponentName cn = new ComponentName("de.zordid.sampleapp",
"de.zordid.sampleapp.widget.WidgetProvider");
That constructor could certainly be used to refer to components in your own application, but since you already have hold of a Context from your own application you might as well use it and use one of the other constructors. In my opinion, the one taking a Class should be preferred whenever usable. You could use the one taking a String if you only know the class dynamically for some reason; in that case, it should take the fully-qualified class name as above.
Robert Tupelo-Schneck's answer is right about preferring objects against Strings. Here's how I see it with details on how all the different prefixes work.
To refer to your own components, use:
new ComponentName(getApplicationContext(), WidgetProvider.class);
To refer to some dynamically referenced component in your own app, use:
// values/strings.xml: <string name="provider">de.zordid.sampleapp.widget.WidgetProvider</string>
String fqcn = getResources().getString(R.string.provider);
new ComponentName(getApplicationContext(), fqcn);
This is useful when you want to use Android's resource qualifiers to decide which component to use, you can override the default string in values-*/strings.xml.
To refer to another application's component, use:
int componentFlags = GET_ACTIVITIES | GET_PROVIDERS | GET_RECEIVERS | GET_SERVICES;
PackageInfo otherApp = context.getPackageManager().getPackageInfo("com.other.app", componentFlags);
ComponentInfo info = otherApp.activities[i]; // or providers/receivers/...
new ComponentName(info.packageName, info.name);
#About .Names and <manifest package="
There may be some confusion here because I think historically Robert's statement was true:
it is the package name of the application---the package attribute of the manifest element in that application's AndroidManifest.xml
but not any more. Since the new Gradle build system was introduced there has been some changes around here, and then they changed it again in AGP 7.3, and made it mandatory in AGP 8.0.
If you have an android.defaultConfig.applicationId specified in your build.gradle that'll be the app package name, and then package attribute in manifest (or later namespace in build.gradle) is a separate thing when building your app. The first argument of ComponentName now refers to applicationId + applicationIdSuffix. The tricky thing is that after the final manifest merge and packaging the APK will have <manifest package=applicationId + applicationIdSuffix and all the .Names will be expanded to FQCNs.
Example app for learning name resolution
Here's an example structure based on the structure of one of my apps. Consider the following classes in a hypothetical app called "app":
net.twisterrob.app.android.App
net.twisterrob.app.android.GlideSetup
net.twisterrob.app.android.subpackage.SearchResultsActivity
net.twisterrob.app.android.subpackage.Activity
net.twisterrob.app.android.content.AppProvider
on the server side backend of the app and/or some shared model classes:
net.twisterrob.app.data.*
net.twisterrob.app.backend.*
net.twisterrob.app.web.*
in my Android helper library:
net.twisterrob.android.activity.AboutActivity
other libraries:
android.support.v4.content.FileProvider
This way everything is namespaced in net.twisterrob.app. The android app being just a single part of the whole inside it's own subpackage.
AndroidManifest.xml (irrelevant parts omitted)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.twisterrob.app.android">
<!--
`package` above defines the base package for .Names
to simplify reading/writing the manifest.
Notice that it's different than the `applicationId` in build.gradle
and can be independently changed in case you want to refactor your packages.
This way you can still publish the same app with the same name.
-->
<!-- Will be expanded to net.twisterrob.app.android.App in the manifest merging phase. -->
<application android:name=".App">
<!-- meta-data needs FQCNs because the merger can't know if you want to expand them or not.
Also notice that name and value both can contain class names, depending on what you use. -->
<meta-data android:name="net.twisterrob.app.android.GlideSetup" android:value="GlideModule" />
<meta-data android:name="android.app.default_searchable" android:value="net.twisterrob.app.android.subpackage.SearchResultsActivity" />
<!-- Will be expanded to net.twisterrob.app.android.subpackage.Activity in the manifest merging phase. -->
<activity android:name=".subpackage.Activity" />
<!-- Needs full qualification because it's not under the package defined on manifest element. -->
<activity android:name="net.twisterrob.android.activity.AboutActivity" />
<!-- Will be expanded to net.twisterrob.app.android.content.AppProvider in the manifest merging phase. -->
<provider android:name=".content.AppProvider" android:authorities="${applicationId}" />
<!-- Needs full qualification because it's not under the package defined on manifest element. -->
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.share" />
</application>
<!-- ${applicationId} will be replaced with what's defined in `build.gradle` -->
</manifest>
build.gradle
android {
defaultConfig {
// this is what will be used when you upload it to the Play Store
applicationId 'net.twisterrob.app'
// in later AGP versions, move manifest's package here:
// namespace 'net.twisterrob.app.android'
}
buildTypes {
debug {
// The neatest trick ever!
// Released application: net.twisterrob.app
// IDE built debug application: net.twisterrob.app.debug
// This will allow you to have your installed released version
// and sideloaded debug application at the same time working independently.
// All the ContentProvider authorities within a system must have a unique name
// so using ${applicationId} as authority will result in having two different content providers.
applicationIdSuffix '.debug'
}
}
}
To check out what your final manifest will look like after all the merging open build\intermediates\manifests\full\debug\AndroidManifest.xml.
Or you can use like this inside BroadcastReceiver :
ComponentName smsReceiver = new ComponentName(this, SMSReceiver.class);