Resources

Use the Dev Guide to learn about specific features and how best to integrate these into your app.

Extending Unity Android Activity and Adding Custom Views in Eclipse

This article explains how to integrate a QCAR Unity project for Android with the Eclipse IDE and how to extend the main activity to enable adding custom Android views on top of the Unity view.

Integration steps

  1. Create a Vuforia Unity project using the Unity Editor.
  2. Build the project for the Android platform; when doing so, open the "Player settings" and take note of the package name that you have chosen as your "Bundle Identifier" (e.g., "com.my.org") and the Android API level (e.g., 2.3 "Gingerbread"), as you will reuse these settings later.
  3. Save the APK file when asked by Unity, giving it the name you want (name is not relevant).
  4. Use your file explorer to browse to your Unity project directory, where there is a folder called "/Temp" containing a subfolder called "/StagingArea." Open the StagingArea folder to see a set of files and directories (such as /res, /assets, /bin,  AndroidManifest.xml,...) as in a typical Android project.
  5. Copy the content of the StagingArea folder to another location on your file system (for instance, a location like "C:\Development\Android\Unity\MyVuforiaUnityProject" or similar). Any location is fine, as long as it is not under the original Temp folder of your Unity project.
  6. Open Eclipse, and create a new Android project "from existing source"; click Browse and point to the folder where you just copied the StagingArea content (see last step).
  7. Give the project a name, for instance, "QCARUnity."
  8. Right-click the QCARUnity project, select Properties, select Android and tick the "IsLibrary" checkbox (i.e., make the project a library); press Apply/OK.
  9. Create another new project and name it, for instance, "QCARJava"; be sure to select the same package name and the same API level that you previously selected when building your Unity project with the Unity Editor.
  10. Right-click the "QCARJava" project, select Properties > Java build Path > Libraries, click Add External Jars... and point to Editor\Data\PlaybackEngines\androidplayer\bin\classes.jar under your Unity installation directory, then press OK.
  11. Right-click QCARJava again and select Properties > Android, scroll the page down until you see a Reference Projects table, and add the "QCARUnity" project to the list of referenced projects.
  12. Move the "/assets" and "/libs" folders from the "QCARUnity" project directory to the "QCARJava" project folder.
  13. Copy Vuforia.jar and QCARUnityPlayer.jar from the "/plugins" directory of the "QCARUnity" project to the "/libs" folder of the "QCARJava" project.
  14. Copy the "/QCAR" folder (this should contain your Dataset .XML/.DAT files) from the "/raw" directory of the "QCARUnity"  project to the "/assets" folder of the "QCARJava" project.
  15. Copy the AndroidManifest.xml file from "QCARUnity" to the "QCARJava" project (overwrite the existing AndroidManifest.xml file).

Code changes

Finally, make the following small code changes in the main source file of the "QCARJava" project (where your main activity is defined):

  1. Make your main activity class (e.g., "QCARJavaActivity") extend from QCARPlayerNativeActivity (instead of extending from Activity).
  2. Press Ctrl+Shift+O to adjust the imports automatically.
  3. Remove the line "setContentView(R.layout.main)."
  4. Edit the AndroidManifest.xml file of your QCARJava project; replace the name of the main activity, which is set to "com.qualcomm.QCARUnityPlayer.QCARPlayerNativeActivity" with the name of your actual main activity, e.g., "com.my.org.QCARJavaActivity."

Allow native events forwarding via the ForwardNativeEventsToDalvik setting in the manifest (must be set to true).

<activity android:name="com.my.org.QCARJavaActivity" android:label="@string/app_name"
android:screenOrientation="portrait" android:configChanges="fontScale|keyboard|keyboardHidden|
locale|mnc|mcc|navigation|orientation|screenLayout|uiMode|touchscreen">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
  <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
</activity>

You are now ready to build and run your Android project in your device from Eclipse.

Tip: if you get ClassDefNotFound (or similar) runtime errors, you might need to perform this extra step:

  1. Go to the Project > Properties > Java Build Path > Order and Export tab, and check (tick) the classes.jar, Android x.y and Android Dependencies items.
  2. Apply and rebuild the probject. 

Adding your custom Android views/layouts on top of the QCAR-Unity view

To programmatically add your own views/layouts on top of the existing QCAR Unity view, you need to:

  1. Scan the view hierarchy recursively (starting from the root view of your main activity) and find the leaf view in the hierarchy.
  2. Once you find the leaf view, get the parent of that view; let's call this view leafParent for ease of reference.
  3. Add your custom views (e.g., a layout inflated from xml) as a child of the leafParent view.

The following code snippet shows a possible way of doing this:

public class QCARJavaActivity extends QCARPlayerNativeActivity {
     
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.activity_main);
         
        final long delay = 5000;//ms
       
        Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            public void run() {
                ViewGroup rootView = (ViewGroup)QCARJavaActivity.this.findViewById
                (android.R.id.content);
                 
                // find the first leaf view (i.e. a view without children)
                // the leaf view represents the topmost view in the view stack
                View topMostView = getLeafView(rootView);
                 
                // let's add a sibling to the leaf view
                ViewGroup leafParent = (ViewGroup)topMostView.getParent();
                Button sampleButton = new Button(QCARJavaActivity.this);
                sampleButton.setText("Press Me");
                leafParent.addView(sampleButton, new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT));
                 
            }
        };
         
        handler.postDelayed(runnable, delay);
    }   
     
    private View getLeafView(View view) {
        if (view instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup)view;
            for (int i = 0; i < vg.getChildCount(); ++i) {
                View chview = vg.getChildAt(i);
                View result = getLeafView(chview);
                if (result != null) 
                    return result;
            }
            return null;
        }
        else {
            DebugLog.LOGE("Found leaf view");
            return view;
        }
    }

 

Keywords: Android, Unity, Eclipse