简体   繁体   中英

Google Analytics v4 cannot be cast to Analytics

I try to implement the Google Analytics in my App. The Problem is I get in LogCat the message:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.name.appname/com.name.appname.activity.MainActivity}: java.lang.ClassCastException: com.name.appname.misc.AppApplication cannot be cast to com.name.appname.activity.Analytics

global_tracker.xml

<integer name="ga_sessionTimeout">300</integer>

<!-- Enable automatic Activity measurement -->
<bool name="ga_autoActivityTracking">true</bool>

<!-- Enable verbose logging -->
<String name="ga_loglevel">verbose</String>

<!-- Screen names on the reports -->
<screenName name="com.name.appname.activity.MainActivity">
    MainActivity ScreenView
</screenName>

<!--  Tracking ID -->
<string name="ga_trackingId">UA-xxxxxxx-2</string>

ANALytics.java:

public class Analytics extends Application {

public static int GENERAL_TRACKER = 0;

public enum TrackerName {
    APP_TRACKER, // Tracker used only in this app.
    GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg: roll-up tracking.
    ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a company.
}

HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();


synchronized Tracker getTracker(TrackerName trackerId) {
    if (!mTrackers.containsKey(trackerId)) {

        GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
        Tracker t = analytics.newTracker(R.xml.global_tracker);
        mTrackers.put(trackerId, t);

    }
    return mTrackers.get(trackerId);
}
}

manifest:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:name=".misc.AppApplication" >

       <activity
        android:name=".activity.Analytics"
        android:allowBackup="true"
        android:label="@string/app_name"
        android:screenOrientation="portrait" >
    </activity>

MainActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    adView = (AdView) this.findViewById(R.id.adView);

    // Get tracker.
    Tracker tracker = ((Analytics)getApplication()).getTracker(Analytics.TrackerName.GLOBAL_TRACKER);
    tracker.send(new HitBuilders.EventBuilder()
       .setCategory("Use")
       .setAction("Use Programm")
       .setLabel("submit")
       .build());

@Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        GoogleAnalytics.getInstance(MainActivity.this).reportActivityStart(this);
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        GoogleAnalytics.getInstance(MainActivity.this).reportActivityStop(this);
    }

In my manifest i have already declared android:name=".misc.AppApplication" at application. there is my check for PremiumUsers .

Here is my misc.AppApplication:

import android.app.Application;

public class AppApplication extends Application {

private boolean mIsPremium;
public void setPremium(){
    mIsPremium = true;
}
public boolean isPremium(){
    return mIsPremium;
}
}

where is the problem?

You are setting the name attribute of your application element in the manifest to ".misc.AppApplication". That instructs Android to instantiate .misc.AppApplication class as application instead of the default Application. In your MainActivity class you try to cast .misc.AppApplication to Analytics and that will throw ClassCastException.

The correct setup is to replace the Application class with Analytics (the class that extends Android Application class) and keep MainActivity as the class implementing your main activity.

You should also not be logging events from onCreate override. Activity can be created for reasons other then starting the app. For example when the device changes from landscape to portrait mode Android will ask the activity to save its state to a bundle, tear it down and recreate it passing the saved state in savedInstanceState. onCreate will be called in this case again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM