【问题标题】:Multiple file upload is uploading only last file and not the rest多文件上传仅上传最后一个文件,而不是其余文件
【发布时间】:2013-12-29 08:58:54
【问题描述】:

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

活动类:

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 输出中我们可以了解到,在迭代数组时,我们获取了两个文件链接,但在上传时只上传了最后一个文件。

我错过了什么?该如何纠正?

【问题讨论】:

    标签: java php android file-upload


    【解决方案1】:

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

    也就是说,它开始上传文件 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);
        }
    
    
    }
    

    【讨论】:

    • 试过了,结果还是一样,最后一个文件才上传。可以做什么?
    【解决方案2】:

    在参考 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 循环,而不是迭代器。其余的和 cYrixmorten 回答的一样。

    【讨论】:

    • 很高兴你成功了! :) 可能这首先是问题吗?
    • 可能是,但我感谢您的贡献。
    猜你喜欢
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多