src/main/java/com/simpligility/maven/plugins/android/phase09package/ApkMojo.java
private void doAPKWithAPKBuilder( File outputFile, File dexFile, File zipArchive, Collection<File> sourceFolders,
                                      List<File> jarFiles, Collection<File> nativeFolders,
                                      boolean signWithDebugKeyStore ) throws MojoExecutionException
    {
        getLog().debug( "Building APK with internal APKBuilder" );
        
        //A when jack is running the classes directory will not get filled (usually)
        // so let's skip it if it wasn't created by something else
        if ( projectOutputDirectory.exists() || !getJack().isEnabled() ) 
        {
            sourceFolders.add( projectOutputDirectory );
        }

        for ( Artifact artifact : filterArtifacts( getRelevantCompileArtifacts(), skipDependencies,
                artifactTypeSet.getIncludes(), artifactTypeSet.getExcludes(), artifactSet.getIncludes(),
                artifactSet.getExcludes() ) )
        {
            getLog().debug( "Found artifact for APK :" + artifact );
            if ( extractDuplicates )
            {
                try
                {
                    computeDuplicateFiles( artifact.getFile() );
                }
                catch ( Exception e )
                {
                    getLog().warn( "Cannot compute duplicates files from " + artifact.getFile().getAbsolutePath(), e );
                }
            }
            jarFiles.add( artifact.getFile() );
        }

        for ( File src : sourceFolders )
        {
            computeDuplicateFilesInSource( src );
        }

        // Check duplicates.
        if ( extractDuplicates )
        {
            try
            {
                extractDuplicateFiles( jarFiles, sourceFolders );
            }
            catch ( IOException e )
            {
                getLog().error( "Could not extract duplicates to duplicate-resources.jar", e );
            }
        }

        try
        {
            final String debugKeyStore = signWithDebugKeyStore ? ApkBuilder.getDebugKeystore() : null;
            final ApkBuilder apkBuilder = new ApkBuilder( outputFile, zipArchive, dexFile, debugKeyStore, null );
            if ( apkDebug )
            {
                apkBuilder.setDebugMode( true );
            }

            for ( File sourceFolder : sourceFolders )
            {
                getLog().debug( "Adding source folder : " + sourceFolder );
                // Use ApkBuilder#addFile() to explicitly add resource files so that we can add META-INF/services.
                addResourcesFromFolder( apkBuilder, sourceFolder );
            }

            for ( File jarFile : jarFiles )
            {
                boolean excluded = false;

                if ( excludeJarResourcesPatterns != null )
                {
                    final String name = jarFile.getName();
                    getLog().debug( "Checking " + name + " against patterns" );
                    for ( Pattern pattern : excludeJarResourcesPatterns )
                    {
                        final Matcher matcher = pattern.matcher( name );
                        if ( matcher.matches() )
                        {
                            getLog().debug( "Jar " + name + " excluded by pattern " + pattern );
                            excluded = true;
                            break;
                        }
                        else
                        {
                            getLog().debug( "Jar " + name + " not excluded by pattern " + pattern );
                        }
                    }
                }

                if ( excluded )
                {
                    continue;
                }

                if ( jarFile.isDirectory() )
                {
                    getLog().debug( "Adding resources from jar folder : " + jarFile );
                    final String[] filenames = jarFile.list( new FilenameFilter()
                    {
                        public boolean accept( File dir, String name )
                        {
                            return PATTERN_JAR_EXT.matcher( name ).matches();
                        }
                    } );

                    for ( String filename : filenames )
                    {
                        final File innerJar = new File( jarFile, filename );
                        getLog().debug( "Adding resources from innerJar : " + innerJar );
                        apkBuilder.addResourcesFromJar( innerJar );
                    }
                }
                else
                {
                    getLog().debug( "Adding resources from : " + jarFile );
                    apkBuilder.addResourcesFromJar( jarFile );
                }
            }

            addSecondaryDexes( dexFile, apkBuilder );

            for ( File nativeFolder : nativeFolders )
            {
                getLog().debug( "Adding native library : " + nativeFolder );
                apkBuilder.addNativeLibraries( nativeFolder );
            }
            apkBuilder.sealApk();
        }
        catch ( ApkCreationException | SealedApkException | IOException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
        catch ( DuplicateFileException e )
        {
            final String msg = String.format( "Duplicated file: %s, found in archive %s and %s",
                    e.getArchivePath(), e.getFile1(), e.getFile2() );
            throw new MojoExecutionException( msg, e );
        }
    }
private void doAPKWithAPKBuilder( File outputFile, File dexFile, File zipArchive, Collection<File> sourceFolders,
                                      List<File> jarFiles, Collection<File> nativeFolders,
                                      boolean signWithDebugKeyStore ) throws MojoExecutionException
    {
        getLog().debug( "Building APK with internal APKBuilder" );
        
        //A when jack is running the classes directory will not get filled (usually)
        // so let's skip it if it wasn't created by something else
        if ( projectOutputDirectory.exists() || !getJack().isEnabled() ) 
        {
            sourceFolders.add( projectOutputDirectory );
        }

        for ( Artifact artifact : filterArtifacts( getRelevantCompileArtifacts(), skipDependencies,
                artifactTypeSet.getIncludes(), artifactTypeSet.getExcludes(), artifactSet.getIncludes(),
                artifactSet.getExcludes() ) )
        {
            getLog().debug( "Found artifact for APK :" + artifact );
            if ( extractDuplicates )
            {
                try
                {
                    computeDuplicateFiles( artifact.getFile() );
                }
                catch ( Exception e )
                {
                    getLog().warn( "Cannot compute duplicates files from " + artifact.getFile().getAbsolutePath(), e );
                }
            }
            jarFiles.add( artifact.getFile() );
        }

        for ( File src : sourceFolders )
        {
            computeDuplicateFilesInSource( src );
        }

        // Check duplicates.
        if ( extractDuplicates )
        {
            try
            {
                extractDuplicateFiles( jarFiles, sourceFolders );
            }
            catch ( IOException e )
            {
                getLog().error( "Could not extract duplicates to duplicate-resources.jar", e );
            }
        }

        try
        {
            final String debugKeyStore = signWithDebugKeyStore ? ApkBuilder.getDebugKeystore() : null;
            final ApkBuilder apkBuilder = new ApkBuilder( outputFile, zipArchive, dexFile, debugKeyStore, null );
            if ( apkDebug )
            {
                apkBuilder.setDebugMode( true );
            }

            for ( File sourceFolder : sourceFolders )
            {
                getLog().debug( "Adding source folder : " + sourceFolder );
                // Use ApkBuilder#addFile() to explicitly add resource files so that we can add META-INF/services.
                addResourcesFromFolder( apkBuilder, sourceFolder );
            }

            for ( File jarFile : jarFiles )
            {
                boolean excluded = false;

                if ( excludeJarResourcesPatterns != null )
                {
                    final String name = jarFile.getName();
                    getLog().debug( "Checking " + name + " against patterns" );
                    for ( Pattern pattern : excludeJarResourcesPatterns )
                    {
                        final Matcher matcher = pattern.matcher( name );
                        if ( matcher.matches() )
                        {
                            getLog().debug( "Jar " + name + " excluded by pattern " + pattern );
                            excluded = true;
                            break;
                        }
                        else
                        {
                            getLog().debug( "Jar " + name + " not excluded by pattern " + pattern );
                        }
                    }
                }

                if ( excluded )
                {
                    continue;
                }

                if ( jarFile.isDirectory() )
                {
                    getLog().debug( "Adding resources from jar folder : " + jarFile );
                    final String[] filenames = jarFile.list( new FilenameFilter()
                    {
                        public boolean accept( File dir, String name )
                        {
                            return PATTERN_JAR_EXT.matcher( name ).matches();
                        }
                    } );

                    for ( String filename : filenames )
                    {
                        final File innerJar = new File( jarFile, filename );
                        getLog().debug( "Adding resources from innerJar : " + innerJar );
                        apkBuilder.addResourcesFromJar( innerJar );
                    }
                }
                else
                {
                    getLog().debug( "Adding resources from : " + jarFile );
                    apkBuilder.addResourcesFromJar( jarFile );
                }
            }

            addSecondaryDexes( dexFile, apkBuilder );

            for ( File nativeFolder : nativeFolders )
            {
                getLog().debug( "Adding native library : " + nativeFolder );
                apkBuilder.addNativeLibraries( nativeFolder );
            }
            apkBuilder.sealApk();
        }
        catch ( ApkCreationException | SealedApkException | IOException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
        catch ( DuplicateFileException e )
        {
            final String msg = String.format( "Duplicated file: %s, found in archive %s and %s",
                    e.getArchivePath(), e.getFile1(), e.getFile2() );
            throw new MojoExecutionException( msg, e );
        }
    }
private void doAPKWithAPKBuilder ( File outputFile , File dexFile , File zipArchive , Collection < File > sourceFolders , List < File > jarFiles , Collection < File > nativeFolders , boolean signWithDebugKeyStore ) throws MojoExecutionException { getLog ( ) . debug ( "Building APK with internal APKBuilder" ) ; //A when jack is running the classes directory will not get filled (usually) // so let's skip it if it wasn't created by something else if ( projectOutputDirectory . exists ( ) || ! getJack ( ) . isEnabled ( ) ) { sourceFolders . add ( projectOutputDirectory ) ; } for ( Artifact artifact : filterArtifacts ( getRelevantCompileArtifacts ( ) , skipDependencies , artifactTypeSet . getIncludes ( ) , artifactTypeSet . getExcludes ( ) , artifactSet . getIncludes ( ) , artifactSet . getExcludes ( ) ) ) { getLog ( ) . debug ( "Found artifact for APK :" + artifact ) ; if ( extractDuplicates ) { try { computeDuplicateFiles ( artifact . getFile ( ) ) ; } catch ( Exception e ) { getLog ( ) . warn ( "Cannot compute duplicates files from " + artifact . getFile ( ) . getAbsolutePath ( ) , e ) ; } } jarFiles . add ( artifact . getFile ( ) ) ; } for ( File src : sourceFolders ) { computeDuplicateFilesInSource ( src ) ; } // Check duplicates. if ( extractDuplicates ) { try { extractDuplicateFiles ( jarFiles , sourceFolders ) ; } catch ( IOException e ) { getLog ( ) . error ( "Could not extract duplicates to duplicate-resources.jar" , e ) ; } } try { final String debugKeyStore = signWithDebugKeyStore ? ApkBuilder . getDebugKeystore ( ) : null ; final ApkBuilder apkBuilder = new ApkBuilder ( outputFile , zipArchive , dexFile , debugKeyStore , null ) ; if ( apkDebug ) { apkBuilder . setDebugMode ( true ) ; } for ( File sourceFolder : sourceFolders ) { getLog ( ) . debug ( "Adding source folder : " + sourceFolder ) ; // Use ApkBuilder#addFile() to explicitly add resource files so that we can add META-INF/services. addResourcesFromFolder ( apkBuilder , sourceFolder ) ; } for ( File jarFile : jarFiles ) { boolean excluded = false ; if ( excludeJarResourcesPatterns != null ) { final String name = jarFile . getName ( ) ; getLog ( ) . debug ( "Checking " + name + " against patterns" ) ; for ( Pattern pattern : excludeJarResourcesPatterns ) { final Matcher matcher = pattern . matcher ( name ) ; if ( matcher . matches ( ) ) { getLog ( ) . debug ( "Jar " + name + " excluded by pattern " + pattern ) ; excluded = true ; break ; } else { getLog ( ) . debug ( "Jar " + name + " not excluded by pattern " + pattern ) ; } } } if ( excluded ) { continue ; } if ( jarFile . isDirectory ( ) ) { getLog ( ) . debug ( "Adding resources from jar folder : " + jarFile ) ; final String [ ] filenames = jarFile . list ( new FilenameFilter ( ) { public boolean accept ( File dir , String name ) { return PATTERN_JAR_EXT . matcher ( name ) . matches ( ) ; } } ) ; for ( String filename : filenames ) { final File innerJar = new File ( jarFile , filename ) ; getLog ( ) . debug ( "Adding resources from innerJar : " + innerJar ) ; apkBuilder . addResourcesFromJar ( innerJar ) ; } } else { getLog ( ) . debug ( "Adding resources from : " + jarFile ) ; apkBuilder . addResourcesFromJar ( jarFile ) ; } } addSecondaryDexes ( dexFile , apkBuilder ) ; for ( File nativeFolder : nativeFolders ) { getLog ( ) . debug ( "Adding native library : " + nativeFolder ) ; apkBuilder . addNativeLibraries ( nativeFolder ) ; } apkBuilder . sealApk ( ) ; } catch ( ApkCreationException | SealedApkException | IOException e ) { throw new MojoExecutionException ( e . getMessage ( ) , e ) ; } catch ( DuplicateFileException e ) { final String msg = String . format ( "Duplicated file: %s, found in archive %s and %s" , e . getArchivePath ( ) , e . getFile1 ( ) , e . getFile2 ( ) ) ; throw new MojoExecutionException ( msg , e ) ; } }
Creates the APK file using the internal APKBuilder.

@param outputFile            the output file
@param dexFile               the dex file
@param zipArchive            the classes folder
@param sourceFolders         the resources
@param jarFiles              the embedded java files
@param nativeFolders         the native folders
@param signWithDebugKeyStore enables the signature of the APK using the debug key
@throws MojoExecutionException if the APK cannot be created.
Creates the APK file using the internal APKBuilder .