I'm trying to update the progress of a notification during ftp upload handled by a background service, I tried directly from the service and after using a ResultReceiver but when the upload starts, the notification menu is freezed until the upload is done.How can I do this?
FtpService
public class FtpService extends IntentService {
public static final int UPDATE_PROGRESS = 10;
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
private static final String ACTION_SEND = "SEND";
private static final String EXTRA_PATH = "PATH";
private static final String PREFERENCES = "virtualtv";
private SharedPreferences mPrefs;
private NotificationManager mNotifyManager;
private NotificationCompat.Builder mBuilder;
/********* work only for Dedicated IP ***********/
private String FTP_HOST= "";
/********* FTP USERNAME ***********/
private String FTP_USER;
/********* FTP PASSWORD ***********/
private String FTP_PASS;
private String FTP_PORT;
private String PATH;
private Context mContext;
public FTPClient ftpClient;
private ResultReceiver mUploadReceiver;
public FtpService() {
super("FtpService");
}
/**
* Starts this service to perform action Foo with the given parameters. If
* the service is already performing a task this action will be queued.
*
* @see IntentService
*/
// TODO: Customize helper method
public static void startActionSend(Context context, String param1) {
Intent intent = new Intent(context, FtpService.class);
intent.setAction(ACTION_SEND);
intent.putExtra(EXTRA_PATH, param1);
intent.putExtra("UPLOAD_RECEIVER", new UploadReceiver(new Handler(), context));
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
mContext = this;
final String action = intent.getAction();
mUploadReceiver = intent.getParcelableExtra("UPLOAD_RECEIVER");
if (ACTION_SEND.equals(action)) {
final String filePath = intent.getStringExtra(EXTRA_PATH);
mPrefs = mContext.getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE);
JsonObject config = Account.getInstance(mContext).getConfig();
if(mPrefs != null && config != null){
FTP_HOST = config.get("ftp_host").getAsString();
FTP_USER = config.get("ftp_username").getAsString();
FTP_PASS = config.get("ftp_password").getAsString();
FTP_PORT = config.get("ftp_port").getAsString();
PATH = config.get("ftp_path").getAsString();
}
handleActionSend(filePath);
}
}
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionSend(String filePath) {
File f = new File(filePath);
uploadFile(f);
}
public boolean uploadFile(final File f){
try {
ftpClient = new FTPClient();
ftpClient.connect(FTP_HOST, Integer.valueOf(FTP_PORT));
boolean b = ftpClient.login(FTP_USER, FTP_PASS);
Log.d("Login", "" + b);
b = ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
Log.d("file_type", "" + b);
b = ftpClient.changeWorkingDirectory(PATH);
Log.d("directory", "" + b);
// ftpClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
//
int reply = ftpClient.getReplyCode();
Log.d("reply", "" + reply);
// if(!FTPReply.isPositiveCompletion(reply)) {
// ftpClient.logout();
// ftpClient.disconnect();
// Log.d("ftp", "FTP server refused connection.");
// return false;
// }
InputStream srcFileStream = new FileInputStream(f);
// BufferedInputStream buffIn = new BufferedInputStream(new FileInputStream(f));
ftpClient.setControlKeepAliveTimeout(10);
ftpClient.enterLocalPassiveMode();
final int fileSize = (int) (FileUtils.sizeOf(f) / 1024);
// dati trasferiti
ftpClient.setCopyStreamListener(new CopyStreamListener() {
@Override
public void bytesTransferred(CopyStreamEvent event) {
}
@Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
Log.d("ftp", "total:" + totalBytesTransferred / 1024 + " trasnferred: " + bytesTransferred + " size:" + fileSize);
Bundle data = new Bundle();
data.putInt("fileSize", fileSize);
data.putInt("kbyte_transferred", (int) totalBytesTransferred / 1024);
mUploadReceiver.send(UPDATE_PROGRESS, data);
}
});
// Log.d("buffer", "" + buffIn.available());
Log.d("ftp", "storing file...");
boolean result = ftpClient.storeFile(f.getName(), srcFileStream);
Log.d("ftp", "result:" + result);
Log.d("ftp", "reply code:" + ftpClient.getReplyCode());
// inputStream.close();
srcFileStream.close();
// buffIn.close();
ftpClient.logout();
ftpClient.disconnect();
return result;
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (CopyStreamException e) {
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
return false;
}
}
UploadReceiver
class UploadReceiver extends ResultReceiver{
private NotificationManager mNotifyManager;
private NotificationCompat.Builder mBuilder;
private int id = 1;
public UploadReceiver(Handler handler, Context context) {
super(handler);
final int id = 1;
//Gestione notifica
mNotifyManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_launcher);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == FtpService.UPDATE_PROGRESS) {
int fileSize = resultData.getInt("file_size");
int transferred = resultData.getInt("kbyte_transferred");
mBuilder.setProgress(fileSize,transferred, false);
mNotifyManager.notify(id, mBuilder.build());
}
}
}
I solved the issue adding a check with an interval of 1000 milliseconds, if these have gone the UploadReceiver can update the notify and in this way it seems to work fine without freeze.It works also with a lower interval as 500 milliseconds.