当前位置: 首页 > 工具软件 > WPS2CHM > 使用案例 >

Android调用第三方WPS打开word,excel等文件

萧安怡
2023-12-01

项目中遇到了使用第三方软件打开word,excel等文件的需求,最后是考虑用wps来打开这些软件。从网络上搜集了很多别人的代码,整理出来梳理一遍流程,做出一个小demo,实测可用。

限制:被打开的文档需要是存放在外部存储的(mnt目录下或者storage目录下),data目录下是内部存储,具体可以看看这篇博文https://blog.csdn.net/u012702547/article/details/50269639

 

直接上代码吧:

MainActivity的.xml文件:很简单就一个button用来点击触发事件

<?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"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

在MainActivity里:File获取要打开的文件的路径,bundle传递wps打开的模式,稍后会有代码,FileOpen类执行具体打开操作

Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                File file = new File("/mnt/sdcard/计算公式整理v2.0.docx");

                Bundle bundle = new Bundle();
                bundle.putString(WpsModel.OPEN_MODE, WpsModel.OpenMode.NORMAL); // 打开模式
                bundle.putBoolean(WpsModel.ENTER_REVISE_MODE, true); // 以修订模式打开文档
                bundle.putBoolean(WpsModel.SEND_CLOSE_BROAD, true); // 文件关闭时是否发送广播
                bundle.putBoolean(WpsModel.SEND_SAVE_BROAD, true); // 文件保存时是否发送广播
                bundle.putBoolean(WpsModel.HOMEKEY_DOWN, true); // 单机home键是否发送广播
                bundle.putBoolean(WpsModel.BACKKEY_DOWN, true); // 单机back键是否发送广播
                bundle.putBoolean(WpsModel.SAVE_PATH, true); // 文件这次保存的路径
                bundle.putString(WpsModel.THIRD_PACKAGE, WpsModel.PackageName.NORMAL); // 第三方应用的包名,用于对改应用合法性的验证

                FileOpen.openFile(MainActivity.this,file);
            }
        });

MyMimeMap类:

public class MyMimeMap {

    private static final HashMap<String, String> mapSimple = new HashMap<>();
    /**
     *  常用"文件扩展名—MIME类型"匹配表。
     *  注意,此表并不全,也并不是唯一的,就像有人喜欢用浏览器打开TXT一样,你可以根据自己的爱好自定义。
     */
    public static HashMap<String, String> getMimeMap() {
        if (mapSimple.size() == 0) {
            mapSimple.put(".3gp", "video/3gpp");
            mapSimple.put(".apk", "application/vnd.android.package-archive");
            mapSimple.put(".asf", "video/x-ms-asf");
            mapSimple.put(".avi", "video/x-msvideo");
            mapSimple.put(".bin", "application/octet-stream");
            mapSimple.put(".bmp", "image/bmp");
            mapSimple.put(".c", "text/plain");
            mapSimple.put(".chm", "application/x-chm");
            mapSimple.put(".class", "application/octet-stream");
            mapSimple.put(".conf", "text/plain");
            mapSimple.put(".cpp", "text/plain");
            mapSimple.put(".doc", "application/msword");
            mapSimple.put(".docx", "application/msword");
            mapSimple.put(".exe", "application/octet-stream");
            mapSimple.put(".gif", "image/gif");
            mapSimple.put(".gtar", "application/x-gtar");
            mapSimple.put(".gz", "application/x-gzip");
            mapSimple.put(".h", "text/plain");
            mapSimple.put(".htm", "text/html");
            mapSimple.put(".html", "text/html");
            mapSimple.put(".jar", "application/java-archive");
            mapSimple.put(".java", "text/plain");
            mapSimple.put(".jpeg", "image/jpeg");
            mapSimple.put(".jpg", "image/jpeg");
            mapSimple.put(".js", "application/x-javascript");
            mapSimple.put(".log", "text/plain");
            mapSimple.put(".m3u", "audio/x-mpegurl");
            mapSimple.put(".m4a", "audio/mp4a-latm");
            mapSimple.put(".m4b", "audio/mp4a-latm");
            mapSimple.put(".m4p", "audio/mp4a-latm");
            mapSimple.put(".m4u", "video/vnd.mpegurl");
            mapSimple.put(".m4v", "video/x-m4v");
            mapSimple.put(".mov", "video/quicktime");
            mapSimple.put(".mp2", "audio/x-mpeg");
            mapSimple.put(".mp3", "audio/x-mpeg");
            mapSimple.put(".mp4", "video/mp4");
            mapSimple.put(".mpc", "application/vnd.mpohun.certificate");
            mapSimple.put(".mpe", "video/mpeg");
            mapSimple.put(".mpeg", "video/mpeg");
            mapSimple.put(".mpg", "video/mpeg");
            mapSimple.put(".mpg4", "video/mp4");
            mapSimple.put(".mpga", "audio/mpeg");
            mapSimple.put(".msg", "application/vnd.ms-outlook");
            mapSimple.put(".ogg", "audio/ogg");
            mapSimple.put(".pdf", "application/pdf");
            mapSimple.put(".png", "image/png");
            mapSimple.put(".pps", "application/vnd.ms-powerpoint");
            mapSimple.put(".ppt", "application/vnd.ms-powerpoint");
            mapSimple.put(".pptx", "application/vnd.ms-powerpoint");
            mapSimple.put(".prop", "text/plain");
            mapSimple.put(".rar", "application/x-rar-compressed");
            mapSimple.put(".rc", "text/plain");
            mapSimple.put(".rmvb", "audio/x-pn-realaudio");
            mapSimple.put(".rtf", "application/rtf");
            mapSimple.put(".sh", "text/plain");
            mapSimple.put(".tar", "application/x-tar");
            mapSimple.put(".tgz", "application/x-compressed");
            mapSimple.put(".txt", "text/plain");
            mapSimple.put(".wav", "audio/x-wav");
            mapSimple.put(".wma", "audio/x-ms-wma");
            mapSimple.put(".wmv", "audio/x-ms-wmv");
            mapSimple.put(".wps", "application/vnd.ms-works");
            mapSimple.put(".xml", "text/plain");
            mapSimple.put(".xls", "application/vnd.ms-excel");
            mapSimple.put(".xlsx", "application/vnd.ms-excel");
            mapSimple.put(".z", "application/x-compress");
            mapSimple.put(".zip", "application/zip");
            mapSimple.put("", "*/*");
        }
        return mapSimple;
    }
}
FileOpen类:
public class FileOpen {

    public static void openFile(Context context, File file){
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //intent.addCategory(Intent.CATEGORY_DEFAULT);
        Uri uriForFile;
        if (Build.VERSION.SDK_INT > 23){
            //Android 7.0之后
            uriForFile = FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", file);
            intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);//给目标文件临时授权
        }else {
            uriForFile = Uri.fromFile(file);
        }
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//系统会检查当前所有已创建的Task中是否有该要启动的Activity的Task;
        // 若有,则在该Task上创建Activity;若没有则新建具有该Activity属性的Task,并在该新建的Task上创建Activity。
        intent.setDataAndType(uriForFile,getMimeTypeFromFile(file));
        context.startActivity(intent);
    }

    /**
     * 使用自定义方法获得文件的MIME类型
     */
    private static String getMimeTypeFromFile(File file) {
        String type = "*/*";
        String fName = file.getName();
        //获取后缀名前的分隔符"."在fName中的位置。
        int dotIndex = fName.lastIndexOf(".");
        if (dotIndex > 0) {
            //获取文件的后缀名
            String end = fName.substring(dotIndex, fName.length()).toLowerCase(Locale.getDefault());
            //在MIME和文件类型的匹配表中找到对应的MIME类型。
            HashMap<String, String> map = MyMimeMap.getMimeMap();
            if (!TextUtils.isEmpty(end) && map.keySet().contains(end)) {
                type = map.get(end);
            }
        }
        return type;
    }
}

WpsModel:

public class WpsModel {

    public static final String OPEN_MODE = "OpenMode";// 打开文件的模式。
    public static final String SEND_SAVE_BROAD = "SendSaveBroad";// 文件保存时是否发送广播。
    public static final String SEND_CLOSE_BROAD = "SendCloseBroad";// 文件关闭时是否发送广播
    public static final String THIRD_PACKAGE = "ThirdPackage";// 第三方的包名,关闭的广播会包含该项。
    public static final String CLEAR_BUFFER = "ClearBuffer";// 关闭文件时是否请空临时文件。
    public static final String CLEAR_TRACE = "ClearTrace";// 关闭文件时是否删除使用记录。
    public static final String CLEAR_FILE = "ClearFile";// 关闭文件时是否删除打开的文件。
    public static final String VIEW_PROGRESS = "ViewProgress";// 文件上次查看的进度。
    public static final String AUTO_JUMP = "AutoJump";// 是否自动跳转到上次查看的进度。
    public static final String SAVE_PATH = "SavePath";// 文件保存路径。
    public static final String VIEW_SCALE = "ViewScale";// 文件上次查看的视图的缩放。
    public static final String VIEW_SCALE_X = "ViewScrollX";// 文件上次查看的视图的X坐标。
    public static final String VIEW_SCALE_Y = "ViewScrollY";// 文件上次查看的视图的Y坐标。
    public static final String USER_NAME = "UserName";// 批注的作者。
    public static final String HOMEKEY_DOWN = "HomeKeyDown";// 监听home键并发广播
    public static final String BACKKEY_DOWN = "BackKeyDown";// 监听back键并发广播
    public static final String ENTER_REVISE_MODE = "EnterReviseMode";// 以修订模式打开文档
    public static final String CACHE_FILE_INVISIBLE = "CacheFileInvisible";// Wps生成的缓存文件外部是否可见

    public class OpenMode {
        public static final String NORMAL = "Normal";// 只读模式
        public static final String READ_ONLY = "ReadOnly";// 正常模式
        public static final String READ_MODE = "ReadMode";// 打开直接进入阅读器模式
        // 仅Word、TXT文档支持
        public static final String SAVE_ONLY = "SaveOnly";// 保存模式(打开文件,另存,关闭)
        // 仅Word、TXT文档支持
    }

    public class ClassName {
        public static final String NORMAL = "cn.wps.moffice.documentmanager.PreStartActivity2";
        // 普通版
        public static final String ENGLISH = "cn.wps.moffice.documentmanager.PreStartActivity2";
        // 英文版
        public static final String ENTERPRISE = "cn.wps.moffice.documentmanager.PreStartActivity2";
        // 企业版
    }

    public class PackageName {
        public static final String NORMAL = "cn.wps.moffice_eng";// 普通版
        public static final String ENGLISH = "cn.wps.moffice_eng";// 英文版
    }

    public class Reciver {
        public static final String ACTION_BACK = "com.kingsoft.writer.back.key.down";// 返回键广播
        public static final String ACTION_HOME = "com.kingsoft.writer.home.key.down";// Home键广播
        public static final String ACTION_SAVE = "cn.wps.moffice.file.save";// 保存广播
        public static final String ACTION_CLOSE = "cn.wps.moffice.file.close";// 关闭文件广播
    }
}

 

接下来是比较重点的provider

在AndroidManifest.xml文件中,application目录下:

<!--    authorities:一个标识,在当前系统内必须是唯一值,一般用包名。
                exported:表示该 FileProvider 是否需要公开出去。
                granUriPermissions:是否允许授权文件的临时访问权限。这里需要,所以是 true。-->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.wpsstudy.fileProvider"
            tools:replace="android:authorities"
            android:exported="false"
            android:grantUriPermissions="true">
            <!--指定Uri的共享路径-->
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

在res目录下,新建一个xml的文件夹,在里面新建一个叫做"file_paths"的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_storage_root"
        path="." />
    <files-path
        name="files-path"
        path="." />
    <cache-path
        name="cache-path"
        path="." />
    <!--/storage/emulated/0/Android/data/...-->
    <external-files-path
        name="external_file_path"
        path="." />
    <!--代表app 外部存储区域根目录下的文件 Context.getExternalCacheDir目录下的目录-->
    <external-cache-path
        name="external_cache_path"
        path="." />
    <!--配置root-path。这样子可以读取到sd卡和一些应用分身的目录,否则微信分身保存的图片,就会导致 java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/999/tencent/MicroMsg/WeiXin/export1544062754693.jpg,在小米6的手机上微信分身有这个crash,华为没有
-->
    <root-path
        name="root-path"
        path="" />
    </paths>

 

最后,记得添加文件读写权限

<!--文件读写权限-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

同时别忘了安装wps软件。

 

以下是参考的文章内容:https://www.jianshu.com/p/e8d1f95a77b9

https://blog.csdn.net/wxz1179503422/article/details/84874171

https://blog.csdn.net/addbufftoyou/article/details/89632317

https://blog.csdn.net/cjw8990/article/details/80802148

https://bbs.csdn.net/topics/392871878?utm_medium=distribute.pc_relevant.none-task-discussion_topic-BlogCommendFromBaidu-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-discussion_topic-BlogCommendFromBaidu-2.control

 

 类似资料: