Android-Django Image upload

2019-03-19 06:02发布

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://

2条回答
叛逆
2楼-- · 2019-03-19 06:51

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.

http://stunningco.de/2010/04/25/uploading-files-to-http-server-using-post-android-sdk/, notice how he uses a unique boundary string, and writes it to the output stream?

You should start marking your questions as answered. You'll have much better success getting them answered when you do so.

查看更多
孤傲高冷的网名
3楼-- · 2019-03-19 06:52

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.)

查看更多
登录 后发表回答