Using AWS TransferUtility on a service

344 views Asked by At

I need your help with something, I'm making an Android App report some information(text and images), I use a Service to synchronize the data, when comes to the image, I was using the TransferManager method, it was working well for most of the times, know this method is deprecated so I moved out to TransferUtility method, is also working well but I noticed that the Activity is freezing when this method is running, I don't know what to do.

ps: I included the method on an async task, but the problem persists.

Thanks for the help.

the code I have of the service is the next one:

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 (StackOverflowError 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)
        }
    }
}
}
1

There are 1 answers

0
Alejandro_rios On BEST ANSWER

Ok, it's been a long since i have this issue, but i already find the solution, here is it:

  • the transferUtility observer has a Listener attach, and has a onStateChanged method, with this i can check the status of the upload, here i update a variable status("IN_PROGRESS", "FAILED", "PAUSED", "COMPLETED", etc).

  • In the part where i call the AsyncTask i have to add a While that check the Variable status, so it will not go on until the image is uploaded, the code will look like this.

    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 */
       }
    }
    

and that's it.