Android 下Qt打开 调用系统程序打开文件

5 篇文章 0 订阅


在Windows下,调用系统程序打开一个文件非常容易。

QDesktopServices::openUrl(QUrl::fromLocalFile(“c:/test.txt") );

就可以实现。

但是在Android平台下,如果使用Qt的话,将非常麻烦,首先4.8版的Qt for Android 是不支持上述的调用的。

在最新的Qt5.2.1中可能已经对此有所改进,笔者没有试过。有人为此提交了一个Bug,https://bugs.kde.org/show_bug.cgi?id=307605

当然,一些老的工程还没有升级到Qt5,想实现打开怎么办?


#ifdef ANDROID
#include <jni.h>
#include <android/log.h>
#include <qglobal.h>
///JNILOADER/
/*----------------------------------------------------------------------
|    definitions
+---------------------------------------------------------------------*/
#define ATTACH_TO_CURRENT_THREAD_THEN_RET(ret_statement)     \
	JNIEnv* env;                                              \
	if (m_javaVM->AttachCurrentThread(&env, NULL) < 0) {      \
	ret_statement;                                        \
	}

#define DETACH_FROM_CURRENT_THREAD_THEN_RET(ret_statement)       \
	if (!m_javaVM->DetachCurrentThread() < 0) {                   \
	ret_statement;                                            \
	}
#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))

JavaVM* m_javaVM;
static JNIEnv* m_env;
static jmethodID m_methodOpen;
static jmethodID m_methodInit;
static jclass m_classOpen;
static jobject m_obj;
static jstring m_strencode;

//extern Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /*reserved*/);
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
{
	m_javaVM = vm;

	if (m_javaVM->GetEnv((void**)&m_env, JNI_VERSION_1_4) != JNI_OK) {
		//      __android_log_print(ANDROID_LOG_FATAL, "Qt", "GetEnv failed.");
		return JNI_FALSE;
	}

	const char* classNameTexHelper =   "org/kde/necessitas/origo/TestActivity";

	// TODO: remember to free.
	jclass local_class_java_delegate = m_env->FindClass(classNameTexHelper);
	if (!local_class_java_delegate) {
		//       __android_log_print(ANDROID_LOG_FATAL, "Qt", "Unable to find class %s.", classNameTexHelper);
		return JNI_FALSE;
	}

	m_classOpen  = (jclass)m_env->NewGlobalRef(local_class_java_delegate);
	m_env->DeleteLocalRef(local_class_java_delegate);
	m_methodInit= m_env->GetMethodID((jclass)m_classOpen, "<init>", "()V");
	m_methodOpen = m_env->GetStaticMethodID((jclass)m_classOpen, "JIntentActionViewFile","(Ljava/lang/String;)V");
	m_obj = m_env->NewObject((jclass)m_classOpen, m_methodInit);

	return JNI_VERSION_1_4;
}
//
#endif //ANDROID
里面有个JNI_OnLoad,当Android 打开一个so的时候就会先执行这个函数,在这里面可以获取到vm的指针等等,要不然后面怎么跟java进行交互?


在需要调用打开文件的地方:

#ifdef ANDROID
			ATTACH_TO_CURRENT_THREAD_THEN_RET((void)0);
			m_strencode = env->NewStringUTF(fileZip.toStdString().c_str());
			env->CallStaticVoidMethod(m_classOpen,m_methodOpen,m_strencode);
			DETACH_FROM_CURRENT_THREAD_THEN_RET((void)0);
#else


当然了,还有一个必须的东东:

你懂的,这是另外一个Android的Activity用来完成打开文件的工作。

package org.kde.necessitas.origo;

import java.io.File;

import org.kde.necessitas.origo.QtActivity;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.webkit.MimeTypeMap;

public class TestActivity {

    public TestActivity (){}

    public static String mdata = "/sdcard/png.png";
        public static void JIntentActionViewFile(final String cdata)
        {
        String data=cdata;
        Intent intent = new Intent(Intent.ACTION_VIEW);
        MimeTypeMap mime = MimeTypeMap.getSingleton();
        File file = new File(data);
        String ext=file.getName().substring(file.getName().lastIndexOf(".")+1).toLowerCase();
        String type = mime.getMimeTypeFromExtension(ext);
        intent.setDataAndType(Uri.fromFile(file),type);
        QtActivity.getQtActivityInstance().startActivity(intent);
        }

}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路边闲人2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值