从后台服务更新通知进度

Update progress of notification from a background service

我正在尝试更新由后台服务处理的 ftp 上传期间的通知进度,我直接从该服务尝试并在使用 ResultReceiver 之后,但是当上传开始时,通知菜单是冻结,直到上传 done.How 我可以这样做吗?

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;

}


}

上传接收器

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());
    }
}
}

我解决了这个问题,添加了一个间隔为 1000 毫秒的检查,如果这些已经消失,UploadReceiver 可以更新通知,这样它似乎在没有 freeze.It 的情况下工作正常,也可以在较低的间隔下工作500 毫秒。

伙计们,我的情况是渲染了很多次进度,但我只想要 100 次进度,所以这段代码解决了我的问题。

int oldProgress =1;

  int progresss = (int) ((progress.currentBytes / (float) progress.totalBytes) * 100);

                    if(progresss>oldProgress)
                    {
                        oldProgress=progresss;
                        notificationBuilder.setProgress(100, progresss,false);
                        notification = notificationBuilder.build();
                        notificationManager.notify(notificationID,notification);

                    }