Restoring data using AsyncTask - java

I have a saving method that runs during onPause():
String save = numberValue.getText().toString();
FileInputStream fos;
try {
fos = openFileOutput(FILENAME,Context.MODE_PRIVATE);
fos.write(save.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
Toast.makeText(getBaseContext(), "Save has run", Toast.LENGTH_SHORT).show();
}
and I try to read this file by calling
new Loader().execute(FILENAME);
and my Loader class looks like this:
public class Loader extends AsyncTask<String, Integer, String> {
protected void onPostExecute(String result) {
textview.setText(result);
}
#Override
protected String doInBackground(String... params) {
FileInputStream fis;
String loaded = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte[fis.available()];
while (fis.read(dataArray) != -1) {
loaded = new String(dataArray);
}
fis.close();
textview.setText(loaded);
return loaded;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return loaded;
}
}
And I have no idea as to why the textview does not get set as the bytes from FILENAME. The idea is that the textview is an increasing number, and this number gets saved when the activity is closed and gets restored to the textview when the activity starts up again.
It does start, I know that because after a few minutes, Watch Dog tells me that a background service from this app is consuming about 50% of CPU. I did check /data/data//files and the file that I write to is there with the correct value.

You probably need to call your Loader from onResume() for this to work.

Why not just save the state you need by using the onSavedInstanceState() method? Writing stuff out to the fileSystem on the onPause method is going to making switching out of your application really slow. From the Activity Documentation regarding the onPause method:
Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.
Also, from the android documentation:
In situations where the system needs more memory it may kill paused processes to reclaim resources. Because of this, you should be sure that all of your state is saved by the time you return from this function. In general onSaveInstanceState(Bundle) is used to save per-instance state in the activity and this method is used to store global persistent data (in content providers, files, etc.)
Here's where I got that from.

Related

MediaRecorder Start Failed Error

I want to recording a call voice but i get MediaRecorder:start failed : -2147483648
It's my call record code block
public void SesKayitBaslat(String number) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/ASesKaydi");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
//recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
Log.e("Eror","1");
e.printStackTrace();
} catch (IOException e) {
Log.e("Eror","2");
e.printStackTrace();
}
if(!recordstarted)
{
recorder.start();
recordstarted = true;
}
Log.e("Kayit:", "Başladı");
}
What is my error ? Can anyone help me ? I Tried MediaRecorder.AudioSource.VOICE_CALL AND MediaRecorder.AudioSource.VOICE_COMMUNICATION
When i used Voice_Communication type i didn't get voice of caller.
code 2147483648 refers to MEDIA_ERROR_SYSTEM (low-level system error).
Based on the documentation:
A BroadcastReceiver object is only valid for the duration of the call
to onReceive(Context, Intent). Once your code returns from this
function, the system considers the object to be finished and no longer
active.
In other words, the MediaRecorder instance that you expect to be there might actually not exist anymore since you're within a different BroadcastReceiver instance than the one that created the MediaRecorder. Its not a great idea to perform this task in BroadcastReceiver since it will only execute for 10 seconds after which System could declare app as not responding.
One solution would be to execute this code to Service

Getting a weird filenotfoundexception

I am currently on the beginner level when it comes to Android & I am currently scratching my head over an issue that I am currently facing.
I am creating an Android app to check if "cache.json" exists in the internal storage:
If it does not exist then first create it & write a string fetched from HTTP API to the file (replaced with fixed string in code below).
Regardless, read the file after writing is done (if necessary) & do appropriate stuff.
This is the code snippet:
public class ShowClasses extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
filename = "cache.json";
file = new File(getApplicationContext().getFilesDir(), filename);
if (file.exists()) {
System.out.println("EXISTS");
} else {
System.out.println("DOES NOT EXIST");
writeFile();
}
readFile();
}
public void writeFile() {
new JsonTask().execute(email);
}
public void readFile() {
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int c;
result = "";
try {
while( (c = fin.read()) != -1){
result = result + Character.toString((char)c);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
private class JsonTask extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
result = ""; // Clear result
super.onPreExecute();
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
return "THIS STRING IS GOING TO BE RETURNED " + params[0];
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream fileout = null;
try {
fileout = new FileOutputStream(file);
fileout.write(result.getBytes());
//display file saved message
msg("File saved successfully!");
} catch (Exception e) {
e.printStackTrace();
}
try {
fileout.close();
} catch (IOException e) {
e.printStackTrace();
}
if (pd.isShowing()){
pd.dismiss();
}
}
}
}
I have tried to remove un-necessary part of the code so that it is smaller in length.
The actual issue I am facing is when writeFile() & readFile() both are called. I get a FileNotFoundException in readFile() when I open the stream even though the file should be created since writeFile() is called before readFile().
If I writeFile on one execution & then call readFile() on the other, it simply works as it should be.
This is the error that I am facing.
System.err: java.io.FileNotFoundException: /data/user/0/host.timetable.timetablenotifier/files/cache.json (No such file or directory)
System.err: at java.io.FileInputStream.open(Native Method)
Any help would be really appreciated.
Thanks
writeFile() is asynchronous. When that method returns, nothing has happened with respect to this file. At most, onPreExecute() of your JsonTask might be called. So, when you call readFile(), the file will not exist yet.
Beyond that:
You have an AsyncTask that you use in writeFile(), but you do your disk I/O in onPostExecute(), and that method is called on the main application thread.
You are doing disk I/O on the main application thread in readFile().
You catch exceptions, log them, but then continue executing your code, when most of those exceptions mean that the later statements are going to fail as well.
Reading in data one int at a time has not been a recommended approach for getting close to 20 years, for performance reasons.
You will have multiple issues related to configuration changes, such as screen rotations, as neither your AsyncTask nor your ProgressDialog account for configuration changes
Also:
getApplicationContext().getFilesDir() could be replaced by getFilesDir() in onCreate()
You do not need createNewFile()
AsyncTask runs in a background thread so the other code in the main thread doesn't wait for the execution to complete. In simpler terms, your readFile() method is executed before writeFile() completes and hence there is a FileNotFoundException. What would work for you is if you put the readFile() method at the end of the onPostExecute() method inside your Asynctask

Saving a file on the internal storage of android using Context

I'm trying to save a random hello world file onto the internal storage of my android. When I run my app, it simply stops.
Code:
public void saveDataOnDevice(String toWrite, String filename) {
Context ctx = null;
try {
FileOutputStream fos = ctx.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(toWrite.getBytes());
fos.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
Another question is, what Context means. I read a lot about this here, but I still don't get it.
First of all... your context is null always: Context ctx = null;, so you wont be able to make it work in any way.
To simplify: Context, in a simple app, will be your MainActivity. In a bigger app, you can have several contexts and answer will be more complex.
Back to your code, if it is placed inside your MainActivity context will be this:
public void saveDataOnDevice(String toWrite, String filename) {
try {
FileOutputStream fos = this.openFileOutput(filename, Context.MODE_PRIVATE);
// ^ --> refers to main class, in this case your MainActivity
fos.write(toWrite.getBytes());
fos.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
NOTE: if you don't have this method inside the MainActivity, you must pass a reference of your Activity to the method or the class somehow (attribute, method param, etc..etc...).
Check Android Developers::saving files for further info.

Java Smack FileTransfer

Okay, I got the following code from the web, and it does work:
#Override
public void fileTransferRequest(FileTransferRequest request) {
// Check to see if the request should be accepted
final IncomingFileTransfer transfer = request.accept();
runnningFileTransfer = transfer;
try
{
final File file = new File("/Users/Akku/Downloads/in2" + request.getFileName());
transfer.recieveFile(file);
t = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
transfer.recieveFile(file);
System.out.println("DONE?");
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t.run();
This code runs, and in the case of my 10MB test file it takes quite a lot of time. Sadly, I need to know if the transfer is finished or what the progress is. Funnily, I also got this part (which just sleeps and checks for progress) from the web, when I append it, the file transfer does not work anymore:
while(!transfer.isDone())
{
if(transfer.getStatus().equals(Status.error))
{
System.out.println("ERROR"+transfer.getError() + " EX: " + transfer.getException());
}
else
{
System.out.println("Written: "+transfer.getAmountWritten());
System.out.println("STATUS"+transfer.getStatus());
System.out.println("PROGRESS"+transfer.getProgress());
}
try
{
Thread.sleep(10000);
System.out.println("Waiting...");
}
catch (Exception e)
{
e.printStackTrace();
}
}
Any hint why this might happen? I guess it's something Java, because the above snippet works flawlessly.
The case that works should be throwing an exception. You call receive twice on the transfer object. The second call should produce an exception when it tries to create the file again. The second call, along with the thread creation is not necessary in this case as the transfer() method is asynchronous and has it's own internal threading.
It is hard to say why it doesn't work with your status check, since you don't show where you are doing this check. My suspicion is that you are calling it on the read thread and thus blocking the reading of new packets. Your loop checking for the transfer status should be running in its own thread.

Android MediaPlayer - switch to next song

I generate a midi file and write it like this:
File output = new File("exampleout.mid");
I think I might need to change this, so it is in the right folder (just a readable/writable folder, perhaps Music/ )
Next I want to play this midi file with MediaPlayer, but I cannot figure out how to load the file.
mediaPlayer = MediaPlayer.create(this, R.raw.test3);
Only loads from the read only directory /res/raw. But if I try something like:
mediaPlayer = MediaPlayer.create(this, "file://exampleout");
It does not work because create needs an integer as input. I experimented with AssetFileDescriptor, but haven't figured it out yet.
Meanwhile, I want to generate a new midi file and load it in mediaPlayer (chained) to play when the first file finishes playing.
MediaPlayer mediaPlayer = MediaPlayer.create(Activity.this,R.raw.a1);
mediaPlayer.setOnCompletionListener(new musicCompletionListener());
mediaPlayer.start();
private class musicCompletionListener implements OnCompletionListener {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.setDataSource(WHATTOPUTHERE)
mediaPlayer.release();
}
}
My Problem is really how to call the file. I cannot use strings apparantly, and the r.raw directory is not possible due to its read only nature. I feel the solution is not so difficult, but I am just easing into java from c++, any help is much appreciated!
I stored the file in the cache dir, that works!
File output = new File(getCacheDir() + "/exampleout.mid");
And then calling the file:
String filePath = null;
File file = null;
FileInputStream inputStream = null;
try {
filePath = getCacheDir() + "/exampleout.mid";
file = new File(filePath);
inputStream = new FileInputStream(file);
if(inputStream.getFD().valid())
{
System.out.println("Valid!");
}
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(inputStream.getFD());
inputStream.close();
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You have to nicely design the Architecture of your app then only you can achieve what you have asked.
According to me you can do the following.
Design an interface with the method midiReady(uri of midi file)
This interface is implemented by your activity which contains mediaplayer
As soon as midi file is generation is completed call the method midiReady(uri of midi file)
Now since your activity implements the interface callback is invoked on your activity and you can set the mediaplayer to play the midi file since in callback you have uri of your midi file.
The above metinoed points are just a faint idea what you can do.With above faint idea you can go forward for implementation.
Hope this will help.
Thanks.

Categories