多文件上传只上传最后一个文件,不上传其余文件


Multiple file upload is uploading only last file and not the rest

我创建了一个应用程序,它应该一个接一个地上传特定目录中的所有文件。代码只上载目录中的最后一个文件,而不是所有文件。

活动类别:

public class UploadAudioDemo extends Activity {
    private static final int SELECT_AUDIO = 2;
    String selectedPath = "";
    ArrayList<String> selectedPathList = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload_audio_demo);

        openGalleryAudio();
    }
    public void openGalleryAudio(){
        String name = null;
        File sdCardRoot = Environment.getExternalStorageDirectory();
        File yourDir = new File(sdCardRoot, "/My_records");
        for (File f : yourDir.listFiles()) 
        {
            if (f.isFile())
                name = f.getName();
            selectedPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/My_records/"+name;
            // Do your stuff
            Log.d("selectedPath", selectedPath);
            selectedPathList.add(selectedPath);
        }

        new Thread(new Runnable() 
        {
            public void run() 
            {
                runOnUiThread(new Runnable() 
                {
                    public void run() 
                    {
                    }
                });                      
                Iterator<String> it = selectedPathList.iterator();
                while (it.hasNext()) 
                {
                    doFileUpload(it.next()+"");
                }
            }
        }).start();    
    }

    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
    private void doFileUpload(String myFileUrl)
    {
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream inStream = null;
        String lineEnd = "'r'n";
        String twoHyphens = "--";
        String boundary =  "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1*1024*1024;
        String responseFromServer = "";
        String urlString = "http://bumba27.byethost16.com/Tracker/Services/recordedAudio/file_upload_new.php?mb_code='mb_code1'";
        try
        {
            //------------------ CLIENT REQUEST
            FileInputStream fileInputStream = new FileInputStream(new File(myFileUrl) );
            // open a URL connection to the Servlet
            URL url = new URL(urlString);
            // Open a HTTP connection to the URL
            conn = (HttpURLConnection) url.openConnection();
            // Allow Inputs
            conn.setDoInput(true);
            // Allow Outputs
            conn.setDoOutput(true);
            // Don't use a cached copy.
            conn.setUseCaches(false);
            // Use a post method.
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
            dos = new DataOutputStream( conn.getOutputStream() );
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name='"uploadedfile'";filename='"" + selectedPath + "'"" + lineEnd);                 
            dos.writeBytes(lineEnd);
            // create a buffer of maximum size
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];
            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            while (bytesRead > 0)
            {
                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }
            // send multipart form data necesssary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
            // close streams
            Log.e("Debug","File is written");
            fileInputStream.close();
            dos.flush();
            dos.close();
        }
        catch (MalformedURLException ex)
        {
            Log.e("Debug", "error: " + ex.getMessage(), ex);
        }
        catch (IOException ioe)
        {
            Log.e("Debug", "error: " + ioe.getMessage(), ioe);
        }
        //------------------ read the SERVER RESPONSE
        try {
            inStream = new DataInputStream ( conn.getInputStream() );
            String str;
            while (( str = inStream.readLine()) != null)
            {
                Log.e("Debug","Server Response "+str);
            }
            inStream.close();
        }
        catch (IOException ioex){
            Log.e("Debug", "error: " + ioex.getMessage(), ioex);
        }
    }
} 

logcat报告:

/storage/sdcard0/My_records/10_12_2013_13_00_12.amr
/storage/sdcard0/My_records/10_12_2013_13_01_27.amr
File is written
Server Response The file is: 10_12_2013_13_01_27.amr and mb_code is: 'mb_code1'
File is written
Server Response The file is: 10_12_2013_13_01_27.amr and mb_code is: 'mb_code1'

从logcat输出中,我们可以理解,在迭代数组时,我们得到了两个文件链接,但在上传时,只上传了最后一个文件。

我错过了什么?如何纠正这种情况

我认为问题在于,所有上传都使用相同的后台线程。

也就是说,它开始上传文件1..n-1,但由于上传下一个n+1文件的新需求而不断中断。最后一次文件上传没有中断,因此成功。

我建议调查IntentServices:http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/

有了用于上传文件的IntentService,您可以直接在UI线程中对文件进行简单的循环。

for (filesYouWantToUpload) {
     Intent i = new Intent(context, UploadIntentService.class);
     i.putStringExtra(file);
     startService(i);
}

编辑:

无法测试代码,但它应该是这样的。

FileUploader IntentService:

public class FileUploader extends IntentService {
private static final String TAG = FileUploader.class.getName();

public FileUploader() {
    super("FileUploader");
}
@Override
protected void onHandleIntent(Intent intent) {
    String selectedPath = intent.getStringExtra("selectedPath");
    String myFileUrl = intent.getStringExtra("myFileUrl");
    doFileUpload(selectedPath, myFileUrl);
}
 private void doFileUpload(String selectedPath, String myFileUrl)
    {
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream inStream = null;
        String lineEnd = "'r'n";
        String twoHyphens = "--";
        String boundary =  "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1*1024*1024;
        String responseFromServer = "";
        String urlString = "http://bumba27.byethost16.com/Tracker/Services/recordedAudio/file_upload_new.php?mb_code='mb_code1'";
        try
        {
            //------------------ CLIENT REQUEST
            FileInputStream fileInputStream = new FileInputStream(new File(myFileUrl) );
            // open a URL connection to the Servlet
            URL url = new URL(urlString);
            // Open a HTTP connection to the URL
            conn = (HttpURLConnection) url.openConnection();
            // Allow Inputs
            conn.setDoInput(true);
            // Allow Outputs
            conn.setDoOutput(true);
            // Don't use a cached copy.
            conn.setUseCaches(false);
            // Use a post method.
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
            dos = new DataOutputStream( conn.getOutputStream() );
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name='"uploadedfile'";filename='"" + selectedPath + "'"" + lineEnd);                 
            dos.writeBytes(lineEnd);
            // create a buffer of maximum size
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];
            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            while (bytesRead > 0)
            {
                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }
            // send multipart form data necesssary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
            // close streams
            Log.e("Debug","File is written");
            fileInputStream.close();
            dos.flush();
            dos.close();
        }
        catch (MalformedURLException ex)
        {
            Log.e("Debug", "error: " + ex.getMessage(), ex);
        }
        catch (IOException ioe)
        {
            Log.e("Debug", "error: " + ioe.getMessage(), ioe);
        }
        //------------------ read the SERVER RESPONSE
        try {
            inStream = new DataInputStream ( conn.getInputStream() );
            String str;
            while (( str = inStream.readLine()) != null)
            {
                Log.e("Debug","Server Response "+str);
            }
            inStream.close();
        }
        catch (IOException ioex){
            Log.e("Debug", "error: " + ioex.getMessage(), ioex);
        }
    }
 }

记得更新您的清单:

 <service android:name="yourpackage.FileUploader " />

最后openGalleryAudio()会是这样的:

  public void openGalleryAudio(){
    String name = null;
    File sdCardRoot = Environment.getExternalStorageDirectory();
    File yourDir = new File(sdCardRoot, "/My_records");
    for (File f : yourDir.listFiles()) 
    {
        if (f.isFile())
            name = f.getName();
        selectedPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/My_records/"+name;
        // Do your stuff
        Log.d("selectedPath", selectedPath);
        selectedPathList.add(selectedPath);
    }

    Iterator<String> it = selectedPathList.iterator();
    while (it.hasNext()) 
    {
        Intent i = new Intent(this, FileUploader.class)
        i.putExtra("selectedPath", selectedPath);
        i.putExtra("myFileUrl", it.next()+"");
        startService(i);
    }

}

我在引用cYrixmorten的代码后解决了这个问题。我不得不对cYrixmorten的回答做一个小改动。

openGalleryAudio()方法中的编辑:

public void openGalleryAudio(){

    String name = null;
    File sdCardRoot = Environment.getExternalStorageDirectory();
    File yourDir = new File(sdCardRoot, "/My_records");
    for (File f : yourDir.listFiles()) 
    {
        if (f.isFile())
            name = f.getName();
        selectedPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/My_records/"+name;
        // Do your stuff
        Log.d("selectedPath", selectedPath);
        selectedPathList.add(selectedPath);
    }

    for(int z=0; z<selectedPathList.size();z++)
    {
        Intent i = new Intent(this, FileUploader.class);
        i.putExtra("selectedPath", selectedPathList.get(z));
        i.putExtra("myFileUrl", selectedPathList.get(z));
        startService(i);
    }
}

我实现了一个简单的for循环,而不是迭代器。其余的仍然和克里斯莫尔顿的回答一样