Skip to content
Browse files

[droid] Enable external player support

  • Loading branch information...
1 parent 809c430 commit f2297843e64120760a6de2be73a4f88a293f6ad3 Mike C committed
View
127 xbmc/android/activity/XBMCApp.cpp
@@ -730,52 +730,119 @@ bool CXBMCApp::HasLaunchIntent(const string &package)
return true;
}
-bool CXBMCApp::StartActivity(const string &package)
+// Note intent, dataType, dataURI all default to ""
+bool CXBMCApp::StartActivity(const string &package, const string &intent, const string &dataType, const string &dataURI)
{
if (!m_activity || !package.size())
- return false;
+ return false;
+
+ CLog::Log(LOGDEBUG, "CXBMCApp::StartActivity package: '%s' intent: '%s' dataType: '%s' dataURI: '%s'", package.c_str(), intent.c_str(), dataType.c_str(), dataURI.c_str());
jthrowable exc;
JNIEnv *env = NULL;
AttachCurrentThread(&env);
+
jobject oActivity = m_activity->clazz;
jclass cActivity = env->GetObjectClass(oActivity);
- // oPackageManager = new PackageManager();
- jmethodID mgetPackageManager = env->GetMethodID(cActivity, "getPackageManager", "()Landroid/content/pm/PackageManager;");
- jobject oPackageManager = (jobject)env->CallObjectMethod(oActivity, mgetPackageManager);
-
- // oPackageIntent = oPackageManager.getLaunchIntentForPackage(package);
- jclass cPackageManager = env->GetObjectClass(oPackageManager);
- jmethodID mgetLaunchIntentForPackage = env->GetMethodID(cPackageManager, "getLaunchIntentForPackage", "(Ljava/lang/String;)Landroid/content/Intent;");
- jstring sPackageName = env->NewStringUTF(package.c_str());
- jobject oPackageIntent = env->CallObjectMethod(oPackageManager, mgetLaunchIntentForPackage, sPackageName);
- env->DeleteLocalRef(cPackageManager);
- env->DeleteLocalRef(sPackageName);
- env->DeleteLocalRef(oPackageManager);
+ jobject oIntent = NULL;
+ jclass cIntent = NULL;
+ if (intent.size())
+ {
+ // Java equivalent for following JNI
+ // Intent oIntent = new Intent(Intent.ACTION_VIEW);
+ cIntent = env->FindClass("android/content/Intent");
+ jmethodID midIntentCtor = env->GetMethodID(cIntent, "<init>", "(Ljava/lang/String;)V");
+ jstring sIntent = env->NewStringUTF(intent.c_str());
+ oIntent = env->NewObject(cIntent, midIntentCtor, sIntent);
+ env->DeleteLocalRef(sIntent);
+ }
+ else
+ {
+ // oPackageManager = new PackageManager();
+ jmethodID mgetPackageManager = env->GetMethodID(cActivity, "getPackageManager", "()Landroid/content/pm/PackageManager;");
+ jobject oPackageManager = (jobject)env->CallObjectMethod(oActivity, mgetPackageManager);
+
+ // oPackageIntent = oPackageManager.getLaunchIntentForPackage(package);
+ jclass cPackageManager = env->GetObjectClass(oPackageManager);
+ jmethodID mgetLaunchIntentForPackage = env->GetMethodID(cPackageManager, "getLaunchIntentForPackage", "(Ljava/lang/String;)Landroid/content/Intent;");
+ jstring sPackageName = env->NewStringUTF(package.c_str());
+ oIntent = env->CallObjectMethod(oPackageManager, mgetLaunchIntentForPackage, sPackageName);
+ cIntent = env->GetObjectClass(oIntent);
+ env->DeleteLocalRef(cPackageManager);
+ env->DeleteLocalRef(sPackageName);
+ env->DeleteLocalRef(oPackageManager);
+
+ exc = env->ExceptionOccurred();
+ if (exc)
+ {
+ CLog::Log(LOGERROR, "CXBMCApp::StartActivity Failed to load %s. Exception follows:", package.c_str());
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ env->DeleteLocalRef(cActivity);
+ DetachCurrentThread();
+ return false;
+ }
+ if (!oIntent)
+ {
+ CLog::Log(LOGERROR, "CXBMCApp::StartActivity %s has no Launch Intent", package.c_str());
+ env->DeleteLocalRef(cActivity);
+ DetachCurrentThread();
+ return false;
+ }
+ }
- exc = env->ExceptionOccurred();
- if (exc)
+ jobject oUri;
+ if (dataURI.size())
{
- CLog::Log(LOGERROR, "CXBMCApp::StartActivity Failed to load %s. Exception follows:", package.c_str());
- env->ExceptionDescribe();
- env->ExceptionClear();
- env->DeleteLocalRef(cActivity);
- DetachCurrentThread();
- return false;
+ // Java equivalent for the following JNI
+ // Uri oUri = Uri.parse(sPath);
+ jclass cUri = env->FindClass("android/net/Uri");
+ jmethodID midUriParse = env->GetStaticMethodID(cUri, "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
+ jstring sPath = env->NewStringUTF(dataURI.c_str());
+ oUri = env->CallStaticObjectMethod(cUri, midUriParse, sPath);
+ env->DeleteLocalRef(sPath);
+ env->DeleteLocalRef(cUri);
+
+ // Run setData or setDataAndType depending on what was passed into the method
+ // This allows opening market links or external players using the same method
+ if (dataType.size())
+ {
+ // Java equivalent for the following JNI
+ // oIntent.setDataAndType(oUri, "video/*");
+ jmethodID midIntentSetDataAndType = env->GetMethodID(cIntent, "setDataAndType", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;");
+ jstring sMimeType = env->NewStringUTF(dataType.c_str());
+ oIntent = env->CallObjectMethod(oIntent, midIntentSetDataAndType, oUri, sMimeType);
+ env->DeleteLocalRef(sMimeType);
+ }
+ else
+ {
+ // Java equivalent for the following JNI
+ // oIntent.setData(oUri);
+ jmethodID midIntentSetData = env->GetMethodID(cIntent, "setData", "(Landroid/net/Uri;)Landroid/content/Intent;");
+ oIntent = env->CallObjectMethod(oIntent, midIntentSetData, oUri);
+ }
}
- if (!oPackageIntent)
+
+ // Java equivalent for the following JNI
+ // oIntent.setPackage(sPackage);
+ jstring sPackage = env->NewStringUTF(package.c_str());
+ jmethodID mSetPackage = env->GetMethodID(cIntent, "setPackage", "(Ljava/lang/String;)Landroid/content/Intent;");
+ oIntent = env->CallObjectMethod(oIntent, mSetPackage, sPackage);
+
+ if (oUri != NULL)
{
- CLog::Log(LOGERROR, "CXBMCApp::StartActivity %s has no Launch Intent", package.c_str());
- env->DeleteLocalRef(cActivity);
- DetachCurrentThread();
- return false;
+ env->DeleteLocalRef(oUri);
}
- // startActivity(oIntent);
+ env->DeleteLocalRef(cIntent);
+ env->DeleteLocalRef(sPackage);
+
+ // Java equivalent for the following JNI
+ // startActivity(oIntent);
jmethodID mStartActivity = env->GetMethodID(cActivity, "startActivity", "(Landroid/content/Intent;)V");
- env->CallVoidMethod(oActivity, mStartActivity, oPackageIntent);
+ env->CallVoidMethod(oActivity, mStartActivity, oIntent);
env->DeleteLocalRef(cActivity);
- env->DeleteLocalRef(oPackageIntent);
+ env->DeleteLocalRef(oIntent);
exc = env->ExceptionOccurred();
if (exc)
View
2 xbmc/android/activity/XBMCApp.h
@@ -83,7 +83,7 @@ class CXBMCApp : public IActivityHandler
static int android_printf(const char *format, ...);
static int GetBatteryLevel();
- static bool StartActivity(const std::string &package);
+ static bool StartActivity(const std::string &package, const std::string &intent = std::string(), const std::string &dataType = std::string(), const std::string &dataURI = std::string());
static bool ListApplications(std::vector <androidPackage> *applications);
static bool GetIconSize(const std::string &packageName, int *width, int *height);
static bool GetIcon(const std::string &packageName, void* buffer, unsigned int bufSize);
View
23 xbmc/cores/ExternalPlayer/ExternalPlayer.cpp
@@ -47,6 +47,9 @@
#if defined(HAS_LIRC)
#include "input/linux/LIRC.h"
#endif
+#if defined(TARGET_ANDROID)
+ #include "android/activity/XBMCApp.h"
+#endif
// If the process ends in less than this time (ms), we assume it's a launcher
// and wait for manual intervention before continuing
@@ -311,6 +314,8 @@ void CExternalPlayer::Process()
BOOL ret = TRUE;
#if defined(_WIN32)
ret = ExecuteAppW32(strFName.c_str(),strFArgs.c_str());
+#elif defined(TARGET_ANDROID)
+ ret = ExecuteAppAndroid(m_filename.c_str(), mainFile.c_str());
#elif defined(_LINUX) || defined(TARGET_DARWIN_OSX)
ret = ExecuteAppLinux(strFArgs.c_str());
#endif
@@ -443,7 +448,7 @@ BOOL CExternalPlayer::ExecuteAppW32(const char* strPath, const char* strSwitches
}
#endif
-#if defined(_LINUX) || defined(TARGET_DARWIN_OSX)
+#if !defined(TARGET_ANDROID) && (defined(_LINUX) || defined(TARGET_DARWIN_OSX))
BOOL CExternalPlayer::ExecuteAppLinux(const char* strSwitches)
{
CLog::Log(LOGNOTICE, "%s: %s", __FUNCTION__, strSwitches);
@@ -469,6 +474,22 @@ BOOL CExternalPlayer::ExecuteAppLinux(const char* strSwitches)
}
#endif
+#if defined(TARGET_ANDROID)
+BOOL CExternalPlayer::ExecuteAppAndroid(const char* strSwitches,const char* strPath)
+{
+ CLog::Log(LOGNOTICE, "%s: %s", __FUNCTION__, strSwitches);
+
+ int ret = CXBMCApp::StartActivity(strSwitches, "android.intent.action.VIEW", "video/*", strPath);
+
+ if (ret != 0)
+ {
+ CLog::Log(LOGNOTICE, "%s: Failure: %d", __FUNCTION__, ret);
+ }
+
+ return ret == 0;
+}
+#endif
+
void CExternalPlayer::Pause()
{
}
View
2 xbmc/cores/ExternalPlayer/ExternalPlayer.h
@@ -82,6 +82,8 @@ class CExternalPlayer : public IPlayer, public CThread
#if defined(_WIN32)
virtual BOOL ExecuteAppW32(const char* strPath, const char* strSwitches);
//static void CALLBACK AppFinished(void* closure, BOOLEAN TimerOrWaitFired);
+#elif defined(TARGET_ANDROID)
+ virtual BOOL ExecuteAppAndroid(const char* strSwitches,const char* strPath);
#elif defined(_LINUX)
virtual BOOL ExecuteAppLinux(const char* strSwitches);
#endif

0 comments on commit f229784

Please sign in to comment.
Something went wrong with that request. Please try again.