Parrot Bebop cannot download high resolution photos [ANDROID]

Product: [Bebop2]
Use of libARController: [YES]
SDK platform: [Android]
Reproductible with the official app: [NO]

Hello,
I am trying to download the high resolution pictures I have taken from the parrot to my phone wirelessly. Using ARDataTransferManager, I create a dataTrasnferManager, then fetch the mediaList, then download all the medias. However, there is no place in the media object that has the bytes for the high resolution photo, only the thumbnails. Does anyone know how I can attain these photos wirelessly from the parrots sd card.

My Code:

public void createDataTransferManager() {
    String productIP = "192.168.42.1";  // TODO: get this address from libARController

    ARDATATRANSFER_ERROR_ENUM result = ARDATATRANSFER_ERROR_ENUM.ARDATATRANSFER_OK;
    try
    {
        dataTransferManager = new ARDataTransferManager();
    }
    catch (ARDataTransferException e)
    {
        e.printStackTrace();
        result = ARDATATRANSFER_ERROR_ENUM.ARDATATRANSFER_ERROR;
    }

    if (result == ARDATATRANSFER_ERROR_ENUM.ARDATATRANSFER_OK)
    {
        try
        {
            ftpListManager = new ARUtilsManager();
            ftpQueueManager = new ARUtilsManager();

            ftpListManager.initWifiFtp(productIP, DEVICE_PORT, ARUtilsFtpConnection.FTP_ANONYMOUS, "");
            ftpQueueManager.initWifiFtp(productIP, DEVICE_PORT, ARUtilsFtpConnection.FTP_ANONYMOUS, "");
        }
        catch (ARUtilsException e)
        {
            e.printStackTrace();
            result = ARDATATRANSFER_ERROR_ENUM.ARDATATRANSFER_ERROR_FTP;
        }
    }
    if (result == ARDATATRANSFER_ERROR_ENUM.ARDATATRANSFER_OK)
    {
        // direct to external directory
        String externalDirectory = Environment.getExternalStorageDirectory().toString();
        try
        {
            dataTransferManager.getARDataTransferMediasDownloader().createMediasDownloader(ftpListManager, ftpQueueManager, MEDIA_FOLDER, externalDirectory);
        }
        catch (ARDataTransferException e)
        {
            e.printStackTrace();
            result = e.getError();
        }
    }

    if (result == ARDATATRANSFER_ERROR_ENUM.ARDATATRANSFER_OK)
    {
        // create a thread for the download to run the download runnable
        mFileTransferThread = new HandlerThread("FileTransferThread");
        mFileTransferThread.start();
        mFileTransferThreadHandler = new Handler(mFileTransferThread.getLooper());
    }

    if (result != ARDATATRANSFER_ERROR_ENUM.ARDATATRANSFER_OK)
    {
        // clean up here because an error happened
    }
}


private void fetchMediasList() {
    if (getMediaAsyncTask == null)
    {
        getMediaAsyncTask = new AsyncTask<Void, Float, ArrayList<ARMediaObject>>()
        {
            @Override
            protected ArrayList<ARMediaObject> doInBackground(Void... params)
            {
                ArrayList<ARMediaObject> mediaList = null;
                synchronized (lock)
                {
                    ARDataTransferMediasDownloader mediasDownloader = null;
                    if (dataTransferManager != null)
                    {
                        mediasDownloader = dataTransferManager.getARDataTransferMediasDownloader();
                    }

                    if (mediasDownloader != null) {
                        try {
                            int mediaListCount = mediasDownloader.getAvailableMediasSync(false);
                            mediaList = new ArrayList<>(mediaListCount);
                            for (int i = 0; i < mediaListCount; i++) {
                                ARDataTransferMedia currentMedia = mediasDownloader.getAvailableMediaAtIndex(i);
                                final ARMediaObject currentARMediaObject = new ARMediaObject();
                                currentARMediaObject.updateDataTransferMedia(getResources(), currentMedia);
                                mediaList.add(currentARMediaObject);
                            }
                        } catch (ARDataTransferException e) {
                            e.printStackTrace();
                            mediaList = null;
                        }
                    }

                }
                return mediaList;
            }

            @Override
            protected void onPostExecute(ArrayList<ARMediaObject> arMediaObjects)
            {
                
            }
        };
    }

private void downloadMedias(ArrayList<Integer> mediaToDl) throws ARDataTransferException {
    viewer.setText(mediaToDl.size()+"");
    ARDataTransferMediasDownloader mediasDownloader = null;
    if (dataTransferManager != null)
    {
        mediasDownloader = dataTransferManager.getARDataTransferMediasDownloader();
    }

    if (mediasDownloader != null)
    {
        for (int i = 0; i < mediaToDl.size(); i++)
        {
            int mediaIndex = mediaToDl.get(i);
            ARDataTransferMedia mediaObject = null;
            try
            {
                mediaObject = dataTransferManager.getARDataTransferMediasDownloader().getAvailableMediaAtIndex(mediaIndex);
            }
            catch (ARDataTransferException e)
            {
                e.printStackTrace();
            }

            if (mediaObject != null)
            {
                try
                {
                    mediasDownloader.addMediaToQueue(mediaObject, this, null, this, null);
                }
                catch (ARDataTransferException e)
                {
                    e.printStackTrace();
                }
            }
        }

        if (!isRunning)
        {
            isRunning = true;
            Runnable downloaderQueueRunnable = mediasDownloader.getDownloaderQueueRunnable();
            mFileTransferThreadHandler.post(downloaderQueueRunnable);//imageView.setImageBitmap(mediasDownloader.getAvailableMediaAtIndex(0));
        }
    }
    isDownloading = true;
}

I believe there is a whole block of events / callbacks here you have not yet implemented. Let me pull some old code… will BRB.

You need to implement a couple interfaces in your parent class, or separately and pass them via mediasDownloader.addMediaToQueue I believe …

@Override
public void didMediaComplete(Object arg, final ARDataTransferMedia media, final ARDATATRANSFER_ERROR_ENUM error) {
    runOnUiThread(() -> {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();

            trace.stop();
        }

        progressDialog = null;

        if (selectedFolder == 0) {
            videosAdapter.notifyDataSetChanged();
        } else if (selectedFolder == 1) {
            photosAdapter.notifyDataSetChanged();
        }

        itemsList.invalidateViews();

        switch (error) {

            case ARDATATRANSFER_OK:
                break;
            case eARDATATRANSFER_ERROR_UNKNOWN_ENUM_VALUE:
            case ARDATATRANSFER_ERROR:
            case ARDATATRANSFER_ERROR_ALLOC:
            case ARDATATRANSFER_ERROR_BAD_PARAMETER:
            case ARDATATRANSFER_ERROR_NOT_INITIALIZED:
            case ARDATATRANSFER_ERROR_ALREADY_INITIALIZED:
            case ARDATATRANSFER_ERROR_THREAD_ALREADY_RUNNING:
            case ARDATATRANSFER_ERROR_THREAD_PROCESSING:
            case ARDATATRANSFER_ERROR_CANCELED:
            case ARDATATRANSFER_ERROR_SYSTEM:
            case ARDATATRANSFER_ERROR_FTP:
            case ARDATATRANSFER_ERROR_FILE:
                new AlertDialog.Builder(ctx)
                        .setIcon(R.mipmap.ic_launcher)
                        .setTitle(R.string.media_manager)
                        .setMessage(R.string.file_xfer_failed_message)
                        .setCancelable(false)
                        .setNegativeButton(R.string.no, null)
                        .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                File file = new File(MEDIA_STORAGE_DIRECTORY + File.separator + "downloading_" + media.getName());
                                file.delete();
                            }
                        })
                        .show();

                trace.incrementMetric("media_transfer_failed", 1);
        }
    });

    logEvent(Log.DEBUG, CLASS_NAME, "media=" + media.getName() + " complete=" + error.name());
}

@Override
public void didMediaProgress(Object arg, final ARDataTransferMedia media, final float percent) {
    if (lastPercent != Math.round(percent)) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (progressDialog == null) {
                    progressDialog = new ProgressDialog(ctx);
                    progressDialog.setIcon(R.mipmap.ic_launcher);
                    progressDialog.setCancelable(true);
                    progressDialog.setTitle(R.string.media_manager);
                }

                if (!progressDialog.isShowing()) {

                    trace.start();

                    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

                    // MB
                    if (media.getSize() > 2000000) {
                        divisor = 1000000;
                        numberFormat = "%,1d/%,2d MB";
                    } else {
                        // KB
                        divisor = 1000;
                        numberFormat = "%,1d/%,2d KB";
                    }

                    progressDialog.setMax(Math.round(media.getSize() / divisor));
                    progressDialog.setProgressNumberFormat(numberFormat);

                    progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            cancelCurrentDownload();
                            trace.stop();
                        }
                    });
                    progressDialog.setMessage(String.format(Locale.US, getString(R.string.downloading_file), media.getName()));
                    progressDialog.show();
                }

                progressDialog.setProgress(Math.round(media.getSize() / divisor * (percent * .01f)));
            }
        });

        lastPercent = Math.round(percent);
    }

    logEvent(Log.DEBUG, CLASS_NAME, "media=" + media.getName() + " progress=" + percent);
}
1 Like

Hello,

Thank you so much for your reply. I have already implemented the listeners, this was just a section of my code in my file. I realized what my error was. I was looking in the media object for a stream of bytes that pertains to the high resolution photo. Instead, the high resolution photos are just downloaded inside a folder in my phone.