Android下Qtオープンコールシステムプログラムオープンファイル

4117 ワード

Windowsの下で、システムプログラムを呼び出してファイルを開くのは簡単です.
QDesktopServices::openUrl(QUrl::fromLocalFile(“c:/test.txt") );
実現できます.
しかしAndroidプラットフォームでは、Qtを使用すると非常に面倒になりますが、まず4.8版のQt for Androidでは上記の呼び出しはサポートされていません.
最新のQt 5.2.1では改善されたかもしれませんが、筆者は試したことがありません.誰かがバグを提出しましたhttps://bugs.kde.org/show_bug.cgi?id=307605
もちろん、いくつかの古い工事はまだQt 5にアップグレードされていません.
#ifdef ANDROID
#include 
#include 
#include 
///////////////////////////////////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, "", "()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);
        }

}