在一个活动中运行多个任务

时间:2014-07-21 08:00:45

标签: android ftp

我有一个代码可以读取我的收件箱,并将每个读取的短信存储为固定文件夹中的单独文件,我需要稍后在FTP上传。我正在使用FTP上传的意图。我的程序结构类似于:onCreate() -> Method1 inbox read -> Delete inbox messages -> Method2 Upload FTP -> Method3 Delete Uploaded Folder -> Further Tasks问题是在应用程序完成上传文件夹内容之前调用Further Tasks并且服务器只是断开连接。我尝试在Method3的帮助下在Further Tasks中拨打Handler,延迟时间为10分钟,但这并没有帮助,因为上传可能需要花费更多时间。它可能根本没有任何文件上传,所以浪费了10分钟。我希望应用程序等到上传完成。所以问题是:这样做的正确方法是什么? 编辑:
我正在使用的代码:

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            ReadnDeleteSMS();
    }
    public void FTPUpload(){     //FTPUpload via ANDFTP app
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_PICK);
            Uri ftpUri = Uri.parse("Server");       //Server Call
            intent.setDataAndType(ftpUri, "vnd.android.cursor.dir/lysesoft.andftp.uri");
            intent.putExtra("command_type", "upload");
            intent.putExtra("ftp_username", "username");
            intent.putExtra("ftp_password", "password");
            intent.putExtra("ftp_pasv", "true");        
            intent.putExtra("ftp_resume", "true");
            intent.putExtra("ftp_encoding", "UTF-8");
            intent.putExtra("progress_title", "Uploading folder ...");
            intent.putExtra("local_file1", "/sdcard/ReceivedSMS");
            intent.putExtra("remote_folder", "remote folder");
            intent.putExtra("close_ui", "true");        //Finally start the Activity
            startActivityForResult(intent, RESULT_OK); i++;
            customHandler.postDelayed(finalizer, 10*60*1000);}

        public void ReadnDeleteSMS(){       //Reads, BackUps and Deletes Inbox Messages
            Cursor cursor1 = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);
            if (cursor1.getCount() > 0) {
                while (cursor1.moveToNext()){
                    int id = cursor1.getInt(0);
                    String address = cursor1.getString(cursor1.getColumnIndex("address"));
                    String date = cursor1.getString(cursor1.getColumnIndex("date"));
                    String SMSDate = DateConversion(date);
                    String msg = cursor1.getString(cursor1.getColumnIndex("body"));
                    ReadSMS = address + "\n" + SMSDate + "\n" + msg + "\n";
                    FileName(zText);
                    myDate = zText.toString(); zText = new StringBuilder();
                    fileWrite("/sdcard/ReceivedSMS/" + myDate, ReadSMS);
                    try{
                     getApplicationContext().getContentResolver().delete(Uri.parse("content://sms/" + id), null, null);
                     Toast.makeText(getBaseContext(), "Successfully Deleted", Toast.LENGTH_SHORT).show();}
                    catch(Exception e){
                        Toast.makeText(getBaseContext(), "Error Deleting", Toast.LENGTH_SHORT).show();}}}
            FTPUpload();}
  public String DateConversion (String date){           //Proper Date Format Display
        Long timestamp = Long.parseLong(date);    
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp);
        return calendar.getTime().toString();}

    public void FileName(StringBuilder zText) {         //Inbox Message File Name
        SimpleDateFormat mSDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
        myDate = mSDF.format(new Date());
        myDate = myDate.replace(" ", "");
        myDate = myDate.replace("/", "");
        myDate = myDate.replace(":", "");
        myDate = myDate.replace(".", "");
        zText.append(myDate);}
    public Runnable finalizer = new Runnable(){     //Main Handler
            public void run(){
                if (i > 0)
                {DeleteDirectory("/sdcard/ReceivedSMS"); i = 0;}
    //Some Further Tasks
    }

这些进一步的任务经常被调用,但如果上传正在执行,则不必执行此类任务。任务包括阅读网页,字符串编辑等。这些是我的应用程序的主要任务。

1 个答案:

答案 0 :(得分:0)

如果没有发布您正在使用的一些代码,这个过程很难帮助您,但如果您的问题是您必须等到一个任务完成另一个任务,那么这似乎是sendBroadcast的工作BroadcastReceiver

实施例

假设你在服务中处理ftp上传的逻辑(为简单起见,这个逻辑可能在AsyncTask或类似的东西上):

public class RefreshService extends IntentService {
    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            // Backgroud process here
            // ...
            // When the task is completed
            sendBroadcast(new Intent("com.example.action.REFRESH_COMPLETED"));
        }
    }
}

为了抓住com.example.action.REFRESH_COMPLETED,您必须提供BroadcastReceiver

public class RefreshCompletedReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // The logic you want to execute right after the background task is completed
    }

}

您还必须声明此类应该捕获您之前定义的特定操作。为此,请更新清单并包含接收方:

...
        <service
            android:name=".RefreshService"
            android:exported="false" >
        </service>

        <receiver android:name=".RefreshCompletedReceiver" >
            <intent-filter>
                 <action android:name="com.example.action.REFRESH_COMPLETED" />
            </intent-filter>
        </receiver>
...

就是这样。 BroadcastReceiver中的代码将在后台进程完成后执行。请记住,您需要处理进程中断或类似网络错误,并且只有在操作成功时才​​调用sendBroadcast

其他信息

  • 您可以使用context中的registerReceiver动态注册接收者,但您必须取消注册(通常使用活动的onDestroy方法),否则您的应用会崩溃(参见参考资料)。
  • This在这类问题上给了我很多帮助。
  • 同时选中this question以在ServiceAsyncTask之间进行选择。
  • 查看文档herehere,了解有关这两者的更多信息。

声明

我刚刚开始在android中编程,所以可能还有另一种方法可以做到这一点,我发现这种方式很容易理解,也更容易实现。