3

I have developed a Java application. The application connects to an android device programmatically to transfer some files to connects Android devices.

In my application I have added the adb PATH so it can use it to connect to devices.

I was wondering if its possible to maybe package it within the application ? or just copying the adb into the application directory ? Because I want who ever to download this application, wouldn't need to also have download the adb or Android sdk for the application to work

Is it possible ?

Achilles
  • 711
  • 2
  • 13
  • 35

2 Answers2

1

After doing some research you can package an exe within a jar file but you have to extract the exe each run of the application. Following TofuBear's example here I was able to encapsulate adb within a jar file. You'll need to include the AdbWinApi.dll (or equivalent linux libraries).

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

public class Sandbox
{
    public static void main(final String[] args)
        throws URISyntaxException,
               ZipException,
               IOException
    {
        final URI uri;
        final URI exe;

        uri = getJarURI();
        // Extract the adb application
        exe = getFile(uri, "adb.exe");
        // Extract the AdbWinApi dll file.
        getFile(uri, "AdbWinApi.dll");
        System.out.println(exe);
    }

    private static URI getJarURI()
        throws URISyntaxException
    {
        final ProtectionDomain domain;
        final CodeSource       source;
        final URL              url;
        final URI              uri;

        domain = Sandbox.class.getProtectionDomain();
        source = domain.getCodeSource();
        url    = source.getLocation();
        uri    = url.toURI();

        return (uri);
    }    

    private static URI getFile(final URI    where,
                               final String fileName)
        throws ZipException,
               IOException
    {
        final File location;
        final URI  fileURI;

        location = new File(where);

        // not in a JAR, just return the path on disk
        if(location.isDirectory())
        {
            fileURI = URI.create(where.toString() + fileName);
        }
        else
        {
            final ZipFile zipFile;

            zipFile = new ZipFile(location);

            try
            {
                fileURI = extract(zipFile, fileName);
            }
            finally
            {
                zipFile.close();
            }
        }

        return (fileURI);
    }

    private static URI extract(final ZipFile zipFile,
                           final String  fileName)
        throws IOException
    {
        final File         tempFile;
        final ZipEntry     entry;
        final InputStream  zipStream;
        OutputStream       fileStream;

        //tempFile = File.createTempFile(fileName,     Long.toString(System.currentTimeMillis()));
        tempFile = new File(System.getProperty("java.io.tmpdir") + File.separator + fileName);

        tempFile.deleteOnExit();
        entry    = zipFile.getEntry(fileName);

        if(entry == null)

        {
            throw new FileNotFoundException("cannot find file: " + fileName + " in archive: " + zipFile.getName());
        }

        zipStream  = zipFile.getInputStream(entry);
        fileStream = null;

        try
        {
            final byte[] buf;
            int          i;

            fileStream = new FileOutputStream(tempFile);
            buf        = new byte[1024];
            i          = 0;

            while((i = zipStream.read(buf)) != -1)
            {
                fileStream.write(buf, 0, i);
            }
        }
        finally
        {
            close(zipStream);
            close(fileStream);
        }

        return (tempFile.toURI());
    }

    private static void close(final Closeable stream)
    {
        if(stream != null)
        {
            try
            {
                stream.close();
            }
            catch(final IOException ex)
            {
                ex.printStackTrace();
            }
        }
    }
}

I had to change the file creation from TofuBear's example so that the file name of the exe would not be changed. It's still created in the temporary folder and will be deleted on exit. I left the original code as a comment.

Edit: Seems I got so caught up with the technical possiblity of it I forgot the legal ramifications. It's been stated here by Chris Stratton that the SDK Terms of Service prohibits redistribution of any part of the sdk. Which would include adb.

Community
  • 1
  • 1
Fr33dan
  • 4,227
  • 3
  • 35
  • 62
  • adb and other parts of the SDK are licensed with Apache 2.0 license. which means you can compile it yourself and redistribute it. https://github.com/android/platform_system_core/blob/master/adb/adb.c – m_vitaly Aug 26 '12 at 06:53
  • I've been confused about this. According to the SDK Terms of service, you cannot "copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK". Which directly contradicts the Apache License. The only thing I can find that links the sdk to the Apache License is this: http://source.android.com/source/licenses.html which "states majority of the Android software is licensed with Apache 2.0". Its there some breakdown of what is covered by what? – Fr33dan Aug 26 '12 at 12:24
  • 1
    The sources say they are Apache License. So they can be distributed (sources, not binaries). Android SDK is the Google compiled and packaged version of these sources - any they probably can't be distributed as is. What is not included in "majority of Android software is licensed with Apache 2.0" are linux kernel (GPL which is not Apache) and other proprietary driver stuff. – m_vitaly Aug 26 '12 at 12:43
  • Why would you say binaries cannot be distributed? Apache License says: "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form." I don't see why it would not be possible to distribute ADB. – HFSDev Apr 04 '13 at 13:05
1

It should be easier to use the Java-native chimpchat to connect to the device.

NoBugs
  • 9,310
  • 13
  • 80
  • 146