美文网首页
Android使用7-zip库

Android使用7-zip库

作者: 会上网的井底之蛙 | 来源:发表于2017-06-02 15:21 被阅读0次

    一.去http://www.7-zip.org/sdk.html下载源代码

    1.在download页面http://www.7-zip.org/download.html,选Download p7zip for Linux (Posix) (x86 binaries and source code):里的p7zip at SourceForge

     2.“p7zip at sourceForge” 点击进去

        3.  Tab里选“Files”页面:

    4.点击上图的“Download p7zip_16.02_src_all.tar.bz2(4.2MB)”进行下载,下载后的文件名为:

          "p7zip_16.02_src_all.tar.bz2",解压成"p7zip_16.02"文件夹。

           可以打开根目录下的“README”查看帮助文档。

    二.在Android Studio中新建Android工程,新建时需要将“Include C++ support”勾上

       当然,你的Android Studio NDK开发环境要提前配置好,需要安装NDK、CMake、LLDB

    CMake: 外部构建工具。如果你准备只使用 ndk-build 的话,可以不使用它。LLDB: Android Studio上面调试本地代码的工具。

    1.在project\app\src\main\cpp\下建一子目录“p7zip”,用来存放c/c++代码。

    2.将7-zip源码目录 p7zip_16.02 下的C与CPP两个目录拷到工程中的project\app\src\main\cpp\p7zip 目录下

    三.打开“p7zip_16.02\DOC\MANUAL\cmdline\index.htm”,查看命令行命令的使用

    点击“Commands”

    然后点击"a",这个是将文件添加到存档的意思,即哪些文件要压缩

    我们可以根据 “7z a archive2.zip .\subdir\*”这个命令示例来执行压缩

    然后再回到“Commands”页面,选"x"

    我们可以根据“7z x archive.zip -oc:\soft *.cpp -r”这个命令示例来执行解压缩

    四.创建native函数

    1.新建java类:ZipUtils.java

    public class ZipUtils {
    public static native int excuteCommand(String command);

    }

    2.根据.java生成.h的本地头文件

     在Android studio的“Terminal”命令行面板里执行javah命令,先cd 到project\app\src\main\java路径下,再执行

    “javah com.example.wilson.zipdemo.zipdemo.ZipUtils”

    在目录树上会立即看到已经生成“com_example_wilson_zipdemo_zipdemo_ZipUtils.h”文件

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_example_wilson_zipdemo_zipdemo_ZipUtils */

    #ifndef _Included_com_example_wilson_zipdemo_zipdemo_ZipUtils
    #define _Included_com_example_wilson_zipdemo_zipdemo_ZipUtils
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
    * Class: com_example_wilson_zipdemo_zipdemo_ZipUtils
    * Method: excuteCommand
    * Signature: (Ljava/lang/String;)I
    */
    JNIEXPORT jint JNICALL Java_com_example_wilson_zipdemo_zipdemo_ZipUtils_excuteCommand
    (JNIEnv *, jclass, jstring);

    #ifdef __cplusplus
    }
    #endif
    #endif

    将它移到 project\app\src\main\cpp\p7zip目录

    3.打开 project\app\src\main\cpp\p7zip\CPP\7zip\UI\Console\MainAr.cpp


    int MY_CDECL main
    (
    #ifndef _WIN32
    int numArgs, char *args[]
    #endif
    )
    {
    g_ErrStream = &g_StdErr;
    g_StdStream = &g_StdOut;

    NT_CHECK

    NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
    int res = 0;

    try
    {
    res = Main2(
    #ifndef _WIN32
    numArgs, args
    #endif
    );
    }

    ......

    }

       这个cpp文件里有main函数,即7-zip的程序入口函数,因为执行命令行命令时,实际上就是执行main函数,所以我们可以根据main函数来编写我们的native调用函数,这样从java端发送一行命令给native端执行,就如在命令行里执行了一条命令一样。

    3.在project\app\src\main\cpp\p7zip目录下new一个c/c++ source file,取名“p7zip”,生成p7zip.cpp文件。再编写相关本地代码:

    //
    // Created by wilson on 2017/5/23.
    //
    #include "com_example_wilson_zipdemo_zipdemo_ZipUtils.h"
    #include "7zTypes.h"
    #include <jni.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    #include "android/log.h"

    #define LOG_ENABLE
    #ifdef LOG_ENABLE
    #define LOG_TAG "p7zip_jni"
    #define LOGI(...) do {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);} while(0)
    #define LOGD(...) do {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);} while(0)
    #define LOGE(...) do {__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__);} while(0)
    #else
    ...
    #endif

    #define ARGV_LEN_MAX 256
    #define ARGC_MAX 32

    extern int MY_CDECL main(
    #ifndef _WIN32
    int numArgs, const char *args[]
    #endif
    );

    static bool str2args(const char* s,char argv[][ARGV_LEN_MAX],int* argc) {
    bool in_token, in_container, escaped;
    bool ret;
    char container_start, c;
    int len, i;
    int index = 0;
    int arg_count = 0;

    ret = true;
    container_start = 0;
    in_token = false;
    in_container = false;
    escaped = false;

    len = strlen(s);
    for (i = 0; i < len; i++) {
    c = s[i];
    switch (c) {
    case ' ':
    case '\t':
    case '\n':

    if (!in_token)
    continue;
    if (in_container) {
    argv[arg_count][index++] = c;
    continue;
    }
    if (escaped) {
    escaped = false;
    argv[arg_count][index++] = c;
    continue;
    }
    /* if reached here, we're at end of token */
    in_token = false;
    argv[arg_count++][index] = '\0';
    index = 0;
    break;
    /* handle quotes */
    case '\'':
    case '\"':

    if (escaped) {
    argv[arg_count][index++] = c;
    escaped = false;
    continue;
    }
    if (!in_token) {
    in_token = true;
    in_container = true;
    container_start = c;
    continue;
    }
    if (in_container) {
    if (c == container_start) { //container end
    in_container = false;
    in_token = false;
    argv[arg_count++][index] = '\0';
    index = 0;
    continue;
    } else { //not the same as contain start char
    argv[arg_count][index++] = c;
    continue;
    }
    }
    LOGE("Parse Error! Bad quotes\n");
    ret = false;
    break;
    case '\\':

    if (in_container && s[i + 1] != container_start) {
    argv[arg_count][index++] = c;
    continue;
    }
    if (escaped) {
    argv[arg_count][index++] = c;
    continue;
    }
    escaped = true;
    break;
    default: //normal char

    if (!in_token) {
    in_token = true;
    }
    argv[arg_count][index++] = c;
    if (i == len - 1) { //reach the end
    argv[arg_count++][index++] = '\0';
    }
    break;
    }
    }
    *argc = arg_count;

    if (in_container) {
    LOGE("Parse Error! Still in container\n");
    ret = false;
    }
    if (escaped) {
    LOGE("Parse Error! Unused escape (\\)\n");
    ret = false;
    }
    return ret;
    }


    JNIEXPORT jint JNICALL Java_com_example_wilson_zipdemo_zipdemo_ZipUtils_excuteCommand
    (JNIEnv *env, jclass jzz, jstring command){
    int ret = -1;
    const char* ccommand = (const char*)env->GetStringUTFChars(command,NULL);

    LOGI("start[%s]",ccommand);

    int argc = 0;
    char temp[ARGC_MAX][ARGV_LEN_MAX] = {0};
    char* argv[ARGC_MAX] = {0};

    if (str2args(ccommand,temp,&argc)==false) {
    return 7;
    }

    for (int i=0;i<argc;i++) {
    argv[i] = temp[i];
    LOGD("arg[%d]:[%s]",i,argv[i]);
    }

    ret = main(argc,(const char**)argv);

    LOGI("end[%s]",ccommand);

    env->ReleaseStringUTFChars(command,ccommand);

    return ret;
    }

    五.编写CMakeLists.txt

    新建工程后,默认使用CMAKE编译C++。编写时特别要注意,不是所有的.cpp都需要,因为有部分是GUI需要的,而且要注意有些预设定的宏必须指定,比如宏:UNIX_USE_WIN_FILE,否则编译会出错(可以参考“\src\main\cpp\p7zip\CPP\ANDROID\7za\jni\Android.mk”).

    # For more information about using CMake with Android Studio, read the
    # documentation: https://d.android.com/studio/projects/add-native-code.html

    # Sets the minimum version of CMake required to build the native library.

    cmake_minimum_required(VERSION 3.4.1)

    # Creates and names a library, sets it as either STATIC
    # or SHARED, and provides the relative paths to its source code.
    # You can define multiple libraries, and CMake builds them for you.
    # Gradle automatically packages shared libraries with your APK.

    set(LOCAL_PATH src/main/cpp/p7zip)

    include_directories(${LOCAL_PATH}/C ${LOCAL_PATH}/CPP ${LOCAL_PATH}/CPP/myWindows ${LOCAL_PATH}/CPP/include_windows ${LOCAL_PATH}/CPP/Windows ${LOCAL_PATH}/CPP/Common ${LOCAL_PATH}/CPP/7zip/Common ${LOCAL_PATH}/CPP/7zip/UI/Agent ${LOCAL_PATH}/CPP/7zip/UI/FileManager)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DANDROID_NDK -fexceptions -DNDEBUG -D_REENTRANT -DENV_UNIX -DEXTERNAL_CODECS -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_NDK -fexceptions -DNDEBUG -D_REENTRANT -DENV_UNIX -DEXTERNAL_CODECS -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE")

    file(GLOB my_c_path ${LOCAL_PATH}/C/*.c)
    file(GLOB my_archive_common_path src/main/cpp/p7zip/CPP/7zip/Archive/Common/*.cpp)
    file(GLOB my_archive_7z_path src/main/cpp/p7zip/CPP/7zip/Archive/7z/*.cpp)
    file(GLOB my_archive_cab_path src/main/cpp/p7zip/CPP/7zip/Archive/Cab/*.cpp)
    file(GLOB my_archive_chm_path src/main/cpp/p7zip/CPP/7zip/Archive/Chm/*.cpp)
    file(GLOB my_archive_iso_path src/main/cpp/p7zip/CPP/7zip/Archive/Iso/*.cpp)
    file(GLOB my_archive_nsis_path src/main/cpp/p7zip/CPP/7zip/Archive/Nsis/*.cpp)
    file(GLOB my_archive_rar_path src/main/cpp/p7zip/CPP/7zip/Archive/Rar/*.cpp)
    file(GLOB my_archive_tar_path src/main/cpp/p7zip/CPP/7zip/Archive/Tar/*.cpp)
    file(GLOB my_archive_udf_path src/main/cpp/p7zip/CPP/7zip/Archive/Udf/*.cpp)
    file(GLOB my_archive_vim_path src/main/cpp/p7zip/CPP/7zip/Archive/Wim/*.cpp)
    file(GLOB my_archive_zip_path src/main/cpp/p7zip/CPP/7zip/Archive/Zip/*.cpp)

    file(GLOB my_7zip_common_path src/main/cpp/p7zip/CPP/7zip/Common/*.cpp)
    file(GLOB my_7zip_crypto_path src/main/cpp/p7zip/CPP/7zip/Crypto/*.cpp)
    file(GLOB my_7zip_ui_path src/main/cpp/p7zip/CPP/7zip/UI/Console/*.cpp)
    file(GLOB my_common_path src/main/cpp/p7zip/CPP/Common/*.cpp)

    add_library( # Sets the name of the library.
    p7zip

    # Sets the library as a shared library.
    SHARED

    # Provides a relative path to your source file(s).
    ${my_c_path}
    ${my_archive_common_path}
    ${my_archive_7z_path}
    ${my_archive_cab_path}
    ${my_archive_chm_path}
    ${my_archive_iso_path}
    ${my_archive_nsis_path}
    ${my_archive_rar_path}
    ${my_archive_tar_path}
    ${my_archive_udf_path}
    ${my_archive_vim_path}
    ${my_archive_zip_path}
    ${my_7zip_common_path}
    ${my_7zip_crypto_path}
    ${my_7zip_ui_path}
    ${my_common_path}
    src/main/cpp/p7zip/CPP/7zip/Archive/ApmHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/ArHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/ArjHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/Bz2Handler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/ComHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/CpioHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/CramfsHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/DeflateProps.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/DmgHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/ElfHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/ExtHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/FatHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/FlvHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/GptHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/GzHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/HandlerCont.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/HfsHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/IhexHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/LzhHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/LzmaHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/MachoHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/MbrHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/MslzHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/MubHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/NtfsHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/PeHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/PpmdHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/QcowHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/RpmHandler.cpp

    src/main/cpp/p7zip/CPP/7zip/Archive/SplitHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/SquashfsHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/SwfHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/UefiHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/VdiHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/VhdHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/VmdkHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/XarHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/XzHandler.cpp
    src/main/cpp/p7zip/CPP/7zip/Archive/ZHandler.cpp

    src/main/cpp/p7zip/CPP/7zip/Compress/Bcj2Coder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Bcj2Register.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BcjCoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BcjRegister.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BitlDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BranchMisc.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BranchRegister.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/ByteSwap.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BZip2Crc.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BZip2Decoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BZip2Encoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/BZip2Register.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/CodecExports.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/CopyCoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/CopyRegister.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Deflate64Register.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/DeflateDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/DeflateEncoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/DeflateRegister.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/DeltaFilter.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/ImplodeDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/LzhDecoder.cpp

    src/main/cpp/p7zip/CPP/7zip/Compress/Lzma2Decoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Lzma2Encoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Lzma2Register.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/LzmaDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/LzmaEncoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/LzmaRegister.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/LzmsDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/LzOutWindow.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/LzxDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/PpmdDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/PpmdEncoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/PpmdRegister.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/PpmdZip.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/QuantumDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Rar1Decoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Rar2Decoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Rar3Decoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Rar3Vm.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/Rar5Decoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/RarCodecsRegister.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/ShrinkDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/XpressDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/ZDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/ZlibDecoder.cpp
    src/main/cpp/p7zip/CPP/7zip/Compress/ZlibEncoder.cpp

    src/main/cpp/p7zip/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/ArchiveName.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/Bench.cpp

    src/main/cpp/p7zip/CPP/7zip/UI/Common/DefaultName.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/EnumDirItems.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/Extract.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/ExtractingFilePath.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/HashCalc.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/LoadCodecs.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/OpenArchive.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/PropIDUtils.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/SetProperties.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/SortUtils.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/TempFiles.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/Update.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/UpdateAction.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/UpdateCallback.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/UpdatePair.cpp
    src/main/cpp/p7zip/CPP/7zip/UI/Common/UpdateProduce.cpp

    src/main/cpp/p7zip/CPP/Windows/COM.cpp
    src/main/cpp/p7zip/CPP/Windows/DLL.cpp
    src/main/cpp/p7zip/CPP/Windows/ErrorMsg.cpp
    src/main/cpp/p7zip/CPP/Windows/FileDir.cpp
    src/main/cpp/p7zip/CPP/Windows/FileFind.cpp
    src/main/cpp/p7zip/CPP/Windows/FileIO.cpp
    src/main/cpp/p7zip/CPP/Windows/FileName.cpp
    src/main/cpp/p7zip/CPP/Windows/PropVariantConv.cpp
    src/main/cpp/p7zip/CPP/Windows/PropVariant.cpp
    src/main/cpp/p7zip/CPP/Windows/PropVariantUtils.cpp
    #src/main/cpp/p7zip/CPP/Windows/Registry.cpp
    src/main/cpp/p7zip/CPP/Windows/Synchronization.cpp
    src/main/cpp/p7zip/CPP/Windows/System.cpp
    src/main/cpp/p7zip/CPP/Windows/TimeUtils.cpp


    src/main/cpp/p7zip/CPP/myWindows/myAddExeFlag.cpp
    src/main/cpp/p7zip/CPP/myWindows/mySplitCommandLine.cpp
    src/main/cpp/p7zip/CPP/myWindows/wine_date_and_time.cpp

    src/main/cpp/p7zip/p7zip.cpp )

    # Searches for a specified prebuilt library and stores the path as a
    # variable. Because CMake includes system libraries in the search path by
    # default, you only need to specify the name of the public NDK library
    # you want to add. CMake verifies that the library exists before
    # completing its build.

    find_library( # Sets the name of the path variable.
    log-lib

    # Specifies the name of the NDK library that
    # you want CMake to locate.
    log )

    # Specifies libraries CMake should link to your target library. You
    # can link multiple libraries, such as libraries you define in this
    # build script, prebuilt third-party libraries, or system libraries.

    target_link_libraries( # Specifies the target library.
    p7zip

    # Links the target library to the log library
    # included in the NDK.
    ${log-lib} )

    六、配置模块的build.gradle:

    apply plugin: 'com.android.application'

    android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
    applicationId "com.example.wilson.zipdemo.zipdemo"
    minSdkVersion 19
    targetSdkVersion 25
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
    cmake {
    cppFlags ""
    }
    }
    ndk {
    // Specifies the ABI configurations of your native
    // libraries Gradle should build and package with your APK.
    abiFilters 'armeabi-v7a'
    }
    }
    buildTypes {
    release {
    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
    jniDebuggable true
    }
    }
    externalNativeBuild {
    cmake {
    path "CMakeLists.txt"
    }
    }
    sourceSets.main {
    jniLibs.srcDir 'src/main/libs'
    }
    }

    dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    }

    上面只生成armeabi-v7a的so。

    七、编译:

    注意:在编译的过程中.有两个cpp会报错:src/main/cpp/p7zip/CPP/7zip/Archive/7z 目录下的:

    7zHandler.cpp与7zExtract.cpp,都会报:

    undefined reference to 'g_ExternalCodecs'  的错误

    经查,主要由  src/main/cpp/p7zip/CPP/7zip/Common/CreateCoder.h中   宏定义

    #define EXTERNAL_CODECS_VARS2   (__externalCodecs.IsSet() ? &__externalCodecs : &g_ExternalCodecs)

    将其改为:

    #define EXTERNAL_CODECS_VARS2   ( &__externalCodecs)

    即可,因为'g_ExternalCodecs'  与GUI相关,我们只用到命令行

    八、测试

    在manifest文件中要加上权限:

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

    ZipUtils.java:

    package com.example.wilson.zipdemo.zipdemo;

    public class ZipUtils {
    public static native int excuteCommand(String command);

    }

    ZipProcess.java:

    package com.example.wilson.zipdemo.zipdemo;

    import android.app.ProgressDialog;
    import android.content.Context;
    import android.os.Handler;
    import android.os.Message;
    import android.widget.Toast;

    public class ZipProcess {

    /*
    0 No error
    1 Warning (Non fatal error(s)). For example, one or more files were locked by some other application,
    so they were not compressed.
    2 Fatal error
    7 Command line error
    8 Not enough memory for operation
    255 User stopped the process
    */
    private static final int RET_SUCCESS = 0;
    private static final int RET_WARNING = 1;
    private static final int RET_FAULT = 2;
    private static final int RET_COMMAND = 7;
    private static final int RET_MEMORY = 8;
    private static final int RET_USER_STOP = 255;

    Context context = null;
    Thread thread = null;
    ProgressDialog dialog = null;
    Handler handler = null;
    String command = null;

    public ZipProcess(Context context, String command) {
    // TODO Auto-generated method stub
    this.context = context;
    this.command = command;

    dialog = new ProgressDialog(context);
    dialog.setTitle(R.string.progress_title);
    dialog.setMessage(context.getText(R.string.progress_message));
    dialog.setCancelable(false);

    handler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
    // TODO Auto-generated method stub
    dialog.dismiss();

    int retMsgId = R.string.msg_ret_success;
    switch (msg.what) {
    case RET_SUCCESS:
    retMsgId = R.string.msg_ret_success;
    break;
    case RET_WARNING:
    retMsgId = R.string.msg_ret_warning;
    break;
    case RET_FAULT:
    retMsgId = R.string.msg_ret_fault;
    break;
    case RET_COMMAND:
    retMsgId = R.string.msg_ret_command;
    break;
    case RET_MEMORY:
    retMsgId = R.string.msg_ret_memmory;
    break;
    case RET_USER_STOP:
    retMsgId = R.string.msg_ret_user_stop;
    break;
    default:
    break;
    }
    Toast.makeText(ZipProcess.this.context, retMsgId, Toast.LENGTH_SHORT).show();

    return false;
    }
    });

    thread = new Thread(){
    @Override
    public void run() {
    // TODO Auto-generated method stub
    int ret = ZipUtils.excuteCommand(ZipProcess.this.command);
    handler.sendEmptyMessage(ret); //send back return code
    super.run();
    }
    };
    }

    void start(){
    dialog.show();
    thread.start();
    }

    }

    MainActivity.java:

    package com.example.wilson.zipdemo.zipdemo;

    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;

    public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
    System.loadLibrary("p7zip");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    }

    public void compress(View v) {
    compressProcess();
    }

    public void decompress(View v) {
    decompressProcess();
    }

    private void compressProcess(){
    StringBuilder sbCmd = new StringBuilder("7z a ");

    // sbCmd.append("-t7z "); //7z a -t7z = 指定压缩后的文件类型

    sbCmd.append("'/storage/emulated/0/7z_demo/7zdemo.zip' "); //7z a '/storage/emulated/0/7z_demo/7zdemo.zip'
    // sbCmd.append("'/storage/emulated/0/wifi_config.log' "); //7z a '//storage/emulated/0/7z_demo/7zdemo.zip' '/storage/emulated/0/wifi_config.log' = 文件的压缩
    sbCmd.append("'/storage/emulated/0/zp_7100' "); //7z a '//storage/emulated/0/7z_demo/7zdemo.zip' '/storage/emulated/0/zp_7100' = 文件夹的压缩


    new ZipProcess(MainActivity.this, sbCmd.toString()).start();
    }

    private void decompressProcess() {
    StringBuilder sbCmd = new StringBuilder("7z ");
    sbCmd.append("x "); //7z x

    //input file path
    sbCmd.append("'/storage/emulated/0/7z_demo/7zdemo.zip' "); //7z x '/storage/emulated/0/7z_demo/7zdemo.zip'
    //output path
    sbCmd.append("'-o" + "/storage/emulated/0/' "); //7z x '/storage/emulated/0/7z_demo/7zdemo.zip' '-o/storage/emulated/0/'

    sbCmd.append("-aoa "); //-aoa Overwrite All existing files without prompt.
    //7z x '/storage/emulated/0/7z_demo/7zdemo.zip' '-o/storage/emulated/0/' -aoa

    new ZipProcess(MainActivity.this, sbCmd.toString()).start();
    }

    }

    activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    tools:context="com.example.wilson.zipdemo.zipdemo.MainActivity">

    <Button
    android:layout_width="200dp"
    android:layout_height="100dp"
    android:text="压缩"
    android:onClick="compress"/>

    <Button
    android:layout_width="200dp"
    android:layout_height="100dp"
    android:text="解压缩"
    android:onClick="decompress"
    tools:layout_editor_absoluteY="111dp"
    tools:layout_editor_absoluteX="0dp" />

    </LinearLayout>

    最后,在小米5S上测试成功。

    相关文章

      网友评论

          本文标题:Android使用7-zip库

          本文链接:https://www.haomeiwen.com/subject/zbswxxtx.html