Getting GoogleAnalytics working in all activities - java

I want to track all activities and button clicks throughout my 7 activities in my app. Right now I am at the beginning of implementing GA. I have it working in my opening main menu screen and can view it online on google.com/analytics. My question is how to implement this into all activities?
Right now in my main menu class I have this:
private Tracker tracker;
private GoogleAnalytics ga;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.mainmenumain);
EasyTracker.getInstance().activityStart(this);
//Get the GA singleton.
ga = GoogleAnalytics.getInstance(this);
//ga.setDebug(true);
//Use the GA singleton to get a Tracker object.
tracker = ga.getTracker("UA-###-1");
Do I have to declare the 2 variables and then call EasyTracker.getInstance().activityStart(this);, ga = GoogleAnalytics.getInstance(this); and tracker = ga.getTracker("UA-####-1"); in every activity?
I know there are similar topics out there but I am asking this for the new version 2 of Google Analytics and not the legacy version 1.

Implement a new BaseActivity to do the work in it's onCreate method, then make all your 7 activities extends BaseActivity.
Remember to call super.onCreate in your activities.

For Analytcs V2, these are the only 2 lines you need in your Activities:
EasyTracker.getInstance().activityStart(this);
Tracker trackerV2 = EasyTracker.getTracker();
You are kind of mixing up V1 and V2 calls. The tracker instantiation (associating your API key) is set via a attribute in the manifest, so you no longer need the lines:
tracker = ga.getTracker("UA-####-1");

Related

Android O device blank screen after addView / setContentview

I recently decided to update my older apps and bring them a little more up to date. In doing so I noticed an odd problem when running them on my new handset (Android O / API Level 29).
My App is essentially a single Activity using OpenGL. This is basically what happens when the app is first loaded...
Create Layout, Create a Splashscreen View, create custom GLSurfaceView
Add GLSurfaceView to Layout
Add Splashscreen to Layout
Start AsyncTask to load resources and do setup ops
GLSurfaceView dismisses Splashscreen to reveal renderer...
So, it all works perfectly well on my older devices (3 x handsets, 1 x tablet all running various versions of Android no higher than Lollipop).
However, on my Android 10 handset, all I get is a blank screen while the app starts. Just to be clear, there are no errors, the app itself works perfectly fine. After the usual startup time, the blank screen is dismissed and the app continues, it's just that the 'splashscreen' has now become a "blankscreen".
But Android Studio Layout Inspector tells a different story
Indeed, if I open the Layout Inspector in Android Studio, oddly it shows exactly what I would expect... the splashscreen with its text/graphics, but not on the actual device...
Some test code
In the following test code I replaced the resource loading / setup with a simple Thread.sleep just to create a longer delay so I could more easily inspect the output in Android Studio. This does still exhibit the problem...
#Override
protected void onCreate(Bundle savedInstanceState) {
int[] deviceResolution = getDeviceResolution();
width = deviceResolution[0];
height = deviceResolution[1];
layout = new RelativeLayout(this);
splash = new Splash(getApplication(), width, height);
myGLView = new CustomGLSurfaceView(this.getApplication());
layout.addView(myGLView);
layout.addView(splash);
setContentView(layout);
loadResource = new LoadResources(newBundle);
loadResources.execute();
super.onCreate(savedInstanceState);
}
class LoadResources AsyncTask<Void, Void, Void> {
Bundle savedBundle;
LoadResources(Bundle savedBundle){
this.savedBundle=savedBundle;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// Simulate some long-running task here. While this is happening, splashscreen should be visible. And on older devices, it is. Not on Android O handset (but OK in Android Studio Layout Inspector).
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Would typically make my calls here to load resources, and complete other setup tasks here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
** Other observations **
I know that Async is now deprecated and I'm also aware of other Splashscreen tecnhiques such as using a dedicated Activity. However due to the setup/complexity of the apps and given that it doesn't 'break' them per-se, I don't want to have to refactor the entire codebase (just yet anyway) any new apps going forward will use a different system for the splashscreen. What I'm really trying to understand here is why this now doesn't work as it used to. Is this a bug? Or a behavioural change that happened in an Android version somewhere down the line? Or maybe it's just me doing something wrong. If anyone has come across it, I'd be really interested to know of a fix/workaround.
** Other things I've tried **
In the above example, if I simply don't add 'myGLView' then the splashscreen shows, but of course the app then won't work. So I though about adding it in onPostExecute and then bringing the splashscreen view back to the front with splash.bringToFront(). This kind of works, but is messy. The splashscreen only shows for a brief second, and on devices that show it correctly there is a 'glitch' as the correctly displayed splashscreen is overlayed with the GL Renderer and then bought back to the front.
You are adding a view to an object which is not currently set in an Activity.
The better approach would be calling setContentView() first as well as the super method, then adding the multiple views in it.
So in your case, it'll be like:
super.onCreate(savedInstanceState);
setContentView(layout);
layout = new RelativeLayout(this);
int[] deviceResolution = getDeviceResolution();
width = deviceResolution[0];
height = deviceResolution[1];
layout = new RelativeLayout(this);
splash = new Splash(getApplication(), width, height);
myGLView = new CustomGLSurfaceView(this.getApplication());
layout.addView(myGLView);
layout.addView(splash);
loadResource = new LoadResources(newBundle);
loadResources.execute();

Android webview using html+jquery inside app hangs sometimes

i had made html+jquery mobile app using webview , my all code is inside assest folder, i noticed sometime my app hangs and sometime it works fine ,if i am missing some thing
below is android java code
i made html +jquery app , app hangs most of time , and some time it works any way to make it work fine
below problem:
1: some time object in canvas gets duplicated however there is not changes of getting duplicate object on any of canvas this problem occurs only in android browser
2: sometime while dragging object gets stuck any where without being dropped in canvas only in android browser
below is my java code for that
public class MainActivity extends Activity implements OnClickListener {
private static final String URL = "file:///android_asset/index.html";
private WebView mWebView;
#SuppressLint("SetJavaScriptEnabled")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.setWebViewClient(new WebViewClient(){
});
refreshWebView();
}
private void refreshWebView() {
mWebView.loadUrl(URL);
}
#Override
public void onClick(View v) {
refreshWebView();
}
}
and html code that i am using inside assest folde is below link
http://liveweave.com/JckSgC
I faced this bug before 6 months ago. After a lot lot of research on this topic I personally concluded that Its a API bug of android which was fixed in API level 18(KITKAT).
It means, "If the application is working on an android version less than Kitkat, webview starts hanging or works madly"
Reason:
WebView's of android version less than KITKAT doesn't support HTML5 and CSS3.
http://www.mobilexweb.com/blog/android-4-4-kitkat-browser-chrome-webview
Suggestions:
You can use external webviews like "ChromiumWebView"
(Link of ChromiumWebView https://github.com/pwnall/chromeview )
Or you can restrict your application to only runs on android version greater than or equivalent to KITKAT. (I personally doesn't prefer this)

Are Activity/Fragment Transitions compatible with pre-Lollipop devices?

I'm trying to make an Activity Transition using Shared Elements on a pre-Lollipop device (4.x). Is it possible? So far, I'm trying this:
public class RewardDetail extends ActionBarActivity {
#Override
public void onCreate(final Bundle savedInstanceState) {
...
ViewCompat.setTransitionName(imageView, TRANSITION_NAME);
}
...
public static void launch(ActionBarActivity activity, View transitionView, WelcomeReward detailData) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, transitionView, TRANSITION_NAME);
Intent intent = new Intent(activity, RewardDetail.class);
intent.putExtra(PARAM_DATA, detailData);
ActivityCompat.startActivity(activity, intent, options.toBundle());
}
}
called by:
#Override
public void onClick(final View v) {
int position = recyclerView.getChildPosition(v);
WelcomeReward welcomeReward = data.get(position);
RewardDetail.launch(WelcomeRewardActivity.this, v.findViewById(R.id.reward_view), welcomeReward);
}
But it results in a "regular" transition (no shared element). Any ideas?
EDIT
According to this video, it could be done:
https://www.youtube.com/watch?v=RhiPJByIMrM&index=8&list=WL
Is there a library already implementing this for pre Lollipop ?
No, Activity/Fragment Transitions are not possible on pre-Lollipop devices. According to the documentation:
Start an activity with additional launch information, if able.
In Android 4.1+ additional options were introduced to allow for more control on activity launch animations. Applications can use this method along with ActivityOptionsCompat to use these animations when available. When run on versions of the platform where this feature does not exist the activity will be launched normally.
See also George Mount's answer to this StackOverflow question.
You can check out this library for activity and fragment transitions for pre lollipop devices
dependencies {
compile 'com.albinmathew:PreLollipopTransition:1.1.2'
}
https://github.com/albinmathew/PreLollipopTransition
Although the fancy Lollipop Activity/Fragment transitions are not available pre-Lollipop (without the use of a 3rd party library), you can still override the animation used to transition between activities.
Just before/after you start invoke startActivity() you can make a call to [Activity.overridePendingTransition](http://developer.android.com/reference/android/app/Activity.html#overridePendingTransition(int, int)). When you leave your activity, call the same method.
Similarly you can use ActivityOptionsCompat to define a custom animation to use during a transition.
ActivityOptionsCompat opts =
ActivityOptionsCompat.makeCustomAnimation(getActivity(), R.anim.in, R.anim.out);
startActivity(intent, opts.toBundle());
There is a support library, but it does not support (all) transitions on Android versions below 5.0. There are however some alternatives:
Unofficial Compatibility libraries https://github.com/andkulikov/transitions-everywhere
https://github.com/takahirom/PreLollipopTransition
https://github.com/lgvalle/Material-Animations
Android KitKat http://www.doubleencore.com/2013/11/new-transitions-framework/ and a
sample found in your SDK samples folder.
Posted earlier to a duplicate of this question here: https://stackoverflow.com/a/27344471/1683141

Mac Address or IMEI on Libgdx Android App

I'm developing a APP to android using LIGBDX, i need to get the MAC ADDRES or IMEI or any other unique code from the phone. When using NetworkInterface from Java.net works fine on Desktop project, but on Android it doesnt work, so i saw on the internet the WifiManger,
is a API (i guess) from android.
WifiManager wifiMan = (WifiManager) this.getSystemService( Context.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();
String macAddr = wifiInf.getMacAddress();
And it seens it works, BUT i'm using LIBGDX and i not getting to import Android.Net on my project, saw one guys talking when i try to references pure android on LIbgdx i have to work only on android not in Core, but i dont know how to do this.
Maybe add Wifimanager.java into library i tried that but not work.
Note: i am using Gdx Net and edited the manifest, i am dowloading and send data from iternet, i cant do only the mac part
Try this:
1)
Declare an Interface in your core project with a method to retrieve the number you want.
public interface IActivityRequestHandler {
public String getUniqueId();
}
In your core project, add a constructor to your Game class that takes a IActivityRequestHandler as a parameter:
public abstract class MyGame extends Game {
...
public IActivityRequestHandler handler;
...
public MyGame(IActivityRequestHandler handler){
this.handler = handler;
}
You will use "handler" to call platform specific methods.
2)
Make the android MainActivity implement this interface and write the methood to return the value you need.
3) In your Android MainActivity, when you instantiate your AndroidGame, pass the MainActivity as a parameter:
public class MainActivity extends AndroidApplication implements IActivityRequestHandler{
...
ApplicationListener game;
....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
game = new AndroidMyGame(this);
...
}
public String getUniqueId(){
return uniqueId;
}
...
}
4) Now when you need the id from the core you call: handler.getUniqueId() (from MyGame class)
This will be calling the method on your Android MainActivity if you are running the game from an Android Device.
Important notes:
1) This should work if you don't have any contraints regarding the UI Thread in Android.
This is, to return a value it should work. If you call anything that can only be called in the UIThread this won't work and, aditionally, you have to use a Handler to communicate between threads.
2) Your Desktop version will also have to implement IActivityRequestHandler.
3) Getting a unique id in Android devices is something I haven't found a nice solution yet.
a) Tablets, unless they have a phone line, don't have IMEI or telephone number.
b) MAC Addresses are not unique (you have 3g, wifi, bluetooth) and sometimes are not available for example if wifi is turned off.
4) You might be better off generating a unique id yourself and storing it on the phone.
google "Java UUID".

How to get tabs in ICS and gingerbread to look the same?

Being new to android development, i have created a project using tabs using tutourials.
on Gingerbread it looks sort of like :
While on ICS(emulator) it looks like:
Because of the sort of "Holo" type teme i have going i cant have the tab on the gingerbread style. I need help please it is killing me. Please dont tell me i have to figure out how to design it myself for Gingerbread i'll cry.
here is what i did:
public class MainActivity extends FragmentActivity
{
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.tabframelayout);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab 1"),
FragmentTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab 2"),
FragmentTab.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Tab 3"),
FragmentTab.class, null);
}
It is greatly suggested that you use Action Bar Tabs rather than using TabHost. While the Action Bar was added in Honeycomb, you can use compatibility libraries like ActionBarSherlock (which would give you consistent tabs across all devices and my personal recommendation) or follow the Creating Backward-Compatible UIs training (which is very similar to what you are doing now).

Categories

Resources