Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt 4.8 - detect insertion and removal of sd card on mac-mini (OS X Lion)

I am completely new to developing apps on Mac. Here I have developed only 2-3 apps using Qt and none using objective-c / cocoa / xcode.

Is there a way of detecting when an SD card is inserted in a Mac mini (OS X Lion) in Qt 4 (4.8 specifically)?

I (re)searched a lot on the web as well as on stackoverflow - and some results came up - but all for Android and Windows - nothing related to a Mac( mini OS X Lion).

Till now I have found this:

  • on a Mac (mini) a card reader is treated just like any other USB device
  • I also found this example in the Mac Developer Library. I hope this link is accessible to all.
    This example... "demonstrates the use of IOKitLib and IOUSBLib to set up asynchronous callbacks when a USB device is attached to or removed from the system". Hence it is achievable.
    I want to do the same in Qt.

I want to detect when a SD card has been inserted then I want to show my app, get some input and move the selected files from the card to local disk.
Clearly, all is easy - just detecting the card and showing the app (from tray or minimized state) is the important and tough part.

I'd really appreciate if you can point me in the right direction.
Thanks in advance!!


Update:

I have further researched and found that:

  • on Linux we can use udev(libudev) to achieve things like this.
  • but then I found that udev is Linux specific and won't find that in OS X.
    Answers here suggest to use the diskutil activity command to continuously monitor disks being mounted or ejected.
    I found something very similar here and here but for Linux using udev rules : (
  • the latest and seemingly most relevant finding is that:
    • diskutil plist and IOKit(DiskArbitration) have to be part of the solution I seek
  • Finally, here I found out about launchd plist and Lingon

Now... I have a lot more stuff than yesterday, but still I'd need help on putting all this together and using it in a Qt app. I'd highly appreciate someone guiding me to the end-result. I'll keep working on this and update if I can actually create something useful.

Thanks in advance!! : )

like image 276
zeFree Avatar asked Jan 15 '13 00:01

zeFree


1 Answers

I think you'd need to create a launch agent that uses the DiskArbitration framework to monitor for new disks being mounted. This agent would be set to run in the background when the user is logged in. When your helper detects a new disk is mounted it could inspect the properties of the DADiskRef representing the disk to decide if it is of interest to your application. If it is, it could then launch the user-facing portion of your application using the LaunchServices APIs.

A sketch of the code to register for disk mount events using DiskArbitration is as follows:

#include <Foundation/Foundation.h>
#include <DiskArbitration/DiskArbitration.h>

static void diskAppearedCallback(DADiskRef disk, void* context)
{
    CFDictionaryRef description = DADiskCopyDescription(disk);
    NSLog(@"Disk appeared: %@", description);
    CFRelease(description);
}

int main(int argc, char **argv)
{
    DASessionRef session = DASessionCreate(kCFAllocatorDefault);
    DARegisterDiskAppearedCallback(session, kDADiskDescriptionMatchVolumeMountable, diskAppearedCallback, 0);
    DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

    CFRunLoopRun();

    return 0;
}

The dictionary returned by DADiskCopyDescription contains a number of attributes that you may find useful in determining if the newly-mounted disk is of interest, including whether the media is removable, ejectable, and so on.

like image 183
bdash Avatar answered Oct 17 '22 05:10

bdash