When configuring a "Android Native App" in a Facebook app, they require the Android Class Name. If you created the Android APK from Unity3D, how do you know what class to use?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="--------------" android:versionName="1.02" android:versionCode="8">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<application android:icon="#drawable/app_icon" android:label="#string/app_name" android:debuggable="true">
<activity android:name="com.unity3d.player.UnityPlayerProxyActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="landscape">
</activity>
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="landscape">
<meta-data android:name="android.app.lib_name" android:value="unity" />
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
</activity>
<activity android:name="com.unity3d.player.VideoPlayer" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="landscape">
</activity>
<!-- ACTIVITIES -->
<activity android:name="com.prime31.FacebookProxyActivity" />
<!-- META-DATA -->
</application>
<!-- PERMISSIONS -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:glEsVersion="0x00020000" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.sensor.accelerometer" />
<uses-feature android:name="android.hardware.touchscreen" />
<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />
</manifest>
This field should be your main activity (associated with MAIN and LAUNCHER). In this case, I think it would be com.unity3d.player.UnityPlayerProxyActivity.
This is mainly necessary if you use native deep links (so the FB app can create an intent that directly calls your activity). In that respect, any publicly accessible Activity in your app will do.
The main activity's tag should contain an intent-filter tag with the action android.intent.action.MAIN and the category android.intent.category.LAUNCHER.
Description of the intent-filter tag (from documentation):
Specifies the types of intents that an activity, service, or broadcast
receiver can respond to. An intent filter declares the capabilities of
its parent component — what an activity or service can do and what
types of broadcasts a receiver can handle. It opens the component to
receiving intents of the advertised type, while filtering out those
that are not meaningful for the component. Most of the contents of the
filter are described by its <action>, <category>, and <data>
subelements.
For a more detailed discussion of filters, see the separate Intents
and Intent Filters document, as well as the Intents Filters section in
the introduction.
The main activity of an Android application has an intent-filter with the category LAUNCHER which basically tells that the activity can "launch the app" (in other words, that it is the launcher/entry).
The activity tag should look something like this:
<activity android:name="ActivityClassName" android:label="Activity title">
<!-- The intent filter -->
<intent-filter>
<!-- The action -->
<action android:name="android.intent.action.MAIN"/>
<!-- The category -->
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
By looking at your AndroidManifest.xml, you can conclude that the main Activity of your app is the com.unity3d.player.UnityPlayerProxyActivity Activity, because it contains an intent-filter matching those criterias.
Good luck with your game!
Using "UnityPlayerProxyActivity" is no longer true for all unity versions. You may have to use "UnityPlayerActivity" instead.
Details:
If you export an Android project from unity you may find three classes in src:
UnityPlayerActivity
UnityPlayerNativeActivity
UnityPlayerProxyActivity
"UnityPlayerProxyActivity" and "UnityPlayerNativeActivity" have been deprecated since Unity 5.0 beta12, thus you have to use "UnityPlayerActivity" instead.
In Facebook type in:
[tld.yourdomain.game].UnityPlayerActivity
Replace the [...] part with your app specifics of course. Attention: If you have some plugins/extensions that fiddle around with your manifest, then this may be different.
UPDATE:
In newer Versions of the Facebook SDK for Unity (tested with 7.9.4) you can simply search for "FacebookSettings" in your Assets folder and it will tell you what Class Name to use ("com.facebook.unity.FBUnityDeepLinkingActivity" for example).
Related
I've read countless StackOverflow posts, answers and the Android documentation. Yet. I still can't wrap my head around how to achieve the following.
I wish to make an app, the does something when a new SMS text is received, regardless, if the app itself, is in the foreground (user is currently in the app using it), is in the background (user switched to another app but the app is still open so to speak) or closed (user has for example restarted the phone and not opened the app since restart).
I have a broadcast receiver with permissions, but the app only works if the app is in the foreground or the background. If the app is closed, it does not do anything when a SMS is received.
The term background app, "long running background service" etc. in android terminology is confusing and is probably the reason why I haven't figured out what it is I am looking for. Perhaps if someone could explain the three states proper naming or explain how to do what I wish to achieve that would be dandy!
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="__PACKAGE__"
android:versionCode="10000"
android:versionName="1.0">
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:enabled="true"
android:name="com.tns.NativeScriptApplication"
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name="com.tns.NativeScriptActivity"
android:label="#string/title_activity_kimera"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode"
android:theme="#style/NoActionBar">
<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="#style/AppTheme" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.tns.ErrorReportActivity"/>
<receiver
android:name="io.basickarl.passer.HandleSMS" android:exported="true" android:enabled="true">
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
I am making an app that communicates with a piece of usb hardware made by my company (this is the only app allowed to talk to the usb accessory, it's not a public api). I am having difficulties setting up the proper launch modes in the manifest.
There are three components to the app: the main activity, a login activity, and the USBService.
I'm assuming the intent for the main goes to the login activity, and the intent for the usb goes to the USBService, but I am not sure if I do this, will this start the service if the app is not running? More over, if it does, how do I fetch an already existing service?
What type of structure should I be looking at for the manifest file? (specifically, intent-filters, and appropriate launch modes... I've read a few documents about the launch modes but I am still not sure I quite understand... There should only ever be at most one instance of each activity/service, and they need to communicate together.
edit: it is not necessary for communications to start before the app is open, nor is it necessary to launch the app automatically when the usb is connected.
edit: my manifest as it stands, looks like:
<uses-feature android:name="android.hardware.usb.accessory" />
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="mainpackage.MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="#xml/accessory_filter" />
</activity>
<activity
android:name="mainpackage.LoginActivity"
android:label="#string/title_activity_login"
android:windowSoftInputMode="adjustResize|stateVisible" >
</activity>
<service android:name="updater.USBService"
android:exported="false" >
<!--
-->
</service>
</application>
in your manifest add
<manifest ...>
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="12" />
In this case, the following resource file should be saved in res/xml/device_filter.xml and specifies that any USB device with the specified attributes should be filtered:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" />
</resources>
Hope this help.
Your manifest looks good,
I think you make a good choice for putting the intent-filter "android.hardware.usb.action.USB_ACCESSORY_ATTACHED" in the mainActivity and start the application in this activity,
and again I think it's a good choice to start your mainActivity in SingleTop launch mode,
because if an instance of the mainActivity already exists at the top of the current task, the system going to launch this activity, no new instance of this activity will be created.
For a best understanding of the different launch mode available in android,
I think this link may help you :
http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode
To make a long story short I think you'll be all set with this manifest as is.
To Use Android Devices min SDK version should be set to 12 and need to declare following line in AndroidManifest.xml file
<>
<uses-sdk android:minSdkVersion="<version>" />
...
<application>
<uses-library android:name="com.android.future.usb.accessory" />
<activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="#xml/accessory_filter" />
</activity>
</application>
I've got the following situation with a Phonegap 2.9 Android app:
I declared a custom intent so that the app can be opened from a website.
From within the app, I call an external site I control with a form.
On the page of the external site there's a button that is using the custom intent URL to get back to the app.
This construction works for the iOS version of the app, also using Phonegap.
However, for the Android version the popup of Android is saying it doesn't recognizes the custom URL / intent. When I open my browser and navigate to the same external site and pushes the back button with the custom intent-URL, the app gets started.
After searching hours and hours on stackoverflow and the internet in general, I still can't figure out why it isn't working like expected.
Perhaps good to know is that both the app and the external site are using jQuery Mobile.
The external site is opened from the app using
navigator.app.loadUrl('https://site.external/');
The page is on a HTTPS / SSL location, does this makes any difference?
The manifest looks like this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="com.test.app" android:versionName="1.0" android:versionCode="1" android:hardwareAccelerated="true">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/>
<application android:icon="#drawable/icon" android:label="#string/app_name"
android:hardwareAccelerated="true"
android:debuggable="true"
android:allowBackup="false">
<activity android:name="AppName" android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:exported="true"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="customurl" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity
android:name="org.apache.cordova.DroidGap"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden">
<intent-filter></intent-filter>
</activity>
</application>
</manifest>
The code in the external page is using javascript to prevent possible problems with Google automatic search:
window.location = 'customurl://back/';
The error I receive when pushing the button with the custom intent:
Application Error
The protocol is not supported. (customurl://back/)
So, how do I get the external website which was accessed from the app to start the app again, so the user gets back to the app? The only possibility I can think of after searching for hours and hours is to close the app when the user navigates away to the external site.
I think you might need to set a host in the intent filter also:
<data android:scheme="customurl" />
<data android:host="somewebsite.com" />
Can you check to see if that makes a difference?
I wrote my own dictionary definition words in my dictionary application. But whenever i launching my dictionary application in my emulator default android dictionary working won't working my app dictionary. I changed all the provider permission,manifest file all those things. But dictionary not working.
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.searchbook"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_dictionary"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- The default activity of the app; displays search results. -->
<activity android:name=".SearchBook"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Receives the search request. -->
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<!-- No category needed, because the Intent will specify this class component-->
</intent-filter>
<!-- Points to searchable meta data. -->
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
<!-- Displays the definition of a word. -->
<activity android:name=".WordActivity" />
<!-- Provides search suggestions for words and their definitions. -->
<provider android:name=".DictionaryProvider"
android:authorities="com.example.searchbook.DictionaryProvider" />
<!-- Points to searchable activity so the whole app can invoke search. -->
<meta-data android:name="android.app.default_searchable"
android:value=".SearchBook" />
</application>
</manifest>
"com.example.searchbook" seems like convention of android for sample apps. There may be an existing app named exactly like that. As you pointed out it launches the default. Try to refactor it to something else like "com.stackoverflow.karthi".
Situation:
I need to combine several apps into one .apk app. Lets say implement app2 into app1
What i have done:
Copied app2 package into main app1 project which i am working, so my app1 has two packages.
app2 had this manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package.app2" android:versionCode="3" android:versionName="1.2">
<application android:label="App2" android:icon="#drawable/icon">
<activity android:name="Activity1" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="Activity2" android:excludeFromRecents="true"></activity>
</application>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
</manifest>
My original App1 manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package.app1">
<application android:icon="#drawable/icon" android:debuggable="true">
<activity android:name=".Start" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.package.app1.PlayerList" />
<activity android:name="com.package.app1.CreateNewPlayer" />
<activity android:name="com.package.app1.Profile" />
<activity android:name="com.package.app1.Braintrainer" />
</application>
</manifest>
The code in app1 i am using to call activity in app2 package:
Intent i = new Intent();
i.setClassName("com.package.app1", "com.package.app2.Activity1");
startActivity(i);
The question:
How do i modify my app1 manifest file to have activities of app2.
Things i`ve tried:
It works if i create simple HelloWorld test class in app2, call using the same code and just include this in the app1 manifest:
<activity android:name="com.package.app2.Test" />
But i can not figure out how to implement the app2 manifest file into the first one. Every way i try give no errors but crashes when calling that activity. App2 alone works fine, so problem not in the activity file.
Appreciate any thoughts on this.
Intent i = new Intent();
i.setClassName("com.package.app1", "com.package.app2.Activity1");
startActivity(i);
Shot in the dark:
change com.package.app1 to com.package.app2. I've called done what you're attempting right now, and I've always had to specify the package of the class I wanted to call.
Ok, PackageManager is not your solution, I misread and thought you had two apps and wanted one app to call the other. It looks like you just want one app.
Modify your app1's manifest like this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package.app1">
<application android:icon="#drawable/icon" android:debuggable="true">
<activity android:name=".Start" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.package.app2.Activity1" />
<activity android:name="com.package.app2.Activity2" android:excludeFromRecents="true"></activity>
<activity android:name="com.package.app1.PlayerList" />
<activity android:name="com.package.app1.CreateNewPlayer" />
<activity android:name="com.package.app1.Profile" />
<activity android:name="com.package.app1.Braintrainer" />
</application>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
</manifest>
And try the first way again.
I have several packages and need to do something similar in my app.
You need to be careful with this technique, otherwise you'll experience nasty memory leaks.
I declared my activity in my base controller (activity) class as a static variable. All controller classes inherit from this class, so all controller classes are able to access it. Pass in the activity as an argument for anything outside of the controller classes that need to access the activity.