Thursday, September 6, 2012

XBMC as launcher


Now that XBMC is useful as a media player for my MELE (see HW acceleration thread), I also use it as a launcher.

Basic instructions

Download the APK from here.
And if you want to use an external player, check the previous post.

Advanced instructions

Important: There's already a modified manifset file uploaded here

To make xbmc work as launcher and make it persistent (this means it doesn't close when you watch a movie,and it doesn't need to load everything again when you finish a movie) you have to modify the file: "$XBMC_FOLDER/tools/android/packaging/xbmc/bin/AndroidManifest.xml".

Inside the file you can find the "intent-filter" node, we need to add an Intent for the home action.
....
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.HOME" />
....

If you want to xbmc appear in the default launcher as an application, don't replace the line:
<category android:name="android.intent.category.LAUNCHER" />

If you replace LAUNCHER with DEFAULT the application won't be listed anywhere but in the "All" section of the Android application manager.

To make it persistent:
(WARNING this will make XBMC constantly consume resources, so if you have low memory everything will be slower, this doesn't seem to be the case with MELE, but if you are using emulators or other applications with high memory usage this may impact on the performance).

You need to modify the "Application" Node:
"<application android:icon="@drawable/ic_launcher" android:debuggable="true" android:label="@string/app_name" android:hasCode="true">"

add the option:
android:persistent="true"

When this file was modified, the following file got modified also 
$XBMC_FOLDER/tools/android/packaging/xbmc/bin/AndroidManifest.xml.
I believe you should also modify this file with the desired options.


After modifying the xml, you have to build the apk, and install it normally.

XBMC with external player [temporary solution for lack of HW acceleration]

You may know the XBMC project ("XBMC is an award-winning free and open source (GPL) software media player and entertainment hub for digital media."), it's awesome, open source and works very well.

But, for now, in android the hardware acceleration is not working.

inRivalz came up with a workaround to use an external player, which has working hardware acceleration, instead of the internal player.

This means using a closed-source alternative, for now.


Basic instructions

Download this apk.

Install it on your device, and modify the playercorefactory.xml (which, according to XBMC Wiki is in Android/data/org.xbmc.xbmc/files/.xbmc/userdata/)

<playercorefactory>
<players>
<player name="MPC-HC" type="ExternalPlayer" audio="false" video="true">
<filename>com.inisoft.mediaplayer.a</filename>
<hidexbmc>true</hidexbmc>
</player>
</players>
<rules action="prepend">
<rule video="true" player="MPC-HC"/>
</rules>
</playercorefactory>

Replace the bold part with either for the corresponding version of the MXPlayer you have installed.
com.mxtech.videoplayer.pro - Pro Edition.
com.mxtech.videoplayer.ad - Free Edition.

Advanced instructions:

Download the source from XBMC Git: Instructions
Apply this patch Link, but replace "StartActivityWithExtra" with this
// External Player
bool CXBMCApp::StartActivityWithExtra(const string &package,const string &path)
{
if (!m_activity || !package.size())
return false;
jthrowable exc;
JNIEnv *env = NULL;
AttachCurrentThread(&env);
jobject oActivity = m_activity->clazz;
jclass cActivity = env->GetObjectClass(oActivity);


// Intent oIntent = new Intent(Intent.ACTION_VIEW);
jclass cIntent = env->FindClass("android/content/Intent");
jmethodID midIntentCtor = env->GetMethodID(cIntent, "<init>", "(Ljava/lang/String;)V");
jstring sIntentView = env->NewStringUTF("android.intent.action.VIEW"); // Intent.ACTION_VIEW
jobject oIntent = env->NewObject(cIntent, midIntentCtor, sIntentView);
env->DeleteLocalRef(sIntentView);
// 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(path.c_str());
jobject oUri = env->CallStaticObjectMethod(cUri, midUriParse, sPath);
env->DeleteLocalRef(sPath);
env->DeleteLocalRef(cUri);
// oIntent.setDataAndType(oUri, "video/*");
jmethodID midIntentSetDataAndType = env->GetMethodID(cIntent, "setDataAndType", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;");
jstring sMimeType = NULL;
sMimeType = env->NewStringUTF("video/*");
oIntent = env->CallObjectMethod(oIntent, midIntentSetDataAndType, oUri, sMimeType);
// 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);
env->DeleteLocalRef(sMimeType);
env->DeleteLocalRef(oUri);
env->DeleteLocalRef(cIntent);
env->DeleteLocalRef(sPackage);

// startActivity(oIntent);
jmethodID mStartActivity = env->GetMethodID(cActivity, "startActivity", "(Landroid/content/Intent;)V");
env->CallVoidMethod(oActivity, mStartActivity, oIntent);
env->DeleteLocalRef(cActivity);
env->DeleteLocalRef(oIntent);
exc = env->ExceptionOccurred();
if (exc)
{
CLog::Log(LOGERROR, "CXBMCApp::StartActivity Failed to load %s. Exception follows:", package.c_str());
env->ExceptionDescribe();
env->ExceptionClear();
DetachCurrentThread();
return false;
}
DetachCurrentThread();
return true;
}
// End External Player
The issue with the original code was the method "getLaunchIntentForPackage". This finds the first intent action for the package. The MX Player has both, MAIN and VIEW, but "getLaunchIntentForPackage" only finds the MAIN intent, and for this reason it doesn't work.

Build the source and install it on your device, and modify the playercorefactory.xml (which, according to XBMC Wiki is in Android/data/org.xbmc.xbmc/files/.xbmc/userdata/)

<playercorefactory>
<players>
<player name="MPC-HC" type="ExternalPlayer" audio="false" video="true">
<filename>com.inisoft.mediaplayer.a</filename>
<hidexbmc>true</hidexbmc>
</player>
</players>
<rules action="prepend">
<rule video="true" player="MPC-HC"/>
</rules>
</playercorefactory>

Replace the bold part with either for the corresponding version of the MXPlayer you have installed.

com.mxtech.videoplayer.pro - Pro Edition.
com.mxtech.videoplayer.ad - Free Edition.