This document was ed by and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this report form. Report r6l17
Overview 4q3b3c
& View Cómo Cargar Fotos En Una Aplicación Android Desde Cámara, Galería Y Otras Aplicaciones as PDF for free.
S (http://gpmess.com/blog/category/s/) CORPORATIVO (http://gpmess.com/blog/category/corporativo/) CLIENTES (http://gpmess.com/blog/category/clientes/) DESARROLLADORES (http://gpmess.com/blog/category/desarrolladores/)
Cómo cargar fotos en una aplicación Android desde cámara, galería y otras Santi Martínez aplicaciones (http://gpmess.com/blog/author/santi/) 02/10/13
COMUNIDAD DESARROLLADORES
Cuando en GPMESS decidimos que los yipis iban a tener foto, se me
presentó el reto de cargarlas (HTTP://GPMESS.COM/BLOG/CATEGORY/DESARROLLADORES/)
desde distintos medios del teléfono. A
priori, podemos querer cargar fotos en una aplicación Android desde la galería, sin embargo, para dar una experiencia más completa al , podemos querer que también se puedan hacer directamente desde la cámara o compartirse desde otra aplicación. Éste es el primero de una serie de varios artículos dónde trataremos el tema de las fotos, que si bien es sencillo, presenta en Internet una información muy desperdigada que puede llevarnos incluso a programar varios métodos para hacer lo que podríamos hacer con uno.
Primer paso: preparar el botón y la interfaz. Asumiendo que vuestro
layout tiene un botón al que llamaremos photoButton, preparamos nuestro activity o fragment para poder recibir la foto de todos los métodos posibles. En este caso tenemos una clase que se llama PhotoUtils en la que hemos encapsulado los métodos para tratar con las fotos 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
public class AddNewPhoto extends ActionBarActivity{
?
private AlertDialog _photoDialog private Uri mImageUri; private static final int ACTIVITY_SELECT_IMAGE = 1020, ACTIVITY_SELECT_FROM_CAMERA = 1040, ACTIVITY_SHARE = 10 private PhotoUtils photoUtils; private Button photoButton; private ImageView photoViewer; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_new); photoUtils = new PhotoUtils(this); // Get intent, action and MIME type Intent intent = getIntent(); String action = intent.getAction(); String type = intent.getType(); if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { fromShare = true; } else if (type.startsWith("image/")) { fromShare = true; mImageUri = (Uri) intent .getParcelableExtra(Intent.EXTRA_STREAM); getImage(mImageUri); } } photoButton = (Button) findViewById(R.id.photoButton); photoViewer = (ImageView) findViewById(R.id.photoViewer); getPhotoDialog(); setPhotoButton(); }
Vamos a empezar a analizar lo que está pasando aquí. En primer lugar, en el método onCreate creamos un objeto PhotoUtils y le pasamos el contexto, que será después necesario para otras operaciones. Seguidamente recuperamos el intent que ha lanzado este Activity para comprobar si nos han compartido texto (primera rama del if) o si es una foto( rama del else). Comprobamos que, en este último caso, hemos guardado el Uri, que es el objeto de Android donde tenemos una referencia de dónde se encuentra la imagen. Esto es muy importante porque será lo que finalmente utilicemos en los tres casos. Posteriormente llamamos al método getImage(mImageUri) que será el que recupere en este caso la foto, y que como es común a los tres casos, comentaremos posteriormente. Vemos que al final se llama al método getPhotoDialog(), el cual va a crearnos un Dialog para poder elegir entre Cámara o Galería si queremos añadir la
foto nosotros mismos (y no se nos ha compartido ninguna). Así pues, nosotros mismos desde el método setPhotoButton(), vamos a asignar este Dialog a nuestro botón para adjuntar la foto. 1 2 3 4 5 6 7 8
Vemos que se añade un listener a este botón que lo que hace es mostrar el diálogo de selección. El If que hemos añadido nos sirve para evitar que el Dialog pueda mostrarse dos veces, o hacerlo mientras nuestra Activity está terminando, lo cual podría provocar un cierre en nuestra app. Ahora vemos el Dialog 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
? private AlertDialog getPhotoDialog() { if (_photoDialog == null) { AlertDialog.Builder builder = new AlertDialog.Builder( AddNewActivity.this); builder.setTitle(R.string.photo_source); builder.setPositiveButton(R.string.camera, new OnClickL
@Override public void onClick(Diaterface dialog, int whi Intent intent = new Intent( "android.media.action.IMAGE_CAPTURE"); File photo = null; try { // place where to store camera taken pictur photo = PhotoUtils.createTemporaryFile("pic photo.delete(); } catch (Exception e) { Log.v(getClass().getSimpleName(), "Can't create file to take picture! } mImageUri = Uri.fromFile(photo); intent.putExtra(MediaStore.EXTRA_OUTPUT, mImage startActivityForResult(intent, ACTIVITY_SELECT_ } }); builder.setNegativeButton(R.string.gallery, new OnClick @Override public void onClick(Diaterface dialog, int whi Intent galleryIntent = new Intent(Intent.ACTION galleryIntent.setType("image/*"); startActivityForResult(galleryIntent, ACTIVITY_ } }); _photoDialog = builder.create(); } return _photoDialog; }
En este caso, el botón “negative” lanzará la galería, y el “positive” la cámara, vayamos por partes. Galería: 1 2 3 4 5 6 7
@Override public void onClick(Diaterface dialog, int which) { Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT); galleryIntent.setType("image/*"); startActivityForResult(galleryIntent, ACTIVITY_SELECT_IMAGE); }
?
Vemos que aquí simplemente se lanza un intent de tipo ACTION_GET_CONTENT al que le hemos indicado como tipo “image/*”. Esto hará que Android nos lance un diálogo de selección de qué fuente queremos la foto (galería, otras apps con imágenes, etc.). También le pasamos un entero que hemos definido al principio, ACTIVITY_SELECT_IMAGE, que nos ayudará a recoger luego el resultado usando el método onActivityResult (ya que llamamos al intent usando startActivityForResult en lugar de startActivity). Cámara: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
? @Override public void onClick(Diaterface dialog, int which) { Intent intent = new Intent( "android.media.action.IMAGE_CAPTURE"); File photo = null; try { // place where to store camera taken picture photo = PhotoUtils.createTemporaryFile("picture", ".jpg", A photo.delete(); } catch (Exception e) { Log.v(getClass().getSimpleName(), "Can't create file to take picture!"); } mImageUri = Uri.fromFile(photo); intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri); startActivityForResult(intent, ACTIVITY_SELECT_FROM_CAMERA);
}
La cámara es un poco más complicada. Circulan muchos ejemplos de cómo usarla, sin embargo, debido a la fragmentación y que los fabricantes usan sus distintas aplicaciones de cámara, éste es el único que me ha funcionado en todas las cámaras de distintos fabricantes. El truco está en crear un archivo temporal (photo) en el que guardar la fotografía que vamos a hacer. Después, guardamos la ruta de ese fichero en nuestro Uri mImageUri, y así cuando volvamos al método onActivityResult tendremos una Uri garantizada que, de otro modo, podría ser null dependiendo del fabricante de nuestro teléfono. Vemos que el intent que vamos a iniciar es
IMAGE_CAPTURE y le pasaremos el entero ACTIVITY_SELECT_FROM_CAMERA para luego poder controlarlo en onActivityResult(), también le pasamos el Uri para asegurarnos que la foto que hacemos acabe ahí. Aunque en el siguiente artículo veremos la clase PhotoUtils en detalle, os dejo aquí el método PhotoUtils.createTemporaryFile() por, si queréis, poder seguir todos los pasos hasta el momento. 1 2 3 4 5 6 7 8 9
Bien, debido a que en este caso estamos proporcionando nosotros el Uri, y queremos tenerla disponible, hay que asegurarse que al volver de la cámara, la seguimos teniendo disponible. Si estáis familiarizados con el ciclo de vida del activity en Android, sabréis (y si no ya os lo digo yo) que nuestra activity será puesta en pausa (onPause()) e incluso puede ser destruida (onDestroy()) mientras estamos en la actividad de la cámara, por lo que hay que utilizar los métodos onSavedInstaceState() y onRestoredInstanceState() para asegurarnos que, si eso pasa, tendremos el Uri disponible. Esto lo haremos guardando en el Bundle nuestra Uri: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Ahora ya tenemos asegurado nuestro Uri por las tres vías: – Si nos han compartido una imagen, lo hemos guardado en el método onCreate() y lo tendremos disponible. – Si hemos hecho la foto desde la cámara, lo hemos creado nosotros, y al igual que en el caso anterior, lo guardaremos siempre usando onSaved/onRestoredInstanceState. – Si cogemos la foto de la galería, lo recuperaremos en el método onActivityResult().
Bien, pues ya lo tenemos todo listo, así que ahora nos queda lo más difícil, recibir la foto desde la aplicación externa. Para esto usamos el método
onActivityResult(). 1 2 3 4 5 6 7 8 9 10 11
? @Override public void onActivityResult(int requestCode, int resultCode, Inten super.onActivityResult(requestCode, resultCode, data); if (requestCode == ACTIVITY_SELECT_IMAGE && resultCode == RESUL mImageUri = data.getData(); getImage(mImageUri); } else if (requestCode == ACTIVITY_SELECT_FROM_CAMERA && resultCode == RESULT_OK) { getImage(mImageUri); } }
Como se puede ver y tal como hemos comentado, en la rama del else ya tenemos el Uri nosotros guardado, por lo que simplemente llamados a getImage(mImageUri) y en el caso de la galería, lo recogemos del intent que ha reabierto nuestra Activity (data) usando data.getData(). Con esto, ya estamos listos para abrir y asignar la foto. Por ahí se encuentran muchos métodos para hacerlo, pero una vez más, este es el que mejor resultados ha dado, ya que sirve incluso para imágenes de Picasa que hay que descargar. 1 2 3 4 5 6 7 8 9
public void getImage(Uri uri) { Bitmap bounds = photoUtils.getImage(uri); if (bounds != null) { setImage(bounds); } else { showErrorToast(); }
?
}
y el método photoUtils.getImage(uri) es tal cual sigue: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
@Background public Bitmap getImage(Uri uri) { Bitmap result = null; BitmapFactory.Options options = new BitmapFactory.Options(); InputStream is = null; try { is = mContext.getContentResolver().openInputStream(uri); result = BitmapFactory.decodeStream(is, null, options); is.close();
Poco que resaltar aquí, aunque sí comentar que el método se basa en usar un InputStream, que cogerá la foto usando el Uri, y que si lo considera necesario, lo bajará de internet. Es muy importante por tanto que este método se ejecute en segundo plano. En nuestro caso,
utilizamos Android Annotations, lo cual nos permite usar el tag @Background para indicar que el método se ejecutará de dicho modo. Si no es vuestro caso, no tenéis más que utilizar este método en una AsyncTask y devolver el resultado en el método onPostExecute() utilizando una interfaz. Un esbozo sería algo así: Teniendo la interfaz: 1 2 3
Y esto sería equivalente al código anterior. Como podéis comprobar usando Android Annotations hemos ahorrado mucho código y rizar el rizo, pero eso ya será tema para otro post. Pues bien, ahora sólo nos queda, en cualquier caso, usar el método setImageBitmap(Bitmap bitmap) para añadir a nuestra vista, llamémosla photoViewer, nuestra foto recuperada en forma de bitmap. 1 2 3
Y voilá, se hizo la magia. En próximos episodios de esta serie de posts explicaré cómo cargar los bitmaps de modo eficiente para gastar poca memoria, y trataremos la clase PhotoUtils al completo. Espero que os sea útil y para cualquier cosa, ¡me tenéis en los comentarios! Como algunos me lo habéis pedido, adjunto la clase PhotoUtils completa: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
public class PhotoUtils { private static Context mContext; private Options generalOptions;
?
public PhotoUtils(Context context) { mContext = context; } public static File createTemporaryFile(String part, String ext, Context myContext) throws Exception { String path = myContext.getExternalCacheDir().getAbsolutePa + "/temp/"; File tempDir = new File(path); if (!tempDir.exists()) { tempDir.mkdir(); } return File.createTempFile(part, ext, tempDir); } public Bitmap getImage(Uri uri) { BitmapFactory.Options options = new BitmapFactory.Options() options.inJustDecodeBounds = true; InputStream is = null; try { is = mContext.getContentResolver().openInputStream(uri) BitmapFactory.decodeStream(is, null, options); is.close();
△ ▽ • Responder • Compartir › Santiago Orozs • hace 2 años
Buenas noches, Muy buen tutorial, pero podías por favor compartir el código, para saber que tengo mal o poder corre este ejemplo y hacer el paso a paso, de verdad seria de una gran utilidad y ayuda para mas de uno.
△ ▽ • Responder • Compartir › carolina • hace 3 años
Hola ! , espero que no haya llegado tarde y se me pueda contestar a dudas. He realizado el código que nos ha sproporcionao, pero me da error el R.string.camera , y el R.string.photo_source.. intento crearme esas variables en las opciones que me da Eclipse, pero ni aun con esas consigo quitar el error. Tengo desde la versión 2.2 hasta la 5.1 de android instaladas.. ¿ cuál podría ser el fallo? Gracias !
△ ▽ • Responder • Compartir › Jaiver Andres Ocampo Oviedo > carolina • hace 8 meses
Hola!, muy buen tutorial me a servido muchisimo, y funciona muy bien salvo un detalle, que lo expongo por si alguien puede ayudarme. Cuando has cargado una iamgen desde la galeria, y después cargar una imagen desde la cámara, la imagne previa que tenias de la galeria, se sustituye por la de la cámara, y a mi me gustaría que se creara un nuevo .jpg y lo almacenara en dicho archivo, nose si me he explicado bien jajaj. Un saludo!
△ ▽ • Responder • Compartir ›
Artick • hace 3 años
Se que ya hace algún tiempo que se publicó este artículo, pero me parece muy bueno y realmente necesito ayuda pq me da muchos fallos. Aún pueden ayudarme o se cerró el tema?
△ ▽ • Responder • Compartir › Na0z > Artick • hace 3 años
que fallos tienes??
△ ▽ • Responder • Compartir › Cueto re-cabron • hace 3 años
Gran metodo y gran explicacion, yo tenia este problema con mi aplicacion al cargar 5 fotos, redimensionaba pero aun asi tenia que cargar el mapbit para hacer todo el redimensionamiento
△ ▽ • Responder • Compartir › Edna • hace 3 años
Buenas tardes, se me hace muy completa esta aplicación pero yo sólo requiero la parte donde le doy click en el botón "adjuntar imagen" y me abra el explorador de archivos y asi seleccionar la imagen, para luego adjuntarla a un email y enviar, trato de seleccionar el código que le corresponde a esa parte pero no me funciona, tendrá alguna aplicación que sólo haga eso? se lo agradecería mucho, gracias, saludos!
△ ▽ • Responder • Compartir › Sergikito • hace 3 años
Hey, hola. Llevo dos días pegándome con esto, y la verdad es que no entiendo cómo funciona. Soy nuevo en Android, por lo que estoy aprendiendo. Pero no consigo hacer funcionar esta aplicación, y es porque no sé si soy demasiado novato como para ponerme a programar este tipo de cosas, o que se me escapa algo. Primero: ¿Qué son "R.string.photo_source", "R.string.camera" y "R.string.camera"? ¿Tengo que añadirlos manualmente el el fichero strings aunque no ponga nada destacable? Evidentemente si digo esto es porque me da error, diciendo "cannot be resolved or it is not a field" Segundo: Al hacer builder.setNegativeButton (y con el positive igual), el OnClickListener me da el error: "The type new View.OnClickListener(){} must implement the inherited abstract method View.OnClickListener.onClick(View)". Imagino que esto es porque no hay ningún método OnClick, pero... ¿cómo soluciono esto y qué debería añadir? Porque dentro del método ese veo como hay un OnClick ver más
△ ▽ • Responder • Compartir › Aszur > Sergikito • hace 3 años
Buff, deberias leerte antes un poco como funciona android para ver estos tutoriales... R
d
C
ti
△ ▽ • Responder • Compartir › Phillip • hace 3 años
△ ▽ • Responder • Compartir › Miguel • hace 4 años
Hola, cuando corro el ejemplo funciona bien con la galería pero la opción de cámara no. Sucede que en photo = PhotoUtils.createTemporaryFile("picture", ".jpg", AddNewPhoto.this) lanza excepción y por tanto photo queda null. Seria de gran ayuda si alguien me puede indicar como solucionar el error. ( La clase PhotoUtil la tengo igual como la que está adjunta ). El código lo tengo así, totalmente idéntico: private AlertDialog getPhotoDialog() { if (_photoDialog == null) { AlertDialog.Builder builder = new AlertDialog.Builder( AddNewPhoto.this); builder.setTitle(R.string.photo_source); builder.setPositiveButton(R.string.camera, new Diaterface.OnClickListener() { ver más
△ ▽ • Responder • Compartir › Santiago J. Martínez > Miguel • hace 4 años
Hola Miguel. No puedo saber mucho más sin conocer la excepción, pero asegúrate que tienes añadidos en tu manifest los permisos WRITE_EXTERNAL_STORAGE y WRITE_INTERNAL_STORAGE para poder escribir en disco, de otro modo no podrás guardar el archivo y es una posible causa de error. Saludos.
△ ▽ • Responder • Compartir › Claudio Gino • hace 4 años
Hola, para correr tu ejemplo, el AlertDialog va en el Activity principal o se tiene l l d d l t
que crear en una nueva clase, porque me surge la duda en la parte que utilizas como parametro AddNewActivity.this Otra duda es si fromShare lo declaras como una variable booleana. Saludos
△ ▽ • Responder • Compartir › Santiago J. Martínez > Claudio Gino • hace 4 años
Hola Claudio. Efectivamente el método que crea el AlertDialog está en el mismo Activity, lo de AddNewActivity.this se puede sustituir por this en este caso (probablemente copie código dónde tenia eso en una clase interna, pero aquí no es el caso) no cuando estás dentro del setPositiveButton, ya que ahí estás declarando una clase abstracta y si necesitas referenciar a la clase externa. En cuanto a fromShare, efectivamente es un booleano. Saludos.
△ ▽ • Responder • Compartir › Claudio Gino > Santiago J. Martínez • hace 4 años
Gracias Santiago, me ha sido muy útil toda la información. Una consulta mas, dentro del método getImage(Uri uri) creas un objeto Bitmap. Tienes ahi 2 metodos el showErrorToast() donde estoy enviando un mensaje, pero no está definido el metodo setImage(bounds) por lo que en lugar de éste, mande llamar el método setImageBitmap. El punto es que corre la aplicación y si se captura una imagen con la camara si se muestra en el ImageView, pero si se captura una segunda foto el showErrorToast me notifica ya no se carga en el ImageView.
△ ▽ • Responder • Compartir › Santiago J. Martínez > Claudio Gino • hace 4 años
Hola Claudio. Posiblemente el error se deba a que cuando cargas la primera foto, el archivo temporal se bloquea y no puedes recuperar la segunda imagen y guardarla usando el mismo Uri. Prueba a cambiar el Uri cuando haces una segunda foto y a ver que tal.
△ ▽ • Responder • Compartir › Javier • hace 4 años
He intentado implementar tu ejemplo pero conforme voy avanzando suergen mas errores, necesito un ejemplo de como cargar una imagen desde galeria o una foto, no se si puedas ayudarme, seria de gran ayuda
△ ▽ • Responder • Compartir › Santiago J. Martínez > Javier • hace 4 años
Hola Javier. Si me pudieses contar más sobre que errores tienes, podemos intentar ver dónde está el problema :)
Saludos.
△ ▽ • Responder • Compartir › javier > Santiago J. Martínez • hace 4 años
Ya lo pude solucionar, gracias me gustaria saber si no tienes un ejemplo de esto mismo pero cargar varias imagenes en ves de una Saludos y gracias..
△ ▽ • Responder • Compartir › Kauky • hace 4 años
Hola vale muchas gracias por el codigo, funciono espectacularmente, de verdad excelente, pero tengo una duda pues en mi aplicacion tengo muchos FragmentActivity y no Activity solo uno si acaso, asi que pues intente este codigo por los FragmentActivity y pues no me hace nada, simplemente no ejecuta la seleccion de la galeria, que podria hacer en este caso?????
△ ▽ • Responder • Compartir › Santiago J. Martínez > Kauky • hace 4 años
Hola Kauky. ActionBarActivity extiende de FragmentActivity por lo que debería funcionar sin problema también en un FragmentActivity. Comprueba que llamas al método getImage de la clase PhotoUtils desde background y que en el método onActivityResult estas comprobando correctamente el entero correspondiente el que has lanzado el intent. Saludos.
△ ▽ • Responder • Compartir › emiliano • hace 4 años
Hola, muchas gracias por este codigo, el esfuerzo que has empeñado y el tiempo dedicado, me ha funcionado a la perfeccion. Mi duda reside en si es posible hacer una clase aparte, para implementarlo en diferentes fragments o activitys y no agregar codigo adicional, gracias y muy bueno!
△ ▽ • Responder • Compartir › Santiago J. Martínez > emiliano • hace 4 años
Hola emiliano. Todo lo que es la clase PhotoUtils si que lo puedes tener en una clase aparte. Por desgracia todo el tema de onActivityResult o onSavedInstancedState tiene que estar en el Activity si o si. Si no quieres tener que repetir este código, existe un truco: Create un Activity que se llame BaseActivity dónde incluyes este código. Luego, haz que tus Activity extiendan a BaseActivity (en lugar de Activity o FragmentActivity) y así ya tendrás el código incluido en ellos. Lo mismo es valido para los Fragments. Saludos.
△ ▽ • Responder • Compartir ›
Faustino • hace 4 años
Hola Santiago, Estoy intentando utilizar esto, pero tengo bastantes errores. Entre ellos, "_photoDialog" y no tengo claro que hay que poner en actionBarActivity. Te agradeceria un poco de ayuda. (PhotoUtils lo tengo bien hecho y se importa).
△ ▽ • Responder • Compartir › Santiago J. Martínez > Faustino • hace 4 años
Hola Faustino. Siento la tardanza en responder. _photoDialog es un AlertDialog, por lo que tendrías que añadir en las variables de la clase: private AlertDialog _photoDialog; En cuanto a ActionBarActivity, esta es la Activity que se usa para la retrocompatibilidad del ActionBar con versiones antiguas de Android. Si no estás usando esto, puedes cambiarla por "Activity" o "FragmentActivity". Si quieres utilizar "ActionBarActivity", echa un vistazo por los post de desarrolladores, ya que hay un articulo dedicado a ello :) Saludos.
△ ▽ • Responder • Compartir › kasuky > Santiago J. Martínez • hace 4 años
justamente de esto estaba hablando no me ejecuta nada con FragmentActivity
△ ▽ • Responder • Compartir › Victor • hace 4 años
Hola buenas, me gustaría ponerme en o contigo sobre este tema, ya que lo estoy intentando usar en un proyecto en mi universidad pero no veo la forma de encontrar la clase PhotoUtils, si pudieras decirme como ponerme en o contigo te lo agradeceria
△ ▽ • Responder • Compartir › Santiago J. Martínez > Victor • hace 4 años
Hola Victor La clase photoUtils no existe en el SDK de Android, es una clase que programé yo, y en este post tienes todos los métodos necesarios para montarla. Lo unico que tienes que hacer, es crear una nueva clase, llamarla PhotoUtils y copiar el código que tienes aquí. De todos modos para que te resulte más facil, te pego todo el código completo en pastebin.
Entras aquí: http://pastebin.com/p7dew1rr y puedes hacer copiar y pegar. Luego de eso ya deberías poder importar la clase PhotoUtils en cualquier clase de tu aplicación. Si necesitas cualquier cosa más no dudes en preguntar. Saludos
△ ▽ • Responder • Compartir › Abraham > Santiago J. Martínez • hace 4 años
Hola, el enlace esta caído, ¿puedes volver a subirlo? No termino de ver la clase PhotoUtils Un saludo.
△ ▽ • Responder • Compartir › Santiago J. Martínez > Abraham • hace 4 años
Related Documents 171j1w
Imprimir Varias Fotos En Una Hoja 3fo6z
November 2019 34
Cargar Isos Desde Disco Duro Externo Con Rgh En X360 2ho2l
June 2021 0
Para Cargar Folios En Febos Y Sap.docx 5w3860
February 2023 0
Cargar Alumnos En Sage 1k6x30
June 2022 0
Vista Desde Una Acera 2u465c
September 2021 0
Vender Fotos En Internet 4m6l1a
December 2019 39
More Documents from "Jorge Soler" 4a2e6q
2c82t
June 2021 0
Dieta Crash 6u41s
August 2021 0
33 Grado Sob Gran Inspector 255q3x
October 2021 0
Charles Bettelheim Revolucion Cultural Y Organizacion Industrial En China 5j4c6a