Search code examples
getstream-io

How to upload file to Stream.io for activity posts and profile pictures


I'm currently working on a community feature in my android app and I'm using the java CloudClient which has been working well. However I'm running into a roadblock when it comes to uploading images to Stream.io. I'm attempting to have the user upload pictures to their gallery in their phones and have them be uploaded. Below is the gallery access code. (written in Kotlin)

private fun openGalleryForImage() {
        val intent = Intent(Intent.ACTION_PICK)
        intent.type = "image/*"
        startActivityForResult(intent, REQUEST_CODE)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE){
            postImageIV.setImageURI(data?.data) // handle chosen image
            image = data?.data //image is the Uri
        }
    }

After getting the data I then attempt to upload the image using the following code (written in Java)

private static URL uploadImage(Uri imageUri) throws StreamException, MalformedURLException {
       CloudClient client = CloudClient.builder(apiKey, token, userID).build();

       String path = imageUri.getPath();
       File imageFile = new File(path).getAbsoluteFile();
       URL imageURL = null;

       try {
            imageURL = client.images().upload(imageFile).join();
       }catch(Exception M){
           Exception error = M;
           System.out.print(error);
       }
       return imageURL;
   }

Though when I run this section client.images().upload(imageFile).join(); it comes back with "No file to upload" which I believe is a result of the following code in CloudClient's upload method:

checkArgument(imageFile.exists(), "No file to upload");

Am I going about uploading images to Stream.io in the wrong way?


Solution

  • The problem is that you are not passing a valid file path. I have created a library that will return a valid file path for a Uri that was returned from MediaStore. First, implement the library (there is instructions in the "ReadMe") and then return to this answer.

    You would do the same as you have, with some minor changes. In onActivityResult, do the following (It's written in Java, but you can easily changed):

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE){
            postImageIV.setImageURI(data.getData());
    
            //Pass the Uri to the library
            pickiT.getPath(data.getData(), Build.VERSION.SDK_INT);
        }
    }
    

    Then in PickiTonCompleteListener, pass the path to the method you have in your question, like this:

    @Override
    public void PickiTonCompleteListener(String path, boolean wasDriveFile, boolean wasUnknownProvider, boolean wasSuccessful, String reason) {
        if(wasSuccessful){
            //use path to call your uploadImage method
            URL yourUrl = uploadImage(path);
        }
    }
    
    //I changed your method so you can pass the path returned from PickiTonCompleteListener
    private static URL uploadImage(String filePath) throws StreamException, MalformedURLException {
        CloudClient client = CloudClient.builder(apiKey, token, userID).build();
        File imageFile = new File(filePath);
        URL imageURL = null;
        try {
            imageURL = client.images().upload(imageFile).join();
        }catch(Exception M){
            Exception error = M;
            System.out.print(error);
        }
        return imageURL;
    }