Android app crashes when trying to upload audio to Parse.com

Hi this is my first post here & I desperately need help with this problem. Whenever I upload just the image it works fine, but as soon as I try to upload an audio file my app crashes and the logcat shows no error or anything. Can someone please help me. (I am aware of the fact that the file size is limited to 10 MB per file and I've made sure that my audio file is smaller than that.) Thank you in advance.

private static final int SELECT_AUDIO = 1;
private Uri audioUri;
String selectedPath = "";
File audio;
private static final int PICK_FROM_FILE = 2;
Button btn_choose_image;
Bitmap bitmap;
private Uri imageCaptureUri;
private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload_podcast);

        imageView = (ImageView) findViewById(R.id.pART);
        btn_choose_image = (Button) findViewById(R.id.GALLERY);
        btn_choose_image.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);
            }
        });

        TextView textView = (TextView) findViewById(R.id.pARTIST);
        textView.setText(MainActivity.NAME);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK)

            return;
        bitmap = null;
        String path = "";
        if (requestCode == PICK_FROM_FILE) {

            imageCaptureUri = data.getData();
            try {

                bitmap = getBitmapFromUri(imageCaptureUri);
            } catch (IOException e) {

                e.printStackTrace();
            }
            imageView.setImageBitmap(bitmap);
        }
        else if (requestCode == SELECT_AUDIO) {

            try {

                audioUri = data.getData();
                audio = new File(audioUri.getPath());
                } catch (Exception e) {

                e.printStackTrace();
            }
        }
    }

    private Bitmap getBitmapFromUri(Uri uri) throws IOException {

        ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return bitmap;
    }

    //TODO: Upload audio files
    public void uploadAudio(View view) {

        Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(galleryIntent, SELECT_AUDIO);
    }

    public void uploadAll(View view) {

        //Toast.makeText(UploadPodcast.this, "Uploaded", Toast.LENGTH_LONG).show();
        EditText editText = (EditText) findViewById(R.id.pName);
        ParseObject podcast = new ParseObject("Podcast");
        uploadImageToParse(bitmap, podcast, "albumArt");
        finish();
    }
    private ParseObject uploadAudioToParse(File audioFile, ParseObject po, String columnName){

        if(audioFile != null){

            Log.d("EB", "audioFile is not NULL: " + audioFile.toString());
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            BufferedInputStream in = null;
            try {

                in = new BufferedInputStream(new FileInputStream(audioFile));
            } catch (FileNotFoundException e) {

                e.printStackTrace();
            }
            int read;
            byte[] buff = new byte[1024];
            try {

                while ((read = in.read(buff)) > 0)
                {

                    out.write(buff, 0, read);
                }
            } catch (IOException e) {

                e.printStackTrace();
            }
            try {

                out.flush();
            } catch (IOException e) {

                e.printStackTrace();
            }
            byte[] audioBytes = out.toByteArray();

            // Create the ParseFile
            ParseFile file = new ParseFile(audioFile.getName() , audioBytes);
            po.put(columnName, file);

            // Upload the file into Parse Cloud
            file.saveInBackground();
            po.saveInBackground();
        }
        return po;
    }
    private void uploadImageToParse(Bitmap bitmap, ParseObject po, String columnName) {

        // Convert it to byte
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        // Compress image to lower quality scale 1 - 100
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] image = stream.toByteArray();

        // Create the ParseFile
        ParseFile file = new ParseFile("podcastArt.png", image);
        // Upload the image into Parse Cloud
        file.saveInBackground();

        // Create a column named "ImageFile" and insert the image
        po.put("albumArt", file);

        // Create the class and the columns
        po.saveInBackground();

        // Show a simple toast message
        Toast.makeText(UploadPodcast.this, "Image Uploaded", Toast.LENGTH_SHORT).show();
    }

I don't even call the function uploadAudioToParse() but still if I select an audio file, the app crashes when I call uploadAll(). The app works fine if I just select an image but not the audio file. (P.S. - I have different buttons for selecting image and audio file & I also want to upload them both to the same tuple in my Parse database.)


EDIT: Here's the logcat

11-30 01:54:21.586 16550-16550/sas.unplug W/System.err: java.io.FileNotFoundException: /external/audio/media/124081: open failed: ENOENT (No such file or directory) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: at libcore.io.IoBridge.open(IoBridge.java:452) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: at java.io.FileInputStream.(FileInputStream.java:76) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: at sas.unplug.UploadPodcast.uploadAudioToParse(UploadPodcast.java:138) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: at sas.unplug.UploadPodcast.uploadAll(UploadPodcast.java:128) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: at java.lang.reflect.Method.invoke(Native Method) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at android.view.View.performClick(View.java:5198) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at android.view.View$PerformClick.run(View.java:21147) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at android.os.Handler.handleCallback(Handler.java:739) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at android.os.Looper.loop(Looper.java:148) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at java.lang.reflect.Method.invoke(Native Method) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory) 11-30 01:54:21.596 16550-16550/sas.unplug W/System.err: at libcore.io.Posix.open(Native Method) 11-30 01:54:21.596 16550-16550/sas.unplug W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) 11-30 01:54:21.596 16550-16550/sas.unplug W/System.err: at libcore.io.IoBridge.open(IoBridge.java:438) 11-30 01:54:21.596 16550-16550/sas.unplug W/System.err: ... 14 more 11-30 01:54:21.597 16550-16550/sas.unplug D/AndroidRuntime: Shutting down VM 11-30 01:54:21.598 16550-16550/sas.unplug E/AndroidRuntime: FATAL EXCEPTION: main Process: sas.unplug, PID: 16550 java.lang.IllegalStateException: Could not execute method for android:onClick at android.view.View$DeclaredOnClickListener.onClick(View.java:4452) at android.view.View.performClick(View.java:5198) at android.view.View$PerformClick.run(View.java:21147) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) at android.view.View.performClick(View.java:5198)  at android.view.View$PerformClick.run(View.java:21147)  at android.os.Handler.handleCallback(Handler.java:739)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5417)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.BufferedInputStream.read(byte[])' on a null object reference at sas.unplug.UploadPodcast.uploadAudioToParse(UploadPodcast.java:145) at sas.unplug.UploadPodcast.uploadAll(UploadPodcast.java:128) at java.lang.reflect.Method.invoke(Native Method)  at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)  at android.view.View.performClick(View.java:5198)  at android.view.View$PerformClick.run(View.java:21147)  at android.os.Handler.handleCallback(Handler.java:739)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5417)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)  11-30 01:54:21.601 779-2167/? W/ActivityManager: Force finishing activity sas.unplug/.UploadPodcast 11-30 01:54:21.623 779-17380/? W/DropBoxManagerService: Dropping: data_app_crash (1300 > 0 bytes) 11-30 01:54:21.668 779-11434/? I/OpenGLRenderer: Initialized EGL, version 1.4 11-30 01:54:22.106 779-792/? W/ActivityManager: Activity pause timeout for ActivityRecord{8337fab u0 sas.unplug/.UploadPodcast t4229 f} 11-30 01:54:22.533 13913-13982/? I/cm.log.servpro: [isProcessInCache RESCAN_DURATION: ][D]/ 1448828662529 11-30 01:54:22.536 13913-13982/? I/cm.log.servpro: [isProcessInCache RESCAN_DURATION: ][D]/ 1448828662533 11-30 01:54:22.538 13913-13982/? D/AutostartService: set fg pkgname:sas.unplug 11-30 01:54:31.606 779-792/? W/ActivityManager: Launch timeout has expired, giving up wake lock! 11-30 01:54:34.494 16550-16550/sas.unplug I/Process: Sending signal. PID: 16550 SIG: 9 11-30 01:54:34.507 779-11434/? E/Surface: getSlotFromBufferLocked: unknown buffer: 0x995cf840 11-30 01:54:34.547 779-790/? D/GraphicsStats: Buffer count: 8 11-30 01:54:34.547 779-790/? I/WindowState: WIN DEATH: Window{2cb7a31 u0 sas.unplug/sas.unplug.MainActivity} 11-30 01:54:34.551 779-2188/? I/WindowState: WIN DEATH: Window{6286b87 u0 sas.unplug/sas.unplug.UploadPodcast} 11-30 01:54:34.596 779-950/? I/ActivityManager: Process sas.unplug (pid 16550) has died


Here's the layout xml file for the above activity.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/background_floating_material_dark"
     android:fitsSystemWindows="true"
     tools:context="sas.unplug.UploadPodcast">

     <EditText
         android:id="@+id/pName"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         android:layout_centerHorizontal="true"
         android:layout_marginLeft="16dp"
         android:layout_marginRight="16dp"
         android:layout_marginTop="16dp"
         android:hint="Podcast Name"
         android:textColor="#64ffffff"
         android:textColorHint="#64ffffff"
         android:textSize="20sp" />

     <TextView
         android:id="@+id/by"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_below="@+id/pName"
         android:layout_marginLeft="20dp"
         android:layout_marginTop="10dp"
         android:text="by"
         android:textColor="#ff5252"
         android:textSize="14sp" />

     <TextView
         android:id="@+id/pARTIST"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignTop="@+id/by"
         android:layout_toRightOf="@+id/by"
         android:paddingLeft="16dp"
         android:text="Artist"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="#64ffffff" />

     <ImageView
         android:id="@+id/pART"
         android:layout_width="match_parent"
         android:layout_height="250dp"
         android:layout_alignParentStart="true"
         android:layout_below="@+id/GALLERY"
         android:scaleType="centerCrop"
         android:src="@drawable/zghost" />

     <Button
         android:id="@+id/GALLERY"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentEnd="true"
         android:layout_below="@+id/pARTIST"
         android:layout_marginRight="20dp"
         android:layout_marginTop="10dp"
         android:background="?android:attr/selectableItemBackground"
         android:text="Choose image from gallery"
         android:textColor="#ffffff" />

     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_below="@+id/pART"
         android:layout_marginTop="25dp"
         android:gravity="center">

         <Button
             android:id="@+id/pSELECT"
             android:layout_width="150dp"
             android:layout_height="wrap_content"
             android:layout_marginRight="10dp"
             android:background="?android:attr/selectableItemBackground"
             android:onClick="uploadAudio"
             android:text="Select podcast"
             android:textColor="#ffffff" />

         <Button
             android:layout_width="150dp"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dp"
             android:onClick="uploadAll"
             android:text="Upload podcast" />
     </LinearLayout>
</RelativeLayout>

Answers


I think you problem is with handling async actions

// Upload the file into Parse Cloud
file.saveInBackground();
po.saveInBackground();

You start saving the file but before the first bytes have been sent, you save po. With the association made between file and po, your save fails because your file have not yet been handed an id, as it is not yet saved.

Ok dont know how clear my explanation was, but here is a solution that should work:

file.saveInBackground(new SaveCallback() {
    @Override
    public void done(ParseException e) {
        if (e != null) {
            Log.e(TAG, "file upload failed", e);
        } else {
            // now parse knows that file exists and is able to 
            // to make the association with your po object
            po.saveInBackground();
        }
    }
});

Now you also get an error log if the file upload fails.

The file upload also has a progress callback in case you wish to present a dialog with some information of how far the upload is from completion https://parse.com/docs/android/api/com/parse/ParseFile.html#saveInBackground(com.parse.SaveCallback,%20com.parse.ProgressCallback)

I can see that you have the same problem with your image uploading method.


There is a new way and API to upload files to Parse. You can now instantiate a ParseFile in the following manner (there is a bug with the new API that should be fixed shortly where the upload fails) (See Parse SDK github for more info) https://github.com/ParsePlatform/Parse-SDK-Android:

final ParseObject parseObject = new ParseObject("CLASS_NAME");
File audioFile = new File(audioUri.getPath());
final ParseFile parseFile = new ParseFile(audioFile);
parseObject.add("FILE_COLUMN", parseFile);
parseFile.saveInBackground(new SaveCallback() {
    @Override
    public void done(ParseException e) {
        if(e == null){
            parseObject.saveInBackground();
        }
    }
});

Need Your Help

Callback after multiple AJAX calls with SQlite transactions

jquery ajax sqlite

I have got multiple AJAX calls with SQlite transactions to add data. For some reasons one of the AJAX calls not executing but hideLoadingScreen() fires fine.