2012-09-03 12 views
12

Estoy tratando de cargar un archivo de imagen a través del método http post desde el dispositivo Android al servidor de rieles. Pero publicar una imagen no funciona. Más específicamente, el parámetro de publicación (incluido el archivo de imagen) no parece enviarse correctamente.Cargando una imagen de Android (con Android Asynchronous Http Client) al servidor de rieles (con clip)

Estoy usando Android Asynchronous Http Client (http://loopj.com/android-async-http/) para publicar una imagen de android, y el código para publicar la imagen es así.

public static void postImage(){ 
    RequestParams params = new RequestParams(); 
    params.put("picture[name]","MyPictureName"); 
    params.put("picture[image]",File(Environment.getExternalStorageDirectory().getPath() + "/Pictures/CameraApp/test.jpg")); 
    AsyncHttpClient client = new AsyncHttpClient(); 
    client.post("http://x.x.x.x:3000/pictures/", params, new AsyncHttpResponseHandler() { 
     @Override 
     public void onSuccess(String response) { 
      Log.w("async", "success!!!!"); 
     }                                          
    }); 
} 

En cuanto a los carriles Paperclip aplicación, simplemente utilicé andamio y modelo generado nombrado "imágenes" y añadió archivo adjunto clip sobre él. El modelo y el controlador (que recibe la solicitud) son como a continuación.

modelo

class Picture < ActiveRecord::Base                                    
    attr_accessible :name, :image 
    has_attached_file :image, 
        :styles => { :original => "480x480>", :thumbnail => "100x100>" }, 
        :path => ':rails_root/public/system/pictures/image/:id_partition/:style_:filename' 
end 

controlador

# POST /pictures                                        
# POST /pictures.json 
def create 
    @picture = Picture.new(params[:picture]) 

    respond_to do |format| 
    if @picture.save 
     format.html { redirect_to @picture, notice: 'Picture was successfully created.' } 
     format.json { render json: @picture, status: :created, location: @picture } 
    else 
     format.html { render action: "new" } 
     format.json { render json: @picture.errors, status: :unprocessable_entity } 
    end 
    end 
end 

Al recibir la solicitud, "raíles del servidor" de la consola dice algo como siguiente

Started POST "/pictures/" for y.y.y.y at 2012-09-03 18:23:00 +0900 
Processing by PicturesController#create as HTML 
    Parameters: {"picture"=>{"name"=>"PictureName"}} 
    (0.1ms) begin transaction 
    SQL (0.5ms) INSERT INTO "pictures" ("album_id", "created_at", "image_content_type", "image_file_name", "image_file_size", "image_updated_at", "name", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) [["album_id", nil], ["created_at", Mon, 03 Sep 2012 09:23:00 UTC +00:00], ["image_content_type", nil], ["image_file_name", nil], ["image_file_size", nil], ["image_updated_at", nil], ["name", "PictureName"], ["updated_at", Mon, 03 Sep 2012 09:23:00 UTC +00:00], ["user_id", nil]] 
[paperclip] Saving attachments. 
    (11.0ms) commit transaction 
Redirected to http://x.x.x.x:3000/pictures/10                                
Completed 302 Found in 15ms (ActiveRecord: 11.6ms) 

Como se puede ver, sólo hay un parámetro de enviado y el parámetro "imagen [imagen]" que es datos de imagen en bruto no se recibe. ¿Alguien puede ayudarme?

+1

Gracias. Estaba buscando una pregunta similar. –

+0

Obtengo {"estado": "Error", "error": {"tipo_contenido_imagen": ["no es válido"], "imagen": ["no es válido"]}}. ¿Alguien tuvo este problema antes? –

Respuesta

12

Lo siento, ese fue mi tonto error. que debería haber hecho

params.put("picture[image]", new File(Environment.getExternalStorageDirectory().getPath() + "/Pictures/CameraApp/test.jpg")); 

no

params.put("picture[image]", File(Environment.getExternalStorageDirectory().getPath() + "/Pictures/CameraApp/test.jpg")); 

Deben usar nuevo archivo Archivo no

Al usar Android asíncrono cliente HTTP (http://loopj.com/android-async-http/), que no tenemos que preocuparse MultipartEntity. ¡Gracias a todos los que respondieron mi pregunta!

+0

Escribo el mismo código en mi aplicación, pero muchas veces el servidor me da error porque el tamaño de la imagen es grande. ¿Conoces alguna forma de enviar una imagen grande al servidor? –

1

Puede cargar las imágenes a través de MultipartEntity.

MultipartEntity, parte de HttpMime 4.0 y posterior. Le permite colocar varias partes, separadas por cadenas de límites y codificadas usando un conjunto de caracteres dado, en la solicitud de httppost.

Para obtener más información y cómo usar Multipart, vea thisy this.

+0

Consulte un enlace más que he agregado en mi respuesta. – Shrikant

+0

¡Muchas gracias por su respuesta! Ahora, entiendo el uso de MultipartEntity, al instanciar MultipartEntity y aplicar el método addPart en él, luego invocar el método setEntity a la instancia de HttpPost. Pero lo que estoy usando no es la clase HttpPost, sino la clase AsyncHttpClient. ¿Podría decirme cómo hacer lo mismo en AsyncHttpClient? – Ryo

+0

Ahhh ... lo siento, ¿sabes cómo hacer lo mismo (usar MultipartEntity) en AsyncHttpClient? – Ryo

0

Hay una descripción, como a continuación, en la página oficial de Android AsyncHttpClient (http://loopj.com/android-async-http/)

"la carga de archivos de varias partes que no tienen bibliotecas de terceros adicionales"

y en la sección de "Carga de archivos con RequestParams", tienen un código de ejemplo para cargar una imagen

File myFile = new File("/path/to/file.png"); 
RequestParams params = new RequestParams(); 
try { 
    params.put("profile_picture", myFile); 
} catch(FileNotFoundException e) {} 

Esto es lo que hice, pero no funcionó. ¿Esto ayuda a responder mi pregunta?

+1

hola Ryo, ¿ha obtenido la respuesta a su pregunta? –

Cuestiones relacionadas