【问题标题】:Downloading a text file using Intent from FTP Server.使用 Intent 从 FTP 服务器下载文本文件。
【发布时间】:2012-05-30 09:18:33
【问题描述】:

我正在使用 ftp 连接从服务器下载文本文件。 但不幸的是我得到了例外:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.PICK dat=64.78.178.19 typ=vnd.android.cursor.dir/lysesoft.andftp.uri (has extras) }

我也在 manifest.xml 中定义了活动。

下面是我的清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.saltriver.hourdoc"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>


<application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
    <activity android:name=".HourdocActivity"
              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>

下载文本文件的代码。

public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

   Button downloadFilesButton = (Button) findViewById(R.id.button_download_files_id);
    downloadFilesButton.setOnClickListener(new View.OnClickListener()
    {
  public void onClick(View v) 
  {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_PICK);
    // FTP URL (Starts with ftp://, sftp://, ftps:// or scp:// followed by hostname and port).
    Uri ftpUri = Uri.parse(ConstantCodes.ftphost);
    intent.setDataAndType(ftpUri, ConstantCodes.ftpuri);
    // Download
    intent.putExtra("command_type", "download");
    // FTP credentials (optional)
    intent.putExtra("ftp_username", ConstantCodes.userid);
    intent.putExtra("ftp_password", ConstantCodes.pwd);
    //intent.putExtra("ftp_keyfile", "/sdcard/dsakey.txt");
    //intent.putExtra("ftp_keypass", "optionalkeypassword");
    // FTP settings (optional)
    intent.putExtra("ftp_pasv", "true");
    //intent.putExtra("ftp_resume", "true");
    //intent.putExtra("ftp_encoding", "UTF-8");
    //intent.putExtra("ftps_mode", "implicit");
    // Activity title
    intent.putExtra("progress_title", "Downloading files ...");
    // Remote files to download.
    intent.putExtra("remote_file1",  ConstantCodes.ftp_remotefile1);
    //intent.putExtra("remote_file2", "/remotefolder/subfolder/file2.zip");
    // Target local folder where files will be downloaded.
    intent.putExtra("local_folder",  ConstantCodes.localfolder_path);  
    intent.putExtra("close_ui", "true");  
    startActivityForResult(intent,ConstantCodes.DOWNLOAD_FILES_REQUEST);
  }
    });
}

protected void onActivityResult(int requestCode, int resultCode, Intent intent) 
 {
Log.i(TAG, "Result: "+resultCode+ " from request: "+requestCode);
if (intent != null)
{
  String transferredBytesStr = intent.getStringExtra("TRANSFERSIZE");
  String transferTimeStr = intent.getStringExtra("TRANSFERTIME");
  Log.i(TAG, "Transfer status: " + intent.getStringExtra("TRANSFERSTATUS"));
  Log.i(TAG, "Transfer amount: " + intent.getStringExtra("TRANSFERAMOUNT") + " file(s)");
  Log.i(TAG, "Transfer size: " + transferredBytesStr + " bytes");
  Log.i(TAG, "Transfer time: " + transferTimeStr + " milliseconds");
  // Compute transfer rate.
  if ((transferredBytesStr != null) && (transferTimeStr != null))
  {
    try
    {
      long transferredBytes = Long.parseLong(transferredBytesStr);
      long transferTime = Long.parseLong(transferTimeStr);
      double transferRate = 0.0;
      if (transferTime > 0) transferRate = ((transferredBytes) * 1000.0) / (transferTime * 1024.0);
      Log.i(TAG, "Transfer rate: " + transferRate + " KB/s");
    } 
    catch (NumberFormatException e)
    {
       // Cannot parse string.
     }
   }
 }
}

建议我哪里做错了。

【问题讨论】:

    标签: android android-intent ftp


    【解决方案1】:

    我给你找到了一些东西。检查这个GoogleCode 示例项目。它非常适合我。他们正在使用以下类实现下载功能

    DownloaderThread.java

    public class DownloaderThread extends Thread
    {
        // constants
        private static final int DOWNLOAD_BUFFER_SIZE = 4096;
    
        // instance variables
        private AndroidFileDownloader parentActivity;
        private String downloadUrl;
    
        /**
         * Instantiates a new DownloaderThread object.
         * @param parentActivity Reference to AndroidFileDownloader activity.
         * @param inUrl String representing the URL of the file to be downloaded.
         */
        public DownloaderThread(AndroidFileDownloader inParentActivity, String inUrl)
        {
            downloadUrl = "";
            if(inUrl != null)
            {
                downloadUrl = inUrl;
            }
            parentActivity = inParentActivity;
        }
    
        /**
         * Connects to the URL of the file, begins the download, and notifies the
         * AndroidFileDownloader activity of changes in state. Writes the file to
         * the root of the SD card.
         */
        @Override
        public void run()
        {
            URL url;
            URLConnection conn;
            int fileSize, lastSlash;
            String fileName;
            BufferedInputStream inStream;
            BufferedOutputStream outStream;
            File outFile;
            FileOutputStream fileStream;
            Message msg;
    
            // we're going to connect now
            msg = Message.obtain(parentActivity.activityHandler,
                    AndroidFileDownloader.MESSAGE_CONNECTING_STARTED,
                    0, 0, downloadUrl);
            parentActivity.activityHandler.sendMessage(msg);
    
            try
            {
                url = new URL(downloadUrl);
                conn = url.openConnection();
                conn.setUseCaches(false);
                fileSize = conn.getContentLength();
    
                // get the filename
                lastSlash = url.toString().lastIndexOf('/');
                fileName = "file.bin";
                if(lastSlash >=0)
                {
                    fileName = url.toString().substring(lastSlash + 1);
                }
                if(fileName.equals(""))
                {
                    fileName = "file.bin";
                }
    
                // notify download start
                int fileSizeInKB = fileSize / 1024;
                msg = Message.obtain(parentActivity.activityHandler,
                        AndroidFileDownloader.MESSAGE_DOWNLOAD_STARTED,
                        fileSizeInKB, 0, fileName);
                parentActivity.activityHandler.sendMessage(msg);
    
                // start download
                inStream = new BufferedInputStream(conn.getInputStream());
                outFile = new File(Environment.getExternalStorageDirectory() + "/" + fileName);
                fileStream = new FileOutputStream(outFile);
                outStream = new BufferedOutputStream(fileStream, DOWNLOAD_BUFFER_SIZE);
                byte[] data = new byte[DOWNLOAD_BUFFER_SIZE];
                int bytesRead = 0, totalRead = 0;
                while(!isInterrupted() && (bytesRead = inStream.read(data, 0, data.length)) >= 0)
                {
                    outStream.write(data, 0, bytesRead);
    
                    // update progress bar
                    totalRead += bytesRead;
                    int totalReadInKB = totalRead / 1024;
                    msg = Message.obtain(parentActivity.activityHandler,
                            AndroidFileDownloader.MESSAGE_UPDATE_PROGRESS_BAR,
                            totalReadInKB, 0);
                    parentActivity.activityHandler.sendMessage(msg);
                }
    
                outStream.close();
                fileStream.close();
                inStream.close();
    
                if(isInterrupted())
                {
                    // the download was canceled, so let's delete the partially downloaded file
                    outFile.delete();
                }
                else
                {
                    // notify completion
                    msg = Message.obtain(parentActivity.activityHandler,
                            AndroidFileDownloader.MESSAGE_DOWNLOAD_COMPLETE);
                    parentActivity.activityHandler.sendMessage(msg);
                }
            }
            catch(MalformedURLException e)
            {
                String errMsg = parentActivity.getString(R.string.error_message_bad_url);
                msg = Message.obtain(parentActivity.activityHandler,
                        AndroidFileDownloader.MESSAGE_ENCOUNTERED_ERROR,
                        0, 0, errMsg);
                parentActivity.activityHandler.sendMessage(msg);
            }
            catch(FileNotFoundException e)
            {
                String errMsg = parentActivity.getString(R.string.error_message_file_not_found);
                msg = Message.obtain(parentActivity.activityHandler,
                        AndroidFileDownloader.MESSAGE_ENCOUNTERED_ERROR,
                        0, 0, errMsg);
                parentActivity.activityHandler.sendMessage(msg); 
            }
            catch(Exception e)
            {
                String errMsg = parentActivity.getString(R.string.error_message_general);
                msg = Message.obtain(parentActivity.activityHandler,
                        AndroidFileDownloader.MESSAGE_ENCOUNTERED_ERROR,
                        0, 0, errMsg);
                parentActivity.activityHandler.sendMessage(msg); 
            }
        }
    
    }
    

    更新

    或者您可以简单地将以下代码用于UploadDownload 进程。

    package com.resource.util;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    
    /**
     * This class is used to upload a file to a FTP server.
     *
     * @author Muthu
     */
    public class FileUpload
    {
    
       /**
        * Upload a file to a FTP server. A FTP URL is generated with the
        * following syntax:
        * ftp://user:password@host:port/filePath;type=i.
        *
        * @param ftpServer , FTP server address (optional port ':portNumber').
        * @param user , Optional user name to login.
        * @param password , Optional password for user.
        * @param fileName , Destination file name on FTP server (with optional
        *            preceding relative path, e.g. "myDir/myFile.txt").
        * @param source , Source file to upload.
        * @throws MalformedURLException, IOException on error.
        */
       public void upload( String ftpServer, String user, String password,
             String fileName, File source ) throws MalformedURLException,
             IOException
       {
          if (ftpServer != null &amp;&amp; fileName != null &amp;&amp; source != null)
          {
             StringBuffer sb = new StringBuffer( "ftp://" );
             // check for authentication else assume its anonymous access.
             if (user != null &amp;&amp; password != null)
             {
                sb.append( user );
                sb.append( ':' );
                sb.append( password );
                sb.append( '@' );
             }
             sb.append( ftpServer );
             sb.append( '/' );
             sb.append( fileName );
             /*
              * type ==&gt; a=ASCII mode, i=image (binary) mode, d= file directory
              * listing
              */
             sb.append( ";type=i" );
    
             BufferedInputStream bis = null;
             BufferedOutputStream bos = null;
             try
             {
                URL url = new URL( sb.toString() );
                URLConnection urlc = url.openConnection();
    
                bos = new BufferedOutputStream( urlc.getOutputStream() );
                bis = new BufferedInputStream( new FileInputStream( source ) );
    
                int i;
                // read byte by byte until end of stream
                while ((i = bis.read()) != -1)
                {
                   bos.write( i );
                }
             }
             finally
             {
                if (bis != null)
                   try
                   {
                      bis.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
                if (bos != null)
                   try
                   {
                      bos.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
             }
          }
          else
          {
             System.out.println( "Input not available." );
          }
       }
    
       /**
        * Download a file from a FTP server. A FTP URL is generated with the
        * following syntax:
        * ftp://user:password@host:port/filePath;type=i.
        *
        * @param ftpServer , FTP server address (optional port ':portNumber').
        * @param user , Optional user name to login.
        * @param password , Optional password for user.
        * @param fileName , Name of file to download (with optional preceeding
        *            relative path, e.g. one/two/three.txt).
        * @param destination , Destination file to save.
        * @throws MalformedURLException, IOException on error.
        */
       public void download( String ftpServer, String user, String password,
             String fileName, File destination ) throws MalformedURLException,
             IOException
       {
          if (ftpServer != null &amp;&amp; fileName != null &amp;&amp; destination != null)
          {
             StringBuffer sb = new StringBuffer( "ftp://" );
             // check for authentication else assume its anonymous access.
             if (user != null &amp;&amp; password != null)
             {
                sb.append( user );
                sb.append( ':' );
                sb.append( password );
                sb.append( '@' );
             }
             sb.append( ftpServer );
             sb.append( '/' );
             sb.append( fileName );
             /*
              * type ==&gt; a=ASCII mode, i=image (binary) mode, d= file directory
              * listing
              */
             sb.append( ";type=i" );
             BufferedInputStream bis = null;
             BufferedOutputStream bos = null;
             try
             {
                URL url = new URL( sb.toString() );
                URLConnection urlc = url.openConnection();
    
                bis = new BufferedInputStream( urlc.getInputStream() );
                bos = new BufferedOutputStream( new FileOutputStream(
                      destination.getName() ) );
    
                int i;
                while ((i = bis.read()) != -1)
                {
                   bos.write( i );
                }
             }
             finally
             {
                if (bis != null)
                   try
                   {
                      bis.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
                if (bos != null)
                   try
                   {
                      bos.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
             }
          }
          else
          {
             System.out.println( "Input not available" );
          }
       }
    }
    

    从上面的代码download() 方法可以为您提供所需的任何内容。

    【讨论】:

      【解决方案2】:

      我使用库 Download Commons Net 是最好的库之一,它非常适合上传或下载

      【讨论】:

      • 嗨,我使用相同的方式进行上传,但它给出了异常:java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClient。你能帮我吗?