您的位置:首页 > 移动开发 > Android开发

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

2014-04-30 16:57 661 查看
在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);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: