Tuesday, November 5, 2013

Saving to a file in Android

We create the routine apart, as part of a task, but that is irrelevant to the topic. Straight to the code...
async_save_file.java
 package com.example.saveit;  
 import java.io.DataOutputStream;  
 import java.io.File;  
 import java.io.FileOutputStream;  
 import java.text.SimpleDateFormat;  
 import java.util.Date;  
 import java.util.Locale;  
 import android.content.Context;  
 import android.os.AsyncTask;  
 import android.os.Environment;  
 import android.os.Handler;  
 import android.os.Message;  
 import android.util.Log;  
 public class async_save_file extends AsyncTask<Void, Void, Void> {  
   Context mContext;  
   private Handler threadHandler;  
   private int[] audio_buffer;  
   public async_save_file(Context context,Handler threadHandler, int[] buffer) {  
     super();  
     this.threadHandler=threadHandler;  
     this.audio_buffer=buffer;  
     mContext = context;  
       }  
   @Override  
     protected Void doInBackground(Void...params) {   
     String root = Environment.getExternalStorageDirectory().toString();  
     File myDir = new File(root + "/captured_files");    
     if (myDir.exists()) Log.v(saveit.TAG,"S: Diretory exists!");  
     else {  
          myDir.mkdirs();   
          Log.v(saveit.TAG,"S: Diretory created!");  
     }  
     String dateInString = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss",Locale.US).format(  
         new Date()).toString();  
     String fileName = dateInString + "_record.bin";  
     File file = new File (myDir, fileName);  
     Log.v(saveit.TAG,"S: file path: "+file.getPath());  
     if (file.exists ()) file.delete ();   
     try {  
          FileOutputStream out = new FileOutputStream(file);  
       DataOutputStream out_s = new DataOutputStream(out);  
           Log.v(saveit.TAG, "L: Length: "+audio_buffer.length);  
           for (int i=0;i<audio_buffer.length;i++) out_s.writeChar(audio_buffer[i]);  
           //out_s.flush();  
           //out.flush();  
           //out.close();  
           out_s.close();   
              Message.obtain(this.threadHandler, saveit.ACK_SAVED, "SAVED").sendToTarget();   
                return null;  
       } catch (Exception e) {  
            e.printStackTrace();  
                    Message.obtain(this.threadHandler, saveit.ACK_NOT_SAVED, "FAILED SAVING").sendToTarget();   
                    return null;  
       }  
   }  
 }  
Notice also the flushing of the file (most of it commented out as the last instruction takes care of the rest). See flushing the file and Will closing a dataoutputstream close also the fileoutputstream. This is called from saveit.java
 package com.example.saveit;  
 import android.os.Bundle;  
 import android.os.Handler;  
 import android.annotation.SuppressLint;  
 import android.app.Activity;  
 import android.util.Log;  
 import android.view.View;  
 import android.widget.Button;  
 import android.widget.TextView;  
 import android.widget.Toast;  
 public class saveit extends Activity {  
      public static final int ACK_SAVED=1;  
      public static final int ACK_NOT_SAVED=2;  
      public static final String TAG = "MyActivity";  
      private TextView mResult;       
      private Button save_array;                    // To trigger the whole process  
      private int[] audio_buffer={1,2,3,4};  
      @Override  
      protected void onCreate(Bundle savedInstanceState) {  
           super.onCreate(savedInstanceState);  
           setContentView(R.layout.saveit_layout);  
           save_array=(Button)findViewById(R.id.button1);  
           mResult=(TextView)findViewById(R.id.display);  
           save_array.setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                     // TODO Auto-generated method stub  
                     new async_save_file(getApplicationContext(),threadHandler,audio_buffer).execute();  
                     Log.v(TAG, "UI: SAVING");  
                     mResult.setText("SAVING");        
                }  
           });  
      }  
      ////////////////////////////////////thread Handler///////////////////////////////////////  
      @SuppressLint("HandlerLeak")  
      private Handler threadHandler = new Handler() {  
           public void handleMessage(android.os.Message msg) {  
           switch(msg.what){  
                case ACK_SAVED:  
                     Toast.makeText(getBaseContext(), (String)msg.obj, Toast.LENGTH_SHORT).show();  
                     mResult.setText("SAVED");   
                     break;  
                case ACK_NOT_SAVED:  
                     Toast.makeText(getBaseContext(), (String)msg.obj, Toast.LENGTH_SHORT).show();  
                     mResult.setText("NOT SAVED");   
                     break;  
                }            
           }  
      };  
 }  
Along the way, I also used few ways to display results/debug notices... just as example...

The manifest:
 <?xml version="1.0" encoding="utf-8"?>  
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
   package="com.example.saveit"  
   android:versionCode="1"  
   android:versionName="1.0" >  
   <uses-sdk  
     android:minSdkVersion="9"  
     android:targetSdkVersion="17" />  
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
   <application  
     android:allowBackup="true"  
     android:icon="@drawable/ic_launcher"  
     android:label="@string/app_name"  
     android:theme="@style/AppTheme" >  
     <activity  
       android:name="com.example.saveit.saveit"  
       android:label="@string/app_name" >  
       <intent-filter>  
         <action android:name="android.intent.action.MAIN" />  
         <category android:name="android.intent.category.LAUNCHER" />  
       </intent-filter>  
     </activity>  
   </application>  
 </manifest>  
And the layout:
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:paddingBottom="@dimen/activity_vertical_margin"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   tools:context=".MyAdderActivity" >  
   <Button  
     android:id="@+id/button1"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:layout_centerHorizontal="true"  
     android:layout_marginTop="81dp"  
     android:text="@string/save_button" />  
   <TextView  
     android:id="@+id/display"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:layout_below="@+id/button1"  
     android:layout_centerHorizontal="true"  
     android:text="@string/display" />  
 </RelativeLayout>  
Cheers!

PS.: Please, click here to see an index of other posts on Android. 

No comments:

Post a Comment