在服务上使用 AWS TransferUtility

Using AWS TransferUtility on a service

我需要你的帮助,我正在制作一个 Android 应用程序报告一些信息(文本和图像),我使用 Service 来同步数据,当谈到图像时,我使用的是 TransferManager 方法,它在大多数时候都运行良好,知道这种方法已被弃用,所以我转向 TransferUtility 方法,它也运行良好但我注意到 Activity当这个方法是运行的时候卡死了,不知道怎么办

ps: 我在异步任务中包含了该方法,但问题仍然存在。

感谢您的帮助。

我的服务代码是下一个:

LIBRARY IMPORTS

public class ServicioUpload extends Service{

private Timer timer = null

private AWSCredentials credential;
private TransferObserver observer;
private TransferUtility transferUtility;

public void onCreate(){
    super.onCreate();       
    varDb =new VIPVSQLiteHelper(this, "DB", null, 1);   

    db = varDb.getWritableDatabase();   
    movil = db.rawQuery("SELECT * FROM Movil",null); 
    movil.moveToFirst();
    id_movil = movil.getString(1); 
    nombre = movil.getString(2);
    movil.close();
    db.close();

    // Iniciamos el servicio   

    cd = new ConnectionDetector(getApplicationContext());
    credential = new BasicAWSCredentials(MY_ACCESS_KEY_ID, MY_SECRET_KEY);


    if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }        

    this.iniciarServicio();
    Log.i(getClass().getSimpleName(), "Servicio iniciado");        
 }

public int onStartCommand (Intent intent, int flags, int startId) {

    try{
        id_movil=(String)intent.getExtras().get("id_movil");
        nombre=(String)intent.getExtras().get("nombre");
    }catch(NullPointerException e){
        db = varDb.getWritableDatabase();   
        movil = db.rawQuery("SELECT * FROM Movil",null); 
        movil.moveToFirst();
        id_movil = movil.getString(1);    
        movil.close();
        db.close();
    }  
    return START_STICKY;
}

public void onDestroy() {
    varDb.close();
    super.onDestroy();

    try{
        notificationManager.cancelAll();
    }catch (NullPointerException e){
        Log.e("noti",e+"");
    }catch (Exception e){
        Log.e("noti",e+"");
    }

    // Detenemos el servicio
    this.finalizarServicio();
    Log.i(getClass().getSimpleName(), "Servicio detenido");
}

public IBinder onBind(Intent intent){

    return null;
}

public void iniciarServicio() {

     try {
         Log.i(getClass().getSimpleName(), "Iniciando servicio...");

         // Creamos el timer
         this.timer=new Timer();

         // Configuramos lo que tiene que hacer
         this.timer.scheduleAtFixedRate(new TimerTask() {
             public void run() {
                 ejecutarTarea();
             }
         }, 0, 240000); // Cada 3 mins

         Log.i(getClass().getSimpleName(), "Temporizador iniciado");
     }
     catch(Exception e) {
         Log.i(getClass().getSimpleName(), e.getMessage());
     }
}

public void finalizarServicio() {

    try {
        Log.i(getClass().getSimpleName(), "Finalizando servicio...");

        // Detenemos el timer
        this.timer.cancel();

        Log.i(getClass().getSimpleName(), "Temporizador detenido");
    }
    catch(Exception e) {
        Log.i(getClass().getSimpleName(), e.getMessage());
    }        
}

private void ejecutarTarea() {
    Log.i(getClass().getSimpleName(), "Ejecutando tarea...");
    System.gc();
    System.runFinalization();
    Log.i(getClass().getSimpleName(), "Memoria liberada");

    Mostrar_badge();

    SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd");
    fecha = date.format(new Date());

    File archivo_log = new File(Environment.getExternalStorageDirectory() +"/logs/");
    logFile = id_movil+"_"+fecha+".txt";

    log = new File(archivo_log, logFile);

    if (!archivo_log.exists()) {
        archivo_log.mkdirs();
    }else if(!log.exists()){
        try {
            log.createNewFile();
        }catch(IOException e){
            Log.e("Error", ""+e);
        }
    }

    if (!cd.isConnectingToInternet()) {
        Log.e("Error", "No hay red");
        Mostrar_mensaje_red(0);
    }else{
        Log.i("Servicio", "hay red");
        Mostrar_mensaje_red(1);

        /*HERE I CHECK IF THERE IS DATA TO SYNC UP*/

        if(is text){
            /*CONSUMES A WEBSERVICE*/
        }else if (is foto){
            new Subida().execute(module, another value);
        }
}

private void Mostrar_badge() {

    int badgeCount = 0;

    try {

        /*CALCULATES HOW MUCH DATA IS AND SHOW A BADGE*/

        if (badgeCount == 0) {
            ShortcutBadger.with(getApplicationContext()).remove();
        } else {
            ShortcutBadger.with(getApplicationContext()).count(badgeCount);
        }
    }catch(IllegalStateException e){
        Log.e("Error Illegal", "" + e);
    }catch(NullPointerException e){
        Log.e("Error Null", "" + e);
    }catch (WhosebugError e) {
        //handle the Exception
        Log.e("Error Shorcut", "" + e);
    }
}

private void Mostrar_mensaje(){

    id = 2;
    ns = Context.NOTIFICATION_SERVICE;
    notificationManager = (NotificationManager) getSystemService(ns);

    CharSequence tickerText = "Sincronizando modulo "+modulo2;
    long when = System.currentTimeMillis();
    Context context = getApplicationContext();
    CharSequence contentTitle = "Sincronizando...";
    CharSequence contentText = "Modulo: "+modulo2;

    Notification checkin_notification = new Notification.Builder(context)
            .setTicker(tickerText)
            .setContentTitle(contentTitle)
            .setContentText(contentText)
            .setSmallIcon(R.drawable.noti_animation)
            .setWhen(when)
            .build();

        checkin_notification.flags = Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(id, checkin_notification);
}

private void Mostrar_mensaje_red(int stat){

    int id = 2;
    int icon;
    Notification checkin_notification;
    ns = Context.NOTIFICATION_SERVICE;
    notificationManager = (NotificationManager) getSystemService(ns);

    long when = System.currentTimeMillis();

    Context context = getApplicationContext();
    CharSequence contentTitle, contentText;
    contentTitle = "Estado conexión ";

    if(stat == 0){
        contentText = "no conectado";
        icon = R.drawable.no_rasp;
        Log.e("ServicioUpload", "no conectado");

    }else{
        contentText = "conectado";
        icon = R.drawable.si_rasp;
        Log.i("ServicioUpload", "conectado");

    }

    checkin_notification = new Notification.Builder(context)
            .setContentTitle(contentTitle)
            .setContentText(contentText)
            .setSmallIcon(icon)
            .setWhen(when)
            .build();

    checkin_notification.flags = Notification.FLAG_AUTO_CANCEL;
    notificationManager.notify(id, checkin_notification);
}
private class Subida extends AsyncTask<String, Void, Boolean>{
    private Boolean resul = true;
    private AmazonS3 s3;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        try {
            fecha_hora = date2.format(new Date());
            //BufferedWriter for performance, true to set append to file flag
            BufferedWriter buf = new BufferedWriter(new FileWriter(log, true));
            buf.append(fecha_hora+" inicio de envio de foto: "+foto);
            buf.newLine();
            buf.close();
        }catch (IOException e){
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    protected Boolean doInBackground(String... args) {
        s3 = new AmazonS3Client(credential);            //Metodos para TransferUtility
        transferUtility = new TransferUtility(s3, getApplicationContext());
        File stream = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/"+ foto);

        if(!stream.exists()) {
            resul = false;
        }

        modulo = args[0];
        otra_foto2 = args[1];

        observer = transferUtility.upload( Variables.existingBucketName, "fotos/"+foto, stream, CannedAccessControlList.PublicRead);
        Log.d("ServicioUpload", observer.getId() + " " + observer.getBytesTransferred()+ " " + observer.getState());
        observer.setTransferListener(new TransferListener() {
            @Override
            public void onStateChanged(int id, TransferState state) {
                Log.i("ServicioUpload", id+" State changed to : " + state.toString());
                if (state.COMPLETED.equals(observer.getState())) {
                    try {
                        fecha_hora = date2.format(new Date());
                        //BufferedWriter for performance, true to set append to file flag
                        BufferedWriter buf = new BufferedWriter(new FileWriter(log, true));
                        buf.append(fecha_hora+" Foto subida ok \n foto:"+foto);
                        buf.newLine();
                        buf.close();
                    }catch (IOException c){
                        // TODO Auto-generated catch block
                        c.printStackTrace();
                    }
                    resul = true;
                }else if(state.PAUSED.equals(observer.getState())){
                    transferUtility.resume(id);
                }else if(state.FAILED.equals(observer.getState()) || state.UNKNOWN.equals(observer.getState())){

                    try {
                        fecha_hora = date2.format(new Date());
                        //BufferedWriter for performance, true to set append to file flag
                        BufferedWriter buf = new BufferedWriter(new FileWriter(log, true));
                        buf.append(fecha_hora+" Foto subida "+observer.getState()+" \n foto:"+foto);
                        buf.newLine();
                        buf.close();
                    }catch (IOException c){
                        // TODO Auto-generated catch block
                        c.printStackTrace();
                    }

                    transferUtility.deleteTransferRecord(id);
                    resul = false;
                }
            }

            @Override
            public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) { }               //Metodos para TransferUtility

            @Override
            public void onError(int id, Exception ex) {
                Log.e("ServicioUpload", "Upload Unsuccessful due to " + ex.toString());
                try {
                    fecha_hora = date2.format(new Date());
                    //BufferedWriter for performance, true to set append to file flag
                    BufferedWriter buf = new BufferedWriter(new FileWriter(log, true));
                    buf.append(fecha_hora+" error de subir_foto: "+foto+" "+ex.toString());
                    buf.newLine();
                    buf.close();
                }catch (IOException ew){
                    // TODO Auto-generated catch block
                    ew.printStackTrace();
                }

                if(cd.isConnectingToInternet()){
                    transferUtility.cancel(id);

                }
                resul = false;
            }
        });

        return resul;
    }

    protected void onPostExecute(Boolean result) {
        if(resul){
            VALIDATE FILE ON THE WEB(USING A WEB SERVICE)
        }
    }
}
}

好的,我已经很久没有遇到这个问题了,但我已经找到了解决方案,就在这里:

  • transferUtility 观察者有一个 Listener 附加,并且有一个 onStateChanged 方法,用这个我可以检查上传的状态,在这里我更新了一个 变量 状态("IN_PROGRESS","FAILED","PAUSED", "COMPLETED", 等等).

  • 在我调用 AsyncTask 的部分我必须添加一个 While 检查 可变状态,所以在图片上传之前不会继续,代码如下所示。

    if(is text){
      /*CONSUMES A WEBSERVICE*/
    }else if (is foto){
       new Subida().execute(module, another value);
    
       while (estadoFoto.equals("") || estadoFoto.equals("IN_PROGRESS")) {
           if (!cd.isConnectingToInternet()) {
                    break;
           }
       }
    
       if (estadoFoto.equals("COMPLETED")) {
          /*VALIDATE PHOTO */
       }
    }
    

就是这样。