Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android-Django Image upload

I am trying to upload image with android as frontend and django as backend.

The model:

    class Photo(models.Model):
        title = models.CharField(max_length=255,blank=True)
        photo = models.FileField(upload_to='photos')
        description = models.TextField(blank=True)
        uploaded = models.DateTimeField(auto_now_add=True)
        modified = models.DateTimeField(auto_now=True)

        class Meta:
            db_table = 'media_photos'

        def __unicode__(self):
            return '%s' % self.title

The view to url url(r'^photos/upload/$','upload_photo'):

def upload_photo(request):
form=PhotoForm(request.POST,request.FILES)
if request.method=='POST':
    if form.is_valid():
        image = request.FILES['photo']
        title1 =''
        new_image = Photo(title=title1,photo=image,description='')
        new_image.save()
        response_data=[{"success": "1"}]
        return HttpResponse(simplejson.dumps(response_data), mimetype='application/json')

now i am trying to access the view here from android. So now my android side code to upload image is:

     public void doFileUpload(String path){
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream inStream = null;
        String lineEnd = "\r\n";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1*1024*1024;
        String urlString = "http://";   // server ip
        try
        {
         //------------------ CLIENT REQUEST
        FileInputStream fileInputStream = new FileInputStream(new File(path) );
         // open a URL connection to the Servlet
         URL url = new URL(urlString);
         // Open a HTTP connection to the URL
         conn = (HttpURLConnection) url.openConnection();
         // Allow Inputs
         conn.setDoInput(true);
         // Allow Outputs
         conn.setDoOutput(true);
         // Don't use a cached copy.
         conn.setUseCaches(false);
         // Use a post method.
         conn.setRequestMethod("POST");
         conn.setRequestProperty("Connection", "Keep-Alive");
         conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+"    ");
         dos = new DataOutputStream( conn.getOutputStream() );
         dos.writeBytes(lineEnd);
         dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + path + "\"" + lineEnd);
         dos.writeBytes(lineEnd);

         // create a buffer of maximum size
         bytesAvailable = fileInputStream.available();
         bufferSize = Math.min(bytesAvailable, maxBufferSize);
         buffer = new byte[bufferSize];

         // read file and write it into form...
         bytesRead = fileInputStream.read(buffer, 0, bufferSize);
         while (bytesRead > 0)
         {
          dos.write(buffer, 0, bufferSize);
          bytesAvailable = fileInputStream.available();
          bufferSize = Math.min(bytesAvailable, maxBufferSize);
          bytesRead = fileInputStream.read(buffer, 0, bufferSize);
         }

         // send multipart form data necesssary after file data...
         dos.writeBytes(lineEnd);
         dos.writeBytes(lineEnd);

         // close streams
         Log.e("Debug","File is written");
         fileInputStream.close();
         dos.flush();
         dos.close();
        }
        catch (MalformedURLException ex)
        {
             Log.e("Debug", "error: " + ex.getMessage(), ex);
        }
        catch (IOException ioe)
        {
             Log.e("Debug", "error: " + ioe.getMessage(), ioe);
        }

        //------------------ read the SERVER RESPONSE
        try {
              inStream = new DataInputStream ( conn.getInputStream() );
              String str;
              while (( str = inStream.readLine()) != null)
              {
                   Log.e("Debug","Server Response "+str);
              }
              inStream.close();
        }
        catch (IOException ioex){
             Log.e("Debug", "error: " + ioex.getMessage(), ioex);
        }
      }
}

but it gives me an error:

E/Debug(590): error: java.net.URISyntaxException: Authority expected at index 7: http://
like image 393
user1163236 Avatar asked Mar 18 '12 14:03

user1163236


2 Answers

Should be urlString = "http://192.168.1.2/photos/upload";

But then if it doesn't work, you'll get a different error, and we'll probably need that error to answer further.

Also, it looks like you don't have a real boundary string set and you aren't using it correctly.

Have a look here. Notice how he uses a unique boundary string and writes it to the output stream?

like image 123
synic Avatar answered Nov 08 '22 20:11

synic


Even after you overcome these difficulties, you'll run afoul of Django's requirement that you supply a csrfmiddlewaretoken with your POST parameters. And I don't see how you can obtain that on an Android device; by design that token is there to prevent calling Django backend code (i.e. a "view") from anything other than a Django frontend (i.e. a "template"). I.e. it's designed to thwart doing exactly what you're trying to do.

You could disable the csrf feature on a particular view -- use the "@csrf_exempt" decorator. And then you can decide if you care enough about security, to work out a substitute of your own for what the csrf thing gives you.

Or, instead of uploading a picture from an Android app, write a web app to upload a picture, and have your Django project serve up that web app. Your Android app could launch the browser (as an Intent) and point it at that web app. Here's some code that'll do that: https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html (It won't win any beauty contests, but it does work.)

like image 42
Theodore Sternberg Avatar answered Nov 08 '22 19:11

Theodore Sternberg