ptplibrary icon indicating copy to clipboard operation
ptplibrary copied to clipboard

use ptp/ip and ptp/usb to connect to cameras like Canon and Nikon

ptplibrary

use ptp/ip and ptp/usb to connect to cameras like Canon and Nikon

Setup

Add dependency

//in build.gradle of module
dependencies {
    implementation 'com.github.rupiapps:ptplibrary:1.0'
}
//in build.gradle of project
allprojects {
    repositories {
        maven {
            url "https://jitpack.io"
        }
    }
}

Add permissions to manifest file

<uses-permission android:name="android.permission.INTERNET"/>

Example usage

Do not run this on mainthread otherwise you will get NetworkOnMainthreadException

            //this is only a test code
            //do not make try-catch-block around all your code
            try
            {
                System.out.println("start connect");

                //1. create a connection object by either using ptp/ip or ptp/usb
                InetAddress host = InetAddress.getByName("192.168.1.1");
                PtpConnection connection = PtpConnection.create(host);

                //2. connect to the host with your guid and name
                //   provide a callback to give feedback to the user
                //   if connection needs to be acknowledged
                connection.connectAndInit(
                        //16 byte guid
                        new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
                        "appname",
                        () -> System.out.println("waiting for acknowledge")
                );

                //3. use connection object to create a session
                PtpSession session = new PtpSession(connection);

                //4. get deviceinfo - some cameras need to have open session to get this
                Packet data = session.getDeviceInfo(true);
                DeviceInfoPacket deviceInfo = new DeviceInfoPacket(data);

                //check if valid
                if(deviceInfo.getBufferSize()>10)
                {
                    System.out.println(deviceInfo.getModel());
                    System.out.println(deviceInfo.getManufacturer());
                }

                //5. close the session after use
                session.closeAndDisconnect();
            }
            catch(InitFailException ife)
            {
                System.out.println("init failed: " + ife.getReason());
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }

Output:

I/System.out: start connect
I/System.out: waiting for acknowledge
I/System.out: D5300
I/System.out: Nikon Corporation

Using ptp/usb

For usb connections you will have to implement PtpUsbEndpoints on your operating system. An implementation for Android is not part of this project to keep the project independent from android.

Here is how it could look like:

public class AndroidUsbEndpoints implements PtpUsbEndpoints
{
	private static int DEFAULT_TIMEOUT = 10000;
	private UsbDeviceConnection usbconnection;
	private UsbInterface usbinterface;
	private UsbEndpoint data_out, data_in, interrupt;
	private int timeout;
	
	
	public AndroidUsbEndpoints(UsbDeviceConnection usbconnection, UsbInterface usbinterface)
	{
		this.usbconnection = usbconnection;
		this.usbinterface = usbinterface;
		timeout = DEFAULT_TIMEOUT;
	}
	
	public void initalize() throws InitFailException
	{
		if(!usbconnection.claimInterface(usbinterface, true))
			throw new InitFailException(InitFailReason.ClaimFailed);
		
		if(usbinterface.getEndpointCount()<3)
			throw new InitFailException(InitFailReason.NoEndpoints);
		
		for(int i=0; i<usbinterface.getEndpointCount(); i++)
		{
			UsbEndpoint ep = usbinterface.getEndpoint(i);
			
			boolean isout = ep.getDirection()==UsbConstants.USB_DIR_OUT;
			boolean isbulk = ep.getType()==UsbConstants.USB_ENDPOINT_XFER_BULK;
			
			if(isout && isbulk)
				data_out = ep;
			if(!isout && isbulk)
				data_in = ep;
			if(!isbulk)
				interrupt = ep;			
		}
		
		if(data_out==null || data_in==null || interrupt==null)
			throw new InitFailException(InitFailReason.NoEndpoints);
	}
	
	public void release()
	{
		usbconnection.releaseInterface(usbinterface);
	}
	
	public int controlTransfer(int requestType, int request, int value, int index, byte[] buffer)
	{
		return usbconnection.controlTransfer(requestType, request, value, index, buffer, buffer!=null?buffer.length:0, 1500);
	}

	public void setTimeOut(int to)
	{
		timeout = to>0?to:DEFAULT_TIMEOUT;
	}
	
	public int writeDataOut(byte[] buffer, int length) throws SendDataException
	{
		int len = usbconnection.bulkTransfer(data_out, buffer, length, timeout);
		if(len<0)
			throw new SendDataException("senderror: len is "+len);
		return len;
	}
	
	public int readDataIn(byte[] buffer) throws ReceiveDataException
	{
		int len=0; 
		while(len==0)		
		  len = usbconnection.bulkTransfer(data_in, buffer, buffer!=null?buffer.length:0, timeout);
		if(len<0)
			throw new ReceiveDataException("receiveerror: len is "+len);
		return len;
	}
	
	public void readEvent(byte[] buffer, boolean bulk)
	{		
		if(bulk)
			usbconnection.bulkTransfer(interrupt, buffer, buffer.length, 500);
		else
		{
			UsbRequest req = new UsbRequest();
			req.initialize(usbconnection, interrupt);		
			ByteBuffer bbuffer = ByteBuffer.wrap(buffer);
			req.queue(bbuffer, buffer.length);							
			req = usbconnection.requestWait();
			PtpLog.debug("received event");
			if(req!=null)
			{
				PtpLog.debug("req != null");
				PtpLog.debug(new Packet(bbuffer.array()).toString());
			}	
			else
				PtpLog.debug("event is null");
		}
		
	}
	
	public int getMaxPacketSizeOut()
	{
		return data_out.getMaxPacketSize();
	}
	
	public int getMaxPacketSizeIn()
	{
		return data_in.getMaxPacketSize();
	}
	
	public int getMaxPacketSizeInterrupt()
	{
		return interrupt.getMaxPacketSize();
	}	
}