NullPointerException in metadata-extractor - java

I am using metadata-extractor library, to read exif-data from photos in phone.
https://github.com/drewnoakes/metadata-extractor
I wanna get the GPS and some specific tags from metadata, for example:Latitude & Longtitude, focal length. I write code as below:
...
Metadata metadata = ImageMetadataReader.readMetadata(file);
String metaDataString = "" ;
GpsDirectory gpsDirectory = metadata.getFirstDirectoryOfType(GpsDirectory.class);
metaDataString += "Long: " + String.valueOf(gpsDirectory.getGeoLocation().getLongitude()) + "Lat: " + String.valueOf(gpsDirectory.getGeoLocation().getLatitude());
ExifSubIFDDirectory exifSubIFDDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
metaDataString += "[focal length]" + exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_FOCAL_LENGTH);
...
I received the NullException with code above. Please help me to figure it out. Thanks in advance.
** Add a log **
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException
at com.testing.MetaData.LoadPhoto.doInBackground(LoadPhoto.java:113)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
The NPE error at code line 113 is
metaDataString += "Long: " + String.valueOf(gpsDirectory.getGeoLocation().getLongitude()) + "Lat: " + String.valueOf(gpsDirectory.getGeoLocation().getLatitude());

Cheers guys, you're all right. After debug, I saw some of my photos don't have GPS, and null.
I post the code to control null value as below (this can be also applied for other specific tag)
// Check if metadata contains the specific Directory
if (metadata.containsDirectoryOfType(GpsDirectory.class)) {
GpsDirectory gpsDirectory = metadata.getFirstDirectoryOfType(GpsDirectory.class);
//Check if Directory contains the specific Tag
if(gpsDirectory.containsTag(GpsDirectory.TAG_LATITUDE)&& gpsDirectory.containsTag(GpsDirectory.TAG_LONGITUDE)) {
metaDataString = "[Longtitude]: " + String.valueOf(gpsDirectory.getGeoLocation().getLongitude()) + ", " +
"[Latitude]: " + String.valueOf(gpsDirectory.getGeoLocation().getLatitude()) + ", ";
}
else {
//Show error or notification
}
}
That's it, any concern or better implement, please leave comment.

If your image does not contain GPS data, the returned directory will be null. Be sure to use a null check. Test again with an image that definitely contains GPS data.

Related

ArrayList just recognise the first element

I have an ArrayList that I add some data in a method, when I try to remove a item that isn't the first one I get the following error
07-25 00:39:03.024 28960-28960/murilopereira.brofut E/[HAS CHECK]: 2
07-25 00:39:03.025 28960-28960/murilopereira.brofut E/[CHECK INDEX]: udidjdid
0
84jdkd
1
07-25 00:39:07.787 28960-29062/murilopereira.brofut D/OpenGLRenderer: endAllActiveAnimators on 0x7f6b86bc00 (MenuPopupWindow$MenuDropDownListView) with handle 0x7f6b8e6940
07-25 00:39:08.054 28960-28960/murilopereira.brofut E/[HAS CHECK]: 1
07-25 00:39:08.055 28960-28960/murilopereira.brofut E/[CHECK INDEX]: 84jdkd
0
07-25 00:39:08.055 28960-28960/murilopereira.brofut D/AndroidRuntime: Shutting down VM
07-25 00:39:08.060 28960-28960/murilopereira.brofut E/AndroidRuntime: FATAL EXCEPTION: main
Process: murilopereira.brofut, PID: 28960
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at murilopereira.brofut.Times.deleteTeam(Times.java:203)
at murilopereira.brofut.Times.access$100(Times.java:29)
at murilopereira.brofut.Times$2.onClick(Times.java:109)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6592)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
But if I check the size of the array, that indicates a number uppon one
My code to delete:
public static ArrayList<String> hasKeys = new ArrayList<>();
...
private void deleteTeam(int indexRemove){
Log.e("[HAS CHECK]", hasKeys.size() + "");
for(int i = 0; i < hasKeys.size(); i++){
Log.e("[CHECK INDEX]", hasKeys.get(i));
Log.e("[CHECK INDEX]", i + "");
}
// Log.e("[CHECK INDEX]", hasKeys.indexOf(m_orders.get(indexRemove).getTeamName()) + "");
hasKeys.remove(hasKeys.indexOf(m_orders.get(indexRemove).getTeamName()) - 1);
Menu.teams.remove(m_orders.get(indexRemove).getTeamName());
m_orders.remove(indexRemove);
m_adapter.removeItem(indexRemove);
m_adapter.notifyDataSetChanged();
}
I'm using the following code to add items to it
m_orders = new ArrayList<Teams>();
Teams o1 = new Teams();
hasKeys.add(teamName.getText().toString());
Log.e("[HAS CHECK]", hasKeys.size() + "");
o1.setTeamName(teamName.getText().toString());
o1.setTeamPlayers(playerOne.getText().toString() + ", " + playerTwo.getText().toString() + ", " + playerThree.getText().toString() + ", " + playerFour.getText().toString() + ", " + playerFive.getText().toString());
Menu.teams.put(o1.getTeamName(), o1.getTeamPlayers());
m_orders.add(o1);
This is happening because your item is always added at index 0. The size of array list is 1 every time from your add items. I don't know the exact flow of your code. But it's seems like if you are calling below statement every time:
m_orders = new ArrayList<Teams>();
This is instantiating your array list.

Cannot parse a String into Float in my app [duplicate]

This question already has an answer here:
java.lang.NumberFormatException: Invalid float: "x" in android
(1 answer)
Closed 5 years ago.
At first I am new in android development. I tried to make this small app where I wanted to take inputs from the users and show them to a (default)list view. When I put values in all the fields it works fine except when I keep the CGPA field empty it stopped. Unfortunately, MyApp is stopped
Here is the OnClickListener login button.
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setData();
}
});
Here is the lines of setData() method where i guess the problem has occurred.
My question is "Is it a right approach to parse data?"
Float cgpa = Float.parseFloat(editTextCgpa.getText().toString());
if(cgpa<=4.00 && cgpa > 0.00 ){
student.setCgpa(cgpa);
}
else{
error = true;
editTextCgpa.setError("CGPA must be within 4 in scale");
}
Android Monitor:
Here is the error message that i found in android monitor.
11-25 13:06:18.917 7896-7896/com.ariful.lict.lictpractice E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NumberFormatException: Invalid float: ""
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseFloat(StringToReal.java:289)
at java.lang.Float.parseFloat(Float.java:300)
at com.ariful.lict.lictpractice.MainActivity.setData(MainActivity.java:55)
at com.ariful.lict.lictpractice.MainActivity$1.onClick(MainActivity.java:45)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
here does the convertion of the String to Float is causing the error ??
Is there anyone who can help me?
You are passing an empty string to be parsed...
Just change your code to check for null/empty String.
if(!editTextCgpa.getText().toString().isEmpty()){
Float cgpa = Float.parseFloat(editTextCgpa.getText().toString());
if(cgpa<=4.00 && cgpa > 0.00 ){
student.setCgpa(cgpa);
}
else{
error = true;
editTextCgpa.setError("CGPA must be within 4 in scale");
}
}

Remove extra dots in float value before a separater " , " occurs using java

I am generating a statistical calculator application.
So I want to format input from edittext like this
i/p = 3.5.6, 6.5 to 3.5 , 6.5
Using " , " (comma) as separator so splitting the input string to float array when a " , " occurs.
I want to ignore 3.5[.6] and generate array like this
s[1] = 3.5 , s[2] = 6.5
While calculating mean application crashes due to extra " . " dots.
s = it.getText().toString(); //"it" is edittext
s=s.replaceAll( ",+" , "," );
String[] strarray =s.split(",");
float[] farray = new float[strarray.length];
for(int i = 0; i < strarray.length; i++)
{
farray[i] = Float.parseFloat(strarray[i]);
}
--DEBUG LOGCAT--
W/dalvikvm(3051): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
FATAL EXCEPTION: main
java.lang.NumberFormatException: Invalid float: "6.7."
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseFloat(StringToReal.java:310)
at java.lang.Float.parseFloat(Float.java:300)
at com.cal.mc2.Mean$1.onClick(Mean.java:67)
at android.view.View.performClick(View.java:4204)
at android.view.View$PerformClick.run(View.java:17355)
at android.os.Handler.handleCallback(Handler.java:725)`
`at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Force finishing activity com.cal.mc2/.Mean
How about this simple function (IdeOne link here: https://ideone.com/utKPjP):
public static float myParseFloat(String str) {
int firstDot = str.indexOf('.');
if (firstDot != -1) {
int secondDot = str.indexOf('.', firstDot+1);
return Float.parseFloat(secondDot == -1 ? str : str.substring(0,secondDot));
}
return Float.parseFloat(str);
}
Then you just replace this statement in your code:
farray[i] = Float.parseFloat(strarray[i]);
with:
farray[i] = myParseFloat(strarray[i]);
You can use regex like this :
public static void main(String[] args) {
String s = "3.5.6, 6.5";
s = s.replaceAll("(?<=\\d\\.\\d)\\.\\d", "");// positive look behind. Only replace `.[digit]` if it is preceeded by [digit][.][digit]
System.out.println(s);
String[] arr = s.split(",");
System.out.println(Arrays.toString(arr));
}
O/P :
3.5, 6.5 --> value of s after replacement
[3.5, 6.5] --> array contents

Strange runtime exception on Android 4.4.4

I've got this strange stack trace from Flurry Analytics and I have no idea where it comes from. All the classes are from android system and not a single line that tells me where it comes from.
This error happened 3 times on a same device with android 4.4.4
Any ideas? Thanks.
java.lang.RuntimeException
android.app.ActivityThread.performResumeActivity(ActivityThread.java:2836)
android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2865)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2291)
android.app.ActivityThread.access$800(ActivityThread.java:144)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
android.os.Handler.dispatchMessage(Handler.java:102)
android.os.Looper.loop(Looper.java:212)
android.app.ActivityThread.main(ActivityThread.java:5135)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:515)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
dalvik.system.NativeStart.main(Native Method)
Caused by: android.app.ActivityThread.deliverResults(ActivityThread.java:3455)
android.app.ActivityThread.performResumeActivity(ActivityThread.java:2823)
android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2865)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2291)
android.app.ActivityThread.access$800(ActivityThread.java:144)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
android.os.Handler.dispatchMessage(Handler.java:102)
android.os.Looper.loop(Looper.java:212)
android.app.ActivityThread.main(ActivityThread.java:5135)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:515)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
dalvik.system.NativeStart.main(Native Method)
Part of the problem here seems to be that Flurry error reporting is leaving out important information.
Anyhow, this is where I think the exception is coming from:
private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
final int N = results.size();
for (int i=0; i<N; i++) {
ResultInfo ri = results.get(i);
try {
if (ri.mData != null) {
ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
}
if (DEBUG_RESULTS) Slog.v(TAG,
"Delivering result to activity " + r + " : " + ri);
r.activity.dispatchActivityResult(ri.mResultWho,
ri.mRequestCode, ri.mResultCode, ri.mData);
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Failure delivering result " + ri + " to activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
}
(This code isn't from Android 4.4.4, but this particular method is identical in the versions I looked at ...)
It would seem that deliverResults is catching some exception it got further up the stack, and wrapping / resthoring it as a RuntimeException. At the point that the exception is constructed, it has a message, and cause. Whatever is generating the stacktrace has removed that information, and that is going to make diagnosis hard.

Android - java.lang.ArrayIndexOutOfBoundsException

I'm new to Java, but I have done some PSP coding in C before. This seems to be quite different.
Below is the stack trace for what I'm seeing:
java.lang.RuntimeException: An error occured while executing doInBackground()
enter code hereenter code here`at android.os.AsyncTask$3.done(AsyncTask.java:299)
enter code here`at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.adev.abmp3.ViewSongDialog$FindLyrics.doInBackground(ViewSongDialog.java:173)
at com.adev.abmp3.ViewSongDialog$FindLyrics.doInBackground(ViewSongDialog.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
And here is the patch of code:
#Override
protected Void doInBackground(Void... arg0) {
String searchQuery = title.replaceAll("[^ \\w]", "");
searchQuery = searchQuery.replace(" ", "+");
String searchResult = httpRun("http://search.azlyrics.com/search.php?q="+searchQuery).toString();
System.out.println("http://search.azlyrics.com/search.php?q="+searchQuery);
if(!searchResult.contains("Sorry, no results") && !searchResult.equals("")) {
String link = searchResult.split("<table width=100%>")[1];
link = link.substring(link.indexOf("<a href=\""), link.indexOf("\" rel"));
link = link.replace("<a href=\"", "");
String lR = httpRun(link).toString();
if(lR != "" && lR.contains("<!-- start of lyrics -->")) {
lR = lR.substring(lR.indexOf("<!-- start of lyrics -->"), lR.indexOf("<!-- end of lyrics -->"));
lR = lR.replace("<!-- start of lyrics -->", "");
lyrics = lR;
} else {
fail = 1;
lyrics = "Couldn't find lyrics";
}
} else {
fail = 1;
lyrics = "Couldn't find lyrics";
}
return null;
}
I've done some research, and have read that you can't print to the screen within doInBackground - but I'm not sure where to go from here. Any help would be appreciated.
EDIT: java.lang.StringIndexOutOfBoundsException
in java.lang.String.startEndAndLength
Heres the new stack:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.StringIndexOutOfBoundsException: length=7338; regionStart=537; regionLength=-538
at java.lang.String.startEndAndLength(String.java:593)
at java.lang.String.substring(String.java:1474)
at com.adev.abmp3.ViewSongDialog$FindLyrics.doInBackground(ViewSongDialog.java:174)
at com.adev.abmp3.ViewSongDialog$FindLyrics.doInBackground(ViewSongDialog.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
Your split call is returning an array of size 1, but you're trying to get the 2nd item in it (with the [1]). You have to account for the possibility that your split string isn't in the input.
String link = searchResult.split("<table width=100%>")[1];
The error is occuring there. Indices start at 0, and your split is returning an array of size 1, so element 1 is out of bounds, and hence the exception is thrown. If you change it to String link = searchResult.split("<table width=100%>")[0]; the exception will no longer be thrown.

Categories

Resources