Matej Očovský Matej Očovský - 3 months ago 32
Java Question

java.lang.ExceptionInInitializerError when button is clicked

I am making an app that tracks the user based on GPS.
When I press the button to move to another intent I get this error.
I didn't get this error when testing on Samsung Galaxy S5 with Android v6.
Error has appeared on HTC that has Android v4.4.4

Here's the error:

java.lang.ExceptionInInitializerError
at com.example.matej.locato.TrackingActivity.l(Unknown Source)
at com.example.matej.locato.TrackingActivity.b(Unknown Source)
at com.example.matej.locato.TrackingActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:5312)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2395)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2495)
at android.app.ActivityThread.access$800(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5633)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Missing type parameter.
at com.google.a.c.a.a(Unknown Source)
at com.google.a.c.a.<init>(Unknown Source)
at com.google.a.k.<init>(Unknown Source)
at com.google.a.j.<clinit>(Unknown Source)
at com.example.matej.locato.TrackingActivity.l(Unknown Source) 
at com.example.matej.locato.TrackingActivity.b(Unknown Source) 
at com.example.matej.locato.TrackingActivity.onCreate(Unknown Source) 
at android.app.Activity.performCreate(Activity.java:5312) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2395) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2495) 
at android.app.ActivityThread.access$800(ActivityThread.java:153) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:157) 
at android.app.ActivityThread.main(ActivityThread.java:5633) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712) 
at dalvik.system.NativeStart.main(Native Method) 


This is the button code :

public void button_click_clicked(View view) {

// check if user has location
if (user.updated) {
// create new intent with TrackingActivity
Intent intent = new Intent(this, TrackingActivity.class);

// start activity
startActivity(intent);

//start tracking and create target
//TrackingActivity.startTracking(user.updated);
} else {
// user has not received location yet
Toast.makeText(MainActivity.this, "Please wait for GPS signal", Toast.LENGTH_SHORT).show();
}
}


And code for the Activity that throws the error:

package com.example.matej.locato;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.InputType;
import android.text.Layout;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.gson.Gson;

import java.util.ArrayList;

/**
* @author Matej Ocovsky -- 9/7/2016
*/

public class TrackingActivity extends AppCompatActivity implements SensorEventListener, OnMapReadyCallback {
public static boolean trackStart = false;

private static ImageView image;

private float currentDegree = 0f;

private SensorManager mSensorManager;

public static ArrayList<Target> targetList = new ArrayList<>();

public static GoogleMap mMap;

private static Target targetDislplayed;

public static SharedPreferences mPrefs;




@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tracking);



////////////////////////////////////////////////////////////
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_frag);
//MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map_frag);
mapFragment.getMapAsync(this);


// make textView that will be displaying current user location
MainActivity.textView = new TextView(this);
MainActivity.textView.setTextSize(30);
MainActivity.textView.setTextColor(Color.parseColor("#FFF4FE53"));

RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp.setMargins(150, 150, 0, 0);
MainActivity.textView.setLayoutParams(rlp);



// check whether user coordinates have been modified
if(MainActivity.user.uLatitude == 0 && MainActivity.user.uLongitude == 0) {
// by default it is gonna show this message
MainActivity.textView.setText("Please wait for coordinates");
}



// find layout that we can display the text on
RelativeLayout layout = (RelativeLayout) findViewById(R.id.contentTrackingActivity);

// add textView to the corresponding layout
layout.addView(MainActivity.textView);


image = (ImageView) findViewById(R.id.arrow_iv);

mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_GAME);

mPrefs = getPreferences(MODE_PRIVATE);

startTracking(MainActivity.user.updated);


}


public void startTracking(boolean userUpdated) {

if (userUpdated) {
Target tryTarget = retrieveTarget();
//Target tryTarget = null;
TextView textview = (TextView) findViewById(R.id.textView_notes);

if (tryTarget == null) {

// initialize target that is going to be tracked

Target target = new Target(MainActivity.user.uLongitude, MainActivity.user.uLatitude);
target.tLocation = MainActivity.currentLocation;
saveTarget(target);

resetParking(target);

}
else{
saveTarget(tryTarget);

resetParking(tryTarget);

if(tryTarget.note == null || tryTarget.note == ""){
textview.setText("Click to add notes");
}
else
{
textview.setText(tryTarget.note);
}

}
}
else {
trackStart = false;
}


}

public static Target getTarget(String targetName){
if(targetList.isEmpty())
{
return null;
}
else{
for(Target target : targetList){
if(target.name.equals(targetName)) {
return target;
}
}
}
return null;
}

public void openMap(View view){
Intent intent = new Intent(this, TrackMap.class);
startActivity(intent);
}


@Override
public void onSensorChanged(SensorEvent event) {
//degree between phone y axis and magnetic north
Float azimuth = (float) Math.round(event.values[0]);

//we need target location object
Target target = getTarget("Car");

// get bearing between phone and target
Float bearing = MainActivity.currentLocation.bearingTo(target.tLocation);

//calculate the direction to which the arrow will be poinitng
Float direction = azimuth - bearing;

//arrow that will be rotating
RotateAnimation ra = new RotateAnimation(currentDegree, -direction, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

//one second
ra.setDuration(1000);
ra.setFillAfter(true);
image.startAnimation(ra);
currentDegree = -direction;
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//not needed
}


@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;

targetDislplayed = TrackingActivity.getTarget("Car");

// Add a marker at user location and move the camera
LatLng userLocation = new LatLng(targetDislplayed.tLatitude, targetDislplayed.tLongitude);
mMap.addMarker(new MarkerOptions().position(new LatLng(targetDislplayed.tLatitude, targetDislplayed.tLongitude))
.title("Target"));

mMap.moveCamera(CameraUpdateFactory.newLatLng(userLocation));

// doesnt need permission check because the code in previous itents would allow user to open this map without the permission, might add it just for fun :D
mMap.setMyLocationEnabled(true);



}


public static void saveTarget(Target tempTarget){

//mPrefs = getPreferences(MODE_PRIVATE);

SharedPreferences.Editor prefsEditor = mPrefs.edit();


Gson gson = new Gson();
String json = gson.toJson(tempTarget);
prefsEditor.putString("SavedTarget", json);
prefsEditor.apply();
//mPrefs.edit().putString("SavedTarget",json).apply();

}

public static Target retrieveTarget(){
Gson gson = new Gson();
String json = mPrefs.getString("SavedTarget","");

Target returnedTarget = null;

returnedTarget = gson.fromJson(json, Target.class);

return returnedTarget;
}

@Override
protected void onStart() {
super.onStart();
//startTracking(MainActivity.user.updated);
}

public void resetParking(Target target){
TextView textView = (TextView) findViewById(R.id.textView_notes);
textView.setText("Click to add notes");

if (targetList.isEmpty()) {
targetList.add(target);
MainActivity.targetTracked = target;

trackStart = true;
} else {
Target tempTarget = getTarget("Car");
targetList.remove(tempTarget);

targetList.add(target);
MainActivity.targetTracked = target;
trackStart = true;
}
}

public void resetParkingButtonClicked(View view){



//Toast.makeText(TrackingActivity.this, "Canceled reset action", Toast.LENGTH_SHORT).show();

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to reset the parking location?");
builder.setTitle("Reset parking location");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//clicked ok button
Target target = new Target(MainActivity.user.uLongitude, MainActivity.user.uLatitude);
target.tLocation = MainActivity.currentLocation;
saveTarget(target);
resetParking(target);
mMap.clear();
TrackingActivity.mMap.addMarker(new MarkerOptions().position(new LatLng(target.tLatitude, target.tLongitude))
.title("Target"));
}
});

builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(TrackingActivity.this, "Canceled reset action", Toast.LENGTH_SHORT).show();
dialog.cancel();
}
});

AlertDialog dialog = builder.create();
dialog.show();


}
public void textViewAddNote(View view){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Add note");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Target target = getTarget("Car");
target.note = input.getText().toString();
TextView textview = (TextView) findViewById(R.id.textView_notes);
textview.setText(target.note);
saveTarget(target);
}
});

builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(TrackingActivity.this, "Canceled note action", Toast.LENGTH_SHORT).show();
dialog.cancel();
}
});

AlertDialog dialog = builder.create();
dialog.show();
}


}

My dependencies:

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.matej.locato"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"

// Enabling multidex support.
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
}
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.google.android.gms:play-services:9.2.0'
compile 'com.google.code.gson:gson:2.7'
compile 'com.android.support:multidex:1.0.0'
}


tried to update the proguard-rules.pro but it has no effect, I am still getting the error.

Answer

Since you have enabled minifyEnabled true in gradle-config, proguard can be the issue.

Try adding these lines in your proguard-rules.pro

-renamesourcefileattribute SourceFile
-keepattributes  Signature,SourceFile,LineNumberTable
-keep public class * extends android.app.Application