【问题标题】:Android app crashes when trying to upload audio to Parse.com尝试将音频上传到 Parse.com 时,Android 应用程序崩溃
【发布时间】:2015-11-29 09:30:23
【问题描述】:

您好,这是我在这里的第一篇文章,我迫切需要解决这个问题的帮助。每当我只上传图像时,它都可以正常工作,但是一旦我尝试上传音频文件,我的应用程序就会崩溃,并且 logcat 没有显示任何错误或任何东西。有人可以帮帮我吗。 (我知道每个文件的文件大小限制为 10 MB,并且我已确保我的音频文件小于此值。)提前致谢。

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();
    }

我什至不调用函数uploadAudioToParse(),但如果我选择一个音频文件,当我调用uploadAll() 时应用程序会崩溃。如果我只选择图像而不是音频文件,该应用程序可以正常工作。 (附注 - 我有不同的按钮用于选择图像和音频文件,我还想将它们上传到我的 Parse 数据库中的同一个元组中。)


编辑:这是日志

11-30 01:54:21.586 16550-16550/sas.unplug W/System.err: java.io.FileNotFoundException:/external/audio/media/124081:打开 失败:ENOENT(没有这样的文件或目录)11-30 01:54:21.593 16550-16550/sas.unplug W/System.err:在 libcore.io.IoBridge.open(IoBridge.java:452) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err:在 java.io.FileInputStream.(FileInputStream.java:76) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: 在 sas.unplug.UploadPodcast.uploadAudioToParse(UploadPodcast.java:138) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: 在 sas.unplug.UploadPodcast.uploadAll(UploadPodcast.java:128) 11-30 01:54:21.593 16550-16550/sas.unplug W/System.err: 在 java.lang.reflect.Method.invoke(本机方法)11-30 01:54:21.593 16550-16550/sas.unplug W/System.err:在 android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: 在 android.view.View.performClick(View.java:5198) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err:在 android.view.View$PerformClick.run(View.java:21147) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err:在 android.os.Handler.handleCallback(Handler.java:739) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err:在 android.os.Handler.dispatchMessage(Handler.java:95) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err:在 android.os.Looper.loop(Looper.java:148) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err:在 android.app.ActivityThread.main(ActivityThread.java:5417) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: 在 java.lang.reflect.Method.invoke(本机方法)11-30 01:54:21.594 16550-16550/sas.unplug W/System.err:在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err: 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 11-30 01:54:21.594 16550-16550/sas.unplug W/System.err:原因: android.system.ErrnoException:打开失败:ENOENT(没有这样的文件或 目录)11-30 01:54:21.596 16550-16550/sas.unplug W/System.err:
在 libcore.io.Posix.open(本机方法)11-30 01:54:21.596 16550-16550/sas.unplug W/System.err:在 libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) 11-30 01:54:21.596 16550-16550/sas.unplug W/System.err:在 libcore.io.IoBridge.open(IoBridge.java:438) 11-30 01:54:21.596 16550-16550/sas.unplug W/System.err: ... 14 更多 11-30 01:54:21.597 16550-16550/sas.unplug D/AndroidRuntime:关闭 VM 11-30 01:54:21.598 16550-16550/sas.unplug E/AndroidRuntime:致命异常: 主要的 进程:sas.unplug,PID:16550 java.lang.IllegalStateException:无法执行方法 安卓:点击 在 android.view.View$DeclaredOnClickListener.onClick(View.java:4452) 在 android.view.View.performClick(View.java:5198) 在 android.view.View$PerformClick.run(View.java:21147) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 引起:java.lang.reflect.InvocationTargetException 在 java.lang.reflect.Method.invoke(本机方法) 在 android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 在 android.view.View.performClick(View.java:5198) 在 android.view.View$PerformClick.run(View.java:21147) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 引起:java.lang.NullPointerException:尝试调用虚拟方法 'int java.io.BufferedInputStream.read(byte[])' 在一个空对象上 参考 在 sas.unplug.UploadPodcast.uploadAudioToParse(UploadPodcast.java:145) 在 sas.unplug.UploadPodcast.uploadAll(UploadPodcast.java:128) 在 java.lang.reflect.Method.invoke(本机方法) 在 android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 在 android.view.View.performClick(View.java:5198) 在 android.view.View$PerformClick.run(View.java:21147) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 11-30 01:54:21.601 779-2167/? W/ActivityManager:强制完成活动 sas.unplug/.UploadPodcast 11-30 01:54:21.623 779-17380/? W/DropBoxManagerService:丢弃:data_app_crash(1300 > 0 字节) 11-30 01:54:21.668 779-11434/? I/OpenGLRenderer:初始化的 EGL, 版本 1.4 11-30 01:54:22.106 779-792/? W/ActivityManager:活动 ActivityRecord{8337fab u0 sas.unplug/.UploadPodcast 的暂停超时 t4229 f} 11-30 01:54:22.533 13913-13982/?我/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: 设置 fg pkgname:sas.unplug 11-30 01:54:31.606 779-792/? W/ActivityManager:启动超时已过期,放弃 唤醒锁! 11-30 01:54:34.494 16550-16550/sas.unplug I/过程: 发送信号。 PID: 16550 SIG: 9 11-30 01:54:34.507 779-11434/? E/Surface:getSlotFromBufferLocked:未知缓冲区:0x995cf840 11-30 01:54:34.547 779-790/? D/GraphicsStats:缓冲区计数: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: 进程 sas.unplug (pid 16550) 已终止


这是上述活动的布局 xml 文件。

<?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>

【问题讨论】:

    标签: android file audio file-upload parse-platform


    【解决方案1】:

    我认为您的问题在于处理异步操作

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

    您开始保存文件,但在发送第一个字节之前,您保存了po。在filepo 之间建立关联后,您的保存将失败,因为您的文件尚未获得ID,因为它尚未保存。

    好吧,不知道我的解释有多清楚,但这里有一个应该可行的解决方案:

    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();
            }
        }
    });
    

    现在,如果文件上传失败,您还会收到错误日志。

    文件上传还有一个进度回调,以防您希望显示一个对话框,其中包含一些关于上传距离完成的信息https://parse.com/docs/android/api/com/parse/ParseFile.html#saveInBackground(com.parse.SaveCallback,%20com.parse.ProgressCallback)

    我看你的图片上传方式也有同样的问题。

    【讨论】:

    • 首先,感谢您的快速响应。其次,我还有另一个问题。我什至不调用uploadAudioToParse(),如果我只是选择一个音频文件并调用uploadAll(),我的应用程序就会崩溃。也许我选择了错误的音频文件,你能帮帮我吗?
    • 没问题,.. 好吧 uploadAll() 只查找图像,正如答案中所说,图像上传与音频上传存在相同的问题,因此可能是对异步操作的相同处理你需要照顾的。否则,如果您提供 LogCat 输出的转储以查看导致应用崩溃的原因,将会非常有帮助。
    • 其实我上传图片没有问题。当我选择应用程序崩溃的音频文件时。
    • 好吧,那么您需要更清楚地说明这一点,因为前面的评论表明uploadAll() 是问题的一部分,而且除了onActivityResult 之外,我没有看到任何关于音频选择的代码。第三,你还没有提供 logcat,所以在不知道错误发生在哪里的情况下很难调试。
    • uploadAudio() 用于音频选择
    【解决方案2】:

    有一种新的方式和 API 可以将文件上传到 Parse。您现在可以通过以下方式实例化 ParseFile(新 API 存在一个错误,应尽快修复上传失败的问题)(有关更多信息,请参阅 Parse SDK github)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();
            }
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-10
      • 2018-09-07
      • 2017-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-09
      • 1970-01-01
      相关资源
      最近更新 更多