我有一个代码可以读取我的收件箱,并将每个读取的短信存储为固定文件夹中的单独文件,我需要稍后在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
}
这些进一步的任务经常被调用,但如果上传正在执行,则不必执行此类任务。任务包括阅读网页,字符串编辑等。这些是我的应用程序的主要任务。
答案 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
。
registerReceiver
动态注册接收者,但您必须取消注册(通常使用活动的onDestroy
方法),否则您的应用会崩溃(参见参考资料)。Service
和AsyncTask
之间进行选择。我刚刚开始在android中编程,所以可能还有另一种方法可以做到这一点,我发现这种方式很容易理解,也更容易实现。