I'm trying to implement some simple caching into my application and I'm having some issues.
Basically my code scrapes a webpage, gets some regex matches and puts them into an ArrayList. This takes a while to do (a few seconds, but this happens frequently) so I'm trying to implement a simple caching system which checks when the cache file was modified, if this is older than a week, refresh cache.
My problem lies with storing the ArrayList, can anyone help with this?
I originally have (which works)
private List<String> getVideoIDS(final String url2) {
if (android.os.Environment.getDataDirectory().equals(android.os.Environment.MEDIA_MOUNTED)) //android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getDataDirectory(),"PL" + url.getQuery());
else
cacheDir=mContext.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
File f = new File(cacheDir, "PL"+url.getQuery());
if (f.lastModified() > 604800000 || f.exists() == false) {
String expr = "(?<=v=)[a-zA-Z0-9-_]{11}(?=&)|(?<=[0-9]/)[^&\n]{11}|(?<=v=)[^&\n]{11}";
int count = 0;
Pattern patt = Pattern.compile(expr,
Pattern.DOTALL | Pattern.UNIX_LINES | Pattern.CASE_INSENSITIVE);
try {
url = new URL(url2);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
m = patt.matcher(getURLContent(url));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (m.find()) {
if ("default.jpg".equals(m.group(0)) || "videos?view".equals(m.group(0))) {
//Do nothing
} else {
allMatches.add(m.group(0));
count++;
Log.i("", m.group(0));
}
}
//Remove duplicates
List<String> noDupes = new ArrayList<String>();
Iterator iterator = allMatches.iterator();
while (iterator.hasNext())
{
String o = (String) iterator.next();
if(!noDupes.contains(o)) noDupes.add(o);
}
allMatches = noDupes;
return allMatches; }
Now what I'm trying to modify this to be is this (in theory, as it currently doesn't work)
private List<String> getVideoIDS(final String url2) {
if (android.os.Environment.getDataDirectory().equals(android.os.Environment.MEDIA_MOUNTED)) //android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getDataDirectory(),"PL" + url.getQuery());
else
cacheDir=mContext.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
File f = new File(cacheDir, "PL"+url.getQuery());
if (f.lastModified() > 604800000 || f.exists() == false) {
String expr = "(?<=v=)[a-zA-Z0-9-_]{11}(?=&)|(?<=[0-9]/)[^&\n]{11}|(?<=v=)[^&\n]{11}";
int count = 0;
Pattern patt = Pattern.compile(expr,
Pattern.DOTALL | Pattern.UNIX_LINES | Pattern.CASE_INSENSITIVE);
try {
url = new URL(url2);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
m = patt.matcher(getURLContent(url));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (m.find()) {
if ("default.jpg".equals(m.group(0)) || "videos?view".equals(m.group(0))) {
//Do nothing
} else {
allMatches.add(m.group(0));
count++;
Log.i("", m.group(0));
}
}
//Remove duplicates
List<String> noDupes = new ArrayList<String>();
Iterator iterator = allMatches.iterator();
while (iterator.hasNext())
{
String o = (String) iterator.next();
if(!noDupes.contains(o)) noDupes.add(o);
}
allMatches = noDupes;
ObjectOutputStream save = null;
FileOutputStream saveFile = null;
try {
saveFile = new FileOutputStream(cacheDir + "PL"+url.getQuery());
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// Create an ObjectOutputStream to put objects into save file.
try {
save = new ObjectOutputStream(saveFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
save.writeObject(allMatches);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
save.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return allMatches;}
else {
try{
// Open file to read from, named SavedObjects.sav.
FileInputStream saveFile = new FileInputStream(cacheDir + "PL"+url.getQuery());
// Create an ObjectInputStream to get objects from save file.
final ObjectInputStream save = new ObjectInputStream(saveFile);
// Now we do the restore.
// readObject() returns a generic Object, we cast those back
// into their original class type.
// For primitive types, use the corresponding reference class.
allMatches = (ArrayList) save.readObject();
// Close the file.
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// This also closes saveFile.
}
} return allMatches;
}
Note: I'm trying to save multiple files as this method is called for various different categories. That should be handled with calling the file a different filename based on whats open. I think I have implemented this correctly.
Stacktrace is as follows
04-03 17:41:20.846: E/AndroidRuntime(2438): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.test/com.test.test.VideoGrid}: java.lang.NullPointerException
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2194)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2229)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.access$600(ActivityThread.java:139)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.os.Handler.dispatchMessage(Handler.java:99)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.os.Looper.loop(Looper.java:154)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.main(ActivityThread.java:4944)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.lang.reflect.Method.invokeNative(Native Method)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.lang.reflect.Method.invoke(Method.java:511)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-03 17:41:20.846: E/AndroidRuntime(2438): at dalvik.system.NativeStart.main(Native Method)
04-03 17:41:20.846: E/AndroidRuntime(2438): Caused by: java.lang.NullPointerException
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.io.DataOutputStream.writeShort(DataOutputStream.java:192)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.io.ObjectOutputStream.writeStreamHeader(ObjectOutputStream.java:1815)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:279)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.test.test.VideoGrid.getVideoIDS(VideoGrid.java:204)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.test.test.VideoGrid.onCreate(VideoGrid.java:74)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.Activity.performCreate(Activity.java:4524)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150)
This
com.test.test.VideoGrid.getVideoIDS(VideoGrid.java:204)
Points to
save = new ObjectOutputStream(saveFile);
I have
android.permission.WRITE_EXTERNAL_STORAGE
In my manifest
I have tried changing the filename to something static (1) instead of my url.getQuery incase that was the problem - doesn't change anything, exact same problem.
I feel I'm making a fundamental error here. Can anyone see where I'm going wrong with saving/reading the ArrayList?
It looks like your save file wasn't found; but its hard to tell since your code is currently swallowing all of the exceptions. instead of :
try {
saveFile = new FileOutputStream(cacheDir + "PL"+url.getQuery())
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Try logging your exceptions instead, since e.printStackTrace(); doesn't do anything by default on android.
catch(FileNotFoundException e1) {
Log.e(getClass().getName(), "File not found:" + cacheDir + "PL" + url.getQuery()", e1);
}
Anyway, that's my theory - your file path is pointing to somewhere that can't be written to for whatever reason (the docs have some possible explanations); saveFile then comes out of the exception as null, and then you pass the null parameter into the outputStream constructor
Related
My app crashes every time I go to send the data gathered by the sensor. The error I am given is as follows:
06-20 14:50:00.784 22983-22983/com.example.adam.proj2 E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.adam.proj2.SensorActivity.onClick(SensorActivity.java:124)
at android.view.View.performClick(View.java:3549)
at android.view.View$PerformClick.run(View.java:14393)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4944)
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:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Here is the code for gathering the sensor data:
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
ArrayList<Float> enrolAcc = new ArrayList<>();
ArrayList<Float> authAcc = new ArrayList<>();
TextView textEnrol = (TextView) findViewById(R.id.textView);
if (choice == 1) {
mPreviousAcc = mCurrentAcc;
mCurrentAcc = (float) Math.sqrt((double) (x * x));
float delta = mCurrentAcc - mPreviousAcc;
mDiffAcc = mDiffAcc * 0.9f + delta;
if (enrolAcc.size() < 100) {
enrolAcc.add(x);
} else {
enrolAcc.remove(0);
enrolAcc.add(x);
}
walkData = enrolAcc.toString();
textEnrol.setText(walkData);
}
Here is the code for writing to the file (this happens onClick of a button):
public void onClick(View v) {
switch (v.getId()) {
case R.id.enrolBtn:
choice = 1;
Toast.makeText(this, "Enrolment Mode Selected", Toast.LENGTH_SHORT).show();
break;
case R.id.authBtn:
choice = 2;
Toast.makeText(this, "Authentication Service Starting", Toast.LENGTH_SHORT).show();
break;
case R.id.sendBtn:
choice = 3;
String baseDir = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "Walk Data.csv";
String filePath = baseDir + File.separator + fileName;
File f = new File(filePath);
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
out.write(walkData.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
android.net.Uri u1 = Uri.fromFile(f);
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, u1);
sendIntent.setType("text/html");
startActivity(sendIntent);
break;
}
}
From what I can see the exception is generated by the out.write method?
The array list holding the sensor values is stored in the walkData string so that the string can be then written in the csv file stored on the external device storage. I would like the data to be in CSV format.
I am stumped and cannot figure out how to prevent this, any help would be much appreciated.
You get the error because you are trying to write to a READ ONLY file.
The line out = new FileOutputStream(f) throws an exception:
java.io.FileNotFoundException: /storage/sdcard/Walk Data.csv: open failed: EROFS (Read-only file system), but you actually ignore it, so out = NULL and then you get the other exception.
Move your file to a place where you can write to it -
String fileName = "Walk Data.csv";
String baseDir = getFilesDir() + "/" + fileName;
File f = new File(baseDir);
Look at the code:
try {
out = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
out.write(walkData.getBytes());
The exception is thrown at the last line. So, what could possibly be wrong at that line?
out could be null. out will be null if the file is not found, since you catch that exception and pretend nothing wrong happened at the line before, leaving out as null. You shouldn't try to use outif you just failed to initialize it. The try block should ensclose all the lines using out, and not just the line initializing it.
walkDatacould also be null. But since we don't know where it comes from, we can't say. Use your debugger to know which is null. And whatever the answer is, fix your exception handling code. It should look like
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
out.write(walkData.getBytes());
android.net.Uri u1 = Uri.fromFile(f);
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, u1);
sendIntent.setType("text/html");
startActivity(sendIntent);
} catch (IOException e) {
// TODO signal the error to the user. Printing a stack trace is not enough
}
finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
// TODO signal the error to the user. Printing a stack trace is not enough
}
}
}
I have a problem when I try to connect my physical device to my server using sockets. On the server side it does not seem to accept any connection while on the client side the socket times out. Any ideas why this is happening?
I provide my code below
Server Code:
public void run()
{
// TODO Auto-generated method stub
try{
gamePending = false;
pid = 0;
while(pid < 2){
System.out.println("Hello from run loop on game");
Socket tempSocket = server.accept();
System.out.println("Client connected at " + tempSocket.getLocalPort());
PrintWriter tempWriter = new PrintWriter(new BufferedWriter (new OutputStreamWriter(tempSocket.getOutputStream())),true);
tempWriter.println("" + pid);
players[pid] = new Client(tempSocket, pid, this);
players[pid].start();
gamePending = true;
if(pid == 0){sendMsg(pid, "waiting for other player");}
pid++;
}
}
catch(Exception e){
System.out.println("There has been an Error. Game will be Terminated.");
}
//Start new game for the next two players...
new Game();
}
Client Side:
public void run() {
// Connects to the Server....
try {
socket = new Socket("192.168.1.116", 9090);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
out = new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
11-16 23:32:11.016: W/System.err(24213): java.net.ConnectException: failed to connect to /192.168.1.116 (port 9090): connect failed: ETIMEDOUT (Connection timed out)
11-16 23:32:11.016: W/System.err(24213): at libcore.io.IoBridge.connect(IoBridge.java:114)
11-16 23:32:11.016: W/System.err(24213): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-16 23:32:11.026: W/System.err(24213): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
11-16 23:32:11.026: W/System.err(24213): at java.net.Socket.connect(Socket.java:842)
11-16 23:32:11.026: W/System.err(24213): at vatos.locos.spheroknockout.Connection.run(Connection.java:22)
11-16 23:32:11.026: W/System.err(24213): at java.lang.Thread.run(Thread.java:841)
11-16 23:32:11.026: W/System.err(24213): Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
}
I can't be sure (because it does not appear in your code) but I think the server is not hosing on the same port (9090). That may be the main problem, but the server or client may also be blocked by a firewall (even if they run on the same machine).
Hi there I have 2 classes in order to push a file into an android device.
My Server CLass:
public class FileServer {
public static void main (String [] args ) throws IOException {
// create socket
ServerSocket servsock = new ServerSocket(13267);
while (true) {
System.out.println("Waiting...");
Socket sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// sendfile
File myFile = new File ("C:\\Users\\Petrica\\Desktop\\zzz.txt");
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
sock.close();
}
}
}
And my Client Class:
public class TCPClient extends AsyncTask{
#Override
protected Object doInBackground(Object... params) {
int filesize=6022386; // filesize temporary hardcoded
long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
// localhost for testing
Socket sock = null;
try {
sock = new Socket("127.0.0.1",13267);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Connecting...");
// receive file
try {
byte [] mybytearray = new byte [filesize];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/zzz.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
// thanks to A. Cádiz for the bug fix
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
sock.close();
// TODO Auto-generated method stub
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
I get an error
09-09 15:52:39.261: E/AndroidRuntime(802): FATAL EXCEPTION: AsyncTask #1
09-09 15:52:39.261: E/AndroidRuntime(802): java.lang.RuntimeException: An error occured while executing doInBackground()
09-09 15:52:39.261: E/AndroidRuntime(802): at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-09 15:52:39.261: E/AndroidRuntime(802): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.lang.Thread.run(Thread.java:841)
09-09 15:52:39.261: E/AndroidRuntime(802): Caused by: java.lang.NullPointerException
09-09 15:52:39.261: E/AndroidRuntime(802): at com.aaaaaa.TCPClient.doInBackground(TCPClient.java:33)
09-09 15:52:39.261: E/AndroidRuntime(802): at com.aaaaaa.TCPClient.doInBackground(TCPClient.java:1)
09-09 15:52:39.261: E/AndroidRuntime(802): at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-09 15:52:39.261: E/AndroidRuntime(802): ... 4 more
MainActivity:
public class MainActivity extends Activity {
TCPClient tcpc;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.send_button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
tcpc.execute();
}
});
}
}
Does anyone have an idea what should I do ??? In the future i would like to send 2 files :D .Thanks in advice .
You're really expected to be able to sort out your own NullPointerExceptions: at least I expect it, but when you get past that, your copy code is wrong. You are presently ignoring the count returned by read() and assuming it fills the buffer. It isn't guaranteed to do that. See the Javadoc.
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Use this at both ends, with any buffer size > 0, typically 8192.
I don't think your Socket is connecting, but its hard to tell. IN your log output, it says NullPointerException caused by doInBackground() line 33. You should check line 33 in your editor, and better yet, show us in your post which line is 33. I kind of have a feeling that you call Socket sock = null;, then you try and instantiate a new Socket in a try block, but that fails, so sock still == null, then you call a method on sock, and boom, NPE.
If you are running the Server on a computer, and the AsyncTask on an Android device, you won't be able to try and connect to localhost (127.0.0.1). You should instead try to connect to the internal network ip of your computer (something like 192.168.1.XXX), assuming both devices are on WiFi. If you are running an android emulator, then 127.0.0.1 refers back to the emulated device, and all emulator sessions run on an emulated router that you will have to configure for port forwarding before you can refer to the development machine, see here-->http://developer.android.com/tools/devices/emulator.html#emulatornetworking
As Andras Balazs Lajtha says, it looks like TCPClient isn't ever initialized/created during onCreate(), it is only declared. Since your logcat output shows errors from TCPClient though, I assume you have that code actually running.
In general, when you post a log output that refers to problems with a specific line of code, you should start there, and when you post, tell us or show us which line that is. And of course, if line 33 isn't related to a null Socket object, then I haven't been much help at all :)
I try to use jaudiotagger like this
but it crashes
Main app.java :
import java.io.File;
import java.io.IOException;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.AudioHeader;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.CannotWriteException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.tag.FieldDataInvalidException;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.KeyNotFoundException;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagException;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class App extends Activity {
/** Called when the activity is first created. */
private TextView txt1;
private TextView txt2;
private TextView txt3;
private TextView txt4;
private TextView txt5;
private TextView txt6;
private TextView txt7;
private TextView txt8;
private TextView txt9;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// try
//{
File mp3 = new File("/sdcard/test.mp3");
AudioFile f = null;
try {
f = AudioFileIO.read(mp3);
} catch (CannotReadException e) {
// TODO Auto-generated catch block
txt1.setText(e.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
txt1.setText(e.toString());
} catch (TagException e) {
// TODO Auto-generated catch block
txt1.setText(e.toString());
} catch (ReadOnlyFileException e) {
// TODO Auto-generated catch block
txt1.setText(e.toString());
} catch (InvalidAudioFrameException e) {
// TODO Auto-generated catch block
txt1.setText(e.toString());
}
Tag tag = f.getTag();
AudioHeader AudioHeader = f.getAudioHeader();
txt1.setText(tag.getFirst(FieldKey.ARTIST));
txt2.setText(tag.getFirst(FieldKey.ALBUM));
txt3.setText(tag.getFirst(FieldKey.TITLE));
txt4.setText(tag.getFirst(FieldKey.COMMENT));
txt5.setText(tag.getFirst(FieldKey.YEAR));
txt6.setText(tag.getFirst(FieldKey.TRACK));
txt7.setText(tag.getFirst(FieldKey.DISC_NO));
txt8.setText(tag.getFirst(FieldKey.COMPOSER));
txt9.setText(tag.getFirst(FieldKey.ARTIST_SORT));
try {
tag.setField(FieldKey.ARTIST,"Kings of Leon");
} catch (KeyNotFoundException e) {
// TODO Auto-generated catch block
txt1.setText(e.toString());
} catch (FieldDataInvalidException e) {
// TODO Auto-generated catch block
txt1.setText(e.toString());
}
try {
AudioFileIO.write(f);
} catch (CannotWriteException e) {
txt1.setText(e.toString());
}
/* }
catch(Exception x)
{
txt1.setText(x.toString());
}
*/
}
}
Logcat :
02-22 21:12:22.546: E/AndroidRuntime(19738): FATAL EXCEPTION: main
02-22 21:12:22.546: E/AndroidRuntime(19738):
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.mp3.tag.editor.alexander.fuchs/com.mp3.tag.editor.alexander.fuchs.App}:
java.lang.NullPointerException 02-22 21:12:22.546:
E/AndroidRuntime(19738): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
02-22 21:12:22.546: E/AndroidRuntime(19738): at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
02-22 21:12:22.546: E/AndroidRuntime(19738): at
android.app.ActivityThread.access$1500(ActivityThread.java:117) 02-22
21:12:22.546: E/AndroidRuntime(19738): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
02-22 21:12:22.546: E/AndroidRuntime(19738): at
android.os.Handler.dispatchMessage(Handler.java:99) 02-22
21:12:22.546: E/AndroidRuntime(19738): at
android.os.Looper.loop(Looper.java:130) 02-22 21:12:22.546:
E/AndroidRuntime(19738): at
android.app.ActivityThread.main(ActivityThread.java:3691) 02-22
21:12:22.546: E/AndroidRuntime(19738): at
java.lang.reflect.Method.invokeNative(Native Method) 02-22
21:12:22.546: E/AndroidRuntime(19738): at
java.lang.reflect.Method.invoke(Method.java:507) 02-22 21:12:22.546:
E/AndroidRuntime(19738): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
02-22 21:12:22.546: E/AndroidRuntime(19738): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665) 02-22
21:12:22.546: E/AndroidRuntime(19738): at
dalvik.system.NativeStart.main(Native Method) 02-22 21:12:22.546:
E/AndroidRuntime(19738): Caused by: java.lang.NullPointerException
02-22 21:12:22.546: E/AndroidRuntime(19738): at
com.mp3.tag.editor.alexander.fuchs.App.onCreate(App.java:72) 02-22
21:12:22.546: E/AndroidRuntime(19738): at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-22 21:12:22.546: E/AndroidRuntime(19738): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
02-22 21:12:22.546: E/AndroidRuntime(19738): ... 11 more
There two blockers
to using jaudiotagger on Android:
1 - javax.swing
2 - javax.imageio
these two Classes isn't supported by android and jaudiotagger uses them
To solve your problem:
Fix the sources so they don't depend no more on these two JAVAX Classes
Seems like this line causes the crash, because f is null:
Tag tag = f.getTag();
You shouldn't ignore the exception in the way you do, as if you got an exception, you just print something and continue with a bad state (in this case - f is still null)
You still need to check that f != null before you get the tag.
Tag r_tag = null;
File testFile = new File(filename);
MP3File f = null;
try {
f = (MP3File)AudioFileIO.read(testFile);
} catch (CannotReadException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TagException e) {
e.printStackTrace();
} catch (ReadOnlyFileException e) {
e.printStackTrace();
} catch (InvalidAudioFrameException e) {
e.printStackTrace();
}
if(f != null) {
f.getTagOrCreateAndSetDefault();
r_tag = f.getID3v2TagAsv24();
}
return r_tag;
I'm loading a file that has been saved by another class via the FileOutputstream method. Anyway, I want to load that file in another class, but it either gives me syntax errors or crashes my App.
The only tutorials I could find where they saved and loaded the file in the same class, but I want to load it up in another class and couldn't find how to solve the problem of loading into another class.
Thanks
My Code:
public class LogIn extends Activity implements OnClickListener {
EditText eTuser;
EditText eTpassword;
CheckBox StaySignedIn;
Button bSubmit;
String user;
String pass;
FileOutputStream fos;
FileInputStream fis = null;
String FILENAME = "userandpass";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
eTuser = (EditText) findViewById(R.id.eTuser);
eTpassword = (EditText) findViewById(R.id.eTpassword);
StaySignedIn = (CheckBox) findViewById(R.id.Cbstay);
bSubmit = (Button) findViewById(R.id.bLogIn);
bSubmit.setOnClickListener(this);
File file = getBaseContext().getFileStreamPath(FILENAME);
if (file.exists()) {
Intent i = new Intent(LogIn.this, ChatService.class);
startActivity(i);
}
// if if file exist close bracket
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // end of catch bracket
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // end of catch
} // create ends here
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bLogIn:
String user = eTuser.getText().toString();
String pass = eTpassword.getText().toString();
Bundle userandpass = new Bundle();
userandpass.putString("user", user);
userandpass.putString("pass", pass);
Intent login = new Intent(LogIn.this, logincheck.class);
login.putExtra("pass", user);
login.putExtra("user", pass);
startActivity(login);
if (StaySignedIn.isChecked())
;
String userstaysignedin = eTuser.getText().toString();
String passstaysignedin = eTpassword.getText().toString();
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(userstaysignedin.getBytes());
fos.write(passstaysignedin.getBytes());
fos.close();
} catch (IOException e) {
// end of try bracket, before the Catch IOExceptions e.
e.printStackTrace();
} // end of catch bracket
} // switch and case ends here
}// Click ends here
}// main class ends here
Class B( Class that loads the data.)
public class ChatService extends Activity {
String collected = null;
FileInputStream fis = null;
String FILENAME;
TextView userandpass;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.chatservice);
userandpass = (TextView) findViewById(R.id.textView1);
try {
fis = openFileInput(FILENAME);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] dataArray = null;
try {
dataArray = new byte[fis.available()];
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
while (fis.read(dataArray) != -1)
;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
{
// while statement
}
userandpass.setText(collected);
}// create ends here
}// class ends here
LogCat:
03-03 21:03:34.725: E/AndroidRuntime(279): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gta5news.bananaphone/com.gta5news.bananaphone.ChatService}: java.lang.NullPointerException
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.os.Handler.dispatchMessage(Handler.java:99)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.os.Looper.loop(Looper.java:123)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ActivityThread.main(ActivityThread.java:4627)
03-03 21:03:34.725: E/AndroidRuntime(279): at java.lang.reflect.Method.invokeNative(Native Method)
03-03 21:03:34.725: E/AndroidRuntime(279): at java.lang.reflect.Method.invoke(Method.java:521)
03-03 21:03:34.725: E/AndroidRuntime(279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-03 21:03:34.725: E/AndroidRuntime(279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-03 21:03:34.725: E/AndroidRuntime(279): at dalvik.system.NativeStart.main(Native Method)
03-03 21:03:34.725: E/AndroidRuntime(279): Caused by: java.lang.NullPointerException
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ContextImpl.makeFilename(ContextImpl.java:1599)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ContextImpl.openFileInput(ContextImpl.java:399)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.content.ContextWrapper.openFileInput(ContextWrapper.java:152)
03-03 21:03:34.725: E/AndroidRuntime(279): at com.gta5news.bananaphone.ChatService.onCreate(ChatService.java:25)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-03 21:03:34.725: E/AndroidRuntime(279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-03 21:03:34.725: E/AndroidRuntime(279): ... 11 more
The FILENAME string in the ChatService class is null. So you get a NullPointerException when you try to load a file using fis = openFileInput(FILENAME).
Also, your read loop throws away the data:
while (fis.read(dataArray) != -1)
;
It needs to collect the data and set the value of your collected String.
The stack trace tells you everything you need to know.
The error is a NullPointerException (meaning that you pass a null reference to a method expecting a non null reference, or that you call a method on a null reference).
The error occurs inside some android code (ContextWrapper.openFileInput()), which is called by your ChatService.onCreate() method, on line 25.
The line 25 is the following line:
fis = openFileInput(FILENAME);
So the error is clear: FILENAME is null. You haven't initialized it before this method is called.
I'm not sure about your program flow and if your two classes are running in the same thread, but it looks like you have a program flow issue. You are trying to open the file and getting a NullPointerException. Make sure the file is created and you have the correct reference to it before attempting to read.
If they are running in separate threads then you might try something like this:
try {
int waitTries=1;
fis = openFileInput(FILENAME);
while(fis.available()<EXPECTEDSIZE && waitTries++<10)
Tread.sleep(50);
}
If you know how large the file should be (EXPECTEDSIZE is some constant you will set), then this may be what you are looking for.