2
0
Эх сурвалжийг харах

Add a simple Android samples launcher activity.

The launcher activity will only be shown when there are actually more samples built into the deployed apk. If no other samples then the launcher will just launch Urho3DPlayer without prompting. Otherwise a list view is presented in the launcher activity to let user to choose which sample library to be loaded.
Due to unloading of shared library is not supported from Java side, currently once a sample library is being loaded, the launcher cannot unload the library and let user to choose other samples. Until a workaround is found, user would have to perform a long pressed on a home button, close the app, and restart it again from scratch.
Yao Wei Tjong 姚伟忠 11 жил өмнө
parent
commit
10cbd8deed

+ 12 - 6
Source/Android/AndroidManifest.xml

@@ -1,21 +1,27 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.googlecode.urho3d"
+    package="com.github.urho3d"
     android:versionCode="1"
     android:versionCode="1"
     android:versionName="1.0">
     android:versionName="1.0">
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-feature android:glEsVersion="0x00020000" />
     <uses-feature android:glEsVersion="0x00020000" />
     <uses-sdk android:targetSdkVersion="9" android:minSdkVersion="9" />
     <uses-sdk android:targetSdkVersion="9" android:minSdkVersion="9" />
     <application android:label="@string/app_name" android:icon="@drawable/icon">
     <application android:label="@string/app_name" android:icon="@drawable/icon">
-        <activity android:name="Urho3D"
-                  android:label="@string/app_name"
-                  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-                  android:configChanges="keyboardHidden|orientation"
-                  android:screenOrientation="landscape">
+        <activity
+            android:name=".SampleLauncher"
+            android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize"
+            android:noHistory="true"
+            android:screenOrientation="portrait">
             <intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
             </intent-filter>
         </activity>
         </activity>
+        <activity android:name=".Urho3D"
+                  android:label="@string/app_name"
+                  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+                  android:configChanges="keyboardHidden|orientation"
+                  android:screenOrientation="landscape">
+        </activity>
     </application>
     </application>
 </manifest>
 </manifest>

BIN
Source/Android/res/drawable/logo_large.png


+ 0 - 8
Source/Android/res/layout/main.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="horizontal"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    >
-</LinearLayout>
-

+ 25 - 0
Source/Android/res/layout/samples_list.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <ImageView
+        android:id="@+id/imageView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:src="@drawable/logo_large" />
+
+    <ListView
+        android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1" />
+
+    <TextView
+        android:id="@android:id/empty"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="No activities" />
+
+</LinearLayout>

+ 11 - 0
Source/Android/res/layout/samples_list_text_view.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:fontFamily="sans-serif"
+    android:gravity="center_vertical"
+    android:paddingBottom="14dp"
+    android:paddingLeft="24dp"
+    android:paddingTop="14dp"
+    android:textSize="22sp" />

+ 78 - 0
Source/Android/src/com/github/urho3d/SampleLauncher.java

@@ -0,0 +1,78 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+package com.github.urho3d;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+public class SampleLauncher extends ListActivity {
+
+    public static final String LIBRARY_NAMES = "LIBRARY_NAMES";
+    public static final String PICKED_LIBRARY = "PICKED_LIBRARY";
+    private static final int OBTAINING_LIBNAMES = 1;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Start Urho3D activity with the intention for obtaining the library name(s)
+        startActivityForResult(new Intent(this, Urho3D.class), OBTAINING_LIBNAMES);
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+        // Prepare a list view for picking the sample library names
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.samples_list_text_view);
+        setContentView(R.layout.samples_list);
+        setListAdapter(adapter);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        // The cancel result code means there are no multiple library names to choose from
+        if (OBTAINING_LIBNAMES != requestCode || RESULT_CANCELED == resultCode)
+            return;
+
+        // Populate the list view with library names as pickable items
+        String[] libraryNames = data.getStringArrayExtra(LIBRARY_NAMES);
+        @SuppressWarnings("unchecked")
+        ArrayAdapter<String> adapter = (ArrayAdapter<String>) getListAdapter();
+        for (final String name : libraryNames)
+            adapter.add(name);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        // Start Urho3D activity with the intention to load the picked library name
+        @SuppressWarnings("unchecked")
+        ArrayAdapter<String> adapter = (ArrayAdapter<String>) getListAdapter();
+        startActivity(new Intent(this, Urho3D.class).putExtra(PICKED_LIBRARY, adapter.getItem(position)));
+    }
+
+}

+ 80 - 0
Source/Android/src/com/github/urho3d/Urho3D.java

@@ -0,0 +1,80 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+package com.github.urho3d;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import org.libsdl.app.SDLActivity;
+
+import android.content.Intent;
+
+public class Urho3D extends SDLActivity {
+
+    @Override
+    protected boolean onLoadLibrary(ArrayList<String> libraryNames) {
+        // Ensure "Urho3D" (in case of Urho3D shared lib type is used) and "Urho3DPlayer" are being sorted to the top of the list 
+        Collections.sort(libraryNames, new Comparator<String>() {
+            private String sortName(String name) {
+                return name.startsWith("Urho3D") ? "00_" + name : name;
+            }
+
+            @Override
+            public int compare(String lhs, String rhs) {
+                return sortName(lhs).compareTo(sortName(rhs));
+            }
+        });
+
+        // Urho3D shared library must always be loaded if available, so exclude it from return result and all list operations below 
+        int startIndex = "Urho3D".equals(libraryNames.get(0)) ? 1 : 0;
+
+        // Determine the intention
+        Intent intent = getIntent();
+        String pickedLibrary = intent.getStringExtra(SampleLauncher.PICKED_LIBRARY);
+        if (pickedLibrary == null) {
+            // Intention for obtaining library names
+            String[] array = libraryNames.subList(startIndex, libraryNames.size()).toArray(new String[libraryNames.size() - startIndex]);
+            if (array.length > 1) {
+                setResult(RESULT_OK, intent.putExtra(SampleLauncher.LIBRARY_NAMES, array));
+
+                // End Urho3D activity lifecycle
+                finish();
+
+                // Return false to indicate no library is being loaded yet
+                return false;
+            } else {
+                // There is only one library available, so cancel the intention for obtaining the library name and by not returning any result
+                // However, since we have already started Urho3D activity, let's the activity runs its whole lifecycle by falling through to call the super implementation 
+                setResult(RESULT_CANCELED);
+            }
+        } else {
+            // Intention for loading a picked library name (and remove all others)
+            libraryNames.subList(startIndex, libraryNames.size()).clear();
+            libraryNames.add(pickedLibrary);
+        }
+
+        return super.onLoadLibrary(libraryNames);
+    }
+
+}

+ 0 - 5
Source/Android/src/com/googlecode/urho3d/Urho3D.java

@@ -1,5 +0,0 @@
-package com.googlecode.urho3d;
-
-import org.libsdl.app.SDLActivity;
-
-public class Urho3D extends SDLActivity {}

+ 17 - 6
Source/Android/src/org/libsdl/app/SDLActivity.java

@@ -3,6 +3,7 @@
 package org.libsdl.app;
 package org.libsdl.app;
 
 
 import java.io.File;
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Comparator;
 
 
@@ -45,9 +46,16 @@ public class SDLActivity extends Activity {
     protected static AudioTrack mAudioTrack;
     protected static AudioTrack mAudioTrack;
 
 
 
 
-    // Urho3D: flag to load the .so
+    // Urho3D: flag to load the .so and a new method load them
     private static boolean mIsSharedLibraryLoaded = false;
     private static boolean mIsSharedLibraryLoaded = false;
 
 
+    protected boolean onLoadLibrary(ArrayList<String> libraryNames) {
+        for (final String name : libraryNames) {
+            System.loadLibrary(name);
+        }
+        return true;
+    }
+
     // Setup
     // Setup
     @Override
     @Override
     protected void onCreate(Bundle savedInstanceState) {
     protected void onCreate(Bundle savedInstanceState) {
@@ -68,12 +76,14 @@ public class SDLActivity extends Activity {
                     return Long.valueOf(lhs.lastModified()).compareTo(rhs.lastModified());
                     return Long.valueOf(lhs.lastModified()).compareTo(rhs.lastModified());
                 }
                 }
             });
             });
+            ArrayList<String> libraryNames = new ArrayList<String>(files.length);
             for (final File libraryFilename : files) {
             for (final File libraryFilename : files) {
                 String name = libraryFilename.getName().replaceAll("^lib(.*)\\.so$", "$1");
                 String name = libraryFilename.getName().replaceAll("^lib(.*)\\.so$", "$1");
                 //Log.v(TAG, "library name: " + name);
                 //Log.v(TAG, "library name: " + name);
-                System.loadLibrary(name);
-            }            
-            mIsSharedLibraryLoaded = true;
+                libraryNames.add(name);
+            }
+            if (onLoadLibrary(libraryNames))
+                mIsSharedLibraryLoaded = true;
         }
         }
 
 
         // Set up the surface
         // Set up the surface
@@ -123,8 +133,9 @@ public class SDLActivity extends Activity {
     protected void onDestroy() {
     protected void onDestroy() {
         super.onDestroy();
         super.onDestroy();
         Log.v("SDL", "onDestroy()");
         Log.v("SDL", "onDestroy()");
-        // Send a quit message to the application
-        SDLActivity.nativeQuit();
+        // Urho3D - Send a quit message to the application only when native library has been loaded
+        if (mIsSharedLibraryLoaded)
+            SDLActivity.nativeQuit();
 
 
         // Now wait for the SDL thread to quit
         // Now wait for the SDL thread to quit
         if (mSDLThread != null) {
         if (mSDLThread != null) {

+ 3 - 3
Source/CMakeLists.txt

@@ -144,9 +144,9 @@ add_subdirectory (Engine)
 add_subdirectory (Tools)
 add_subdirectory (Tools)
 
 
 # Urho3D samples
 # Urho3D samples
-# Samples are built on iOS platform too when enabled
-# Although samples should also work for Android platform, currently there is no available mechanism to package each sample apps into individual *.apk
-if (NOT ANDROID AND ENABLE_SAMPLES)
+# Samples are built on iOS platform too when enabled. Currently there is no available mechanism to package each sample apps into individual *.apk
+# for Android platform, so we deploy all samples into one apk and use a simple list view activity launcher to select the sample to run
+if (ENABLE_SAMPLES)
     add_subdirectory (Samples)
     add_subdirectory (Samples)
 endif ()
 endif ()
 
 

+ 1 - 1
Source/Samples/CMakeLists.txt

@@ -64,4 +64,4 @@ add_subdirectory (23_Water)
 add_subdirectory (24_Urho2DSprite)
 add_subdirectory (24_Urho2DSprite)
 add_subdirectory (25_Urho2DParticle)
 add_subdirectory (25_Urho2DParticle)
 add_subdirectory (26_ConsoleInput)
 add_subdirectory (26_ConsoleInput)
-add_subdirectory (27_Urho2DPhysics)
+add_subdirectory (27_Urho2DPhysics)