Air for Android - How to receive content from other apps? - android

I'm building an Android app with Adobe Air 3.6 and Flash CS 6.
Is it possible to receive content from other apps, e.g. a link from the browser?
I couldn't find a working example anywhere yet.

You can add all the intents you need in the proper section of your app descriptor. Look for the android-related section:
...
<android>
<manifestAdditions>
<![CDATA[
<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature android:required="true" android:name="android.hardware.touchscreen.multitouch"/>
<application android:enabled="true">
<activity android:excludeFromRecents="false">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- ADD INTENTS HERE -->
</activity>
</application>
</manifest>
]]>
</manifestAdditions>
<!-- Color depth for the app (either "32bit" or "16bit"). Optional. Default 16bit before namespace 3.0, 32bit after -->
<!-- <colorDepth></colorDepth> -->
</android>
...
Please note this is only half of the story. In order to properly consume those intents you should handle them in your code, something like this:
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE,onInvoke);
...
function onInvoke(event:InvokeEvent):void
{
/* handle your intent here */
}
Please refer to official docs here.

Related

React Native Deep Linking Application Not Opening

I followed all the steps from both the articles mentioned below
https://hackernoon.com/react-native-deep-linking-for-ios-and-android-d33abfba7ef3
https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e
After the app gets installed on my phone, I tried opening the app from the browser by giving the URL as peopleapp://people/1 format. Instead of opening the app, the browser opens Google search to search for the above.
I Used this application to open my Application by using my App Link(https://play.google.com/store/apps/details?id=com.manoj.dlt&hl=en_US) it's working.
But how to open the application from browser or from another application Using my App Link ?
Anyone has idea, how to solve this issue ?
Here is my Total AndroidManifest Code`
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".MainApplication"
android:allowBackup="false"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:label="#string/app_name"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="filter_react_native">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="whizzard" android:host="article" />
</intent-filter>
</activity>
</application>
`
My Link is whizzard://article
As per google docs:
The functionality has changed slightly in Chrome for Android, versions 25 and later. It is no longer possible to launch an Android app by setting an iframe's src attribute. For example, navigating an iframe to a URI with a custom scheme such as paulsawesomeapp:// will not work even if the user has the appropriate app installed. Instead, you should implement a user gesture to launch the app via a custom scheme, or use the “intent:”.
You can read more about how intents work here. However, the tutorial you followed, for deeplinking will work on other browsers which are not chrome or chrome based.

Android NFC: How to route APDUs for one certain AID to secure element UICC (Off-Host-Routing)

I have a SIM card with an applet (cardlet) on it. If I can set the default secure element in an Android device to UICC I can send commands via contactless interface to UICC.
My NFC reader sends an APDU with a "SELECT AID A0000001234567890" to the NFC controller which shall send it to my applet on the UICC secure element (access control has been taken care of).
Now I want to make this work for devices where I cannot set the default secure element to UICC.
If I understood everything correctly, as I do not need an Android application for this in principle, I nevertheless have to make use of a dummy Android application and declare a so-called "off-host service" in its manifest.
Can someone guide me what I need to do to route the APDUs that select the AID of my applet installed on the secure element and the subsequent APDUs to the UICC secure element?
Here is my first attempt, but maybe someone has a working example for me or some guidance/corrections.
AndroidManifest.xml:
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
<service android:name=".OffHostApduService" android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/>
</intent-filter>
<meta-data android:name="android.nfc.cardemulation.off_host_apdu_service"
android:resource="#xml/apduservice"/>
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
</service>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Echo">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<uses-library
android:name="com.android.nfc_extras"
android:required="true" />
</activity>
</application>
apduservices.xml:
<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="#string/servicedesc">
<aid-group android:description="#string/subscription" android:category="payment">
<aid-filter android:name="A0000001234567890"/>
</aid-group>
</offhost-apdu-service>
Your start looks fine and using an offhost-apdu-service should work fine on devices that support routing card emulation communication to a secure element. Note that some devices simply do not support this though.
There are some issues with your XML files though:
A card emulation service in category payment must declare a service banner drawable resource. The service banner should be a graphic file (e.g. a .png file) with dimensions of 260 x 96 pixels.
<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="#string/servicedesc"
android:apduServiceBanner="#drawable/servicebanner">
<aid-group android:category="payment"
android:description="#string/servicedesc" >
<aid-filter ... />
</aid-group>
</offhost-apdu-service>
Services must be declared within the application tag in your manifest file (note that I also change the name of the service to avoid conflicts with the naming of the framework class):
<application ...>
<activity ...>
...
</activity>
<service android:name=".MyOffHostApduService" android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE" />
</intent-filter>
<meta-data android:name="android.nfc.cardemulation.off_host_apdu_service"
android:resource="#xml/apduservice" />
</service>
</application>
Besides declaring the service in your manifest, you also need to actually create the Java implementation for the service. Something like:
public class MyOffHostApduService extends OffHostApduService {
public IBinder onBind(Intent intent) {
return null;
}
}
<uses-feature ...> and <uses-permission ...> elements must be direct child elements of the <manifest> element (i.e. on the same level as the <application ...> element. They must not be used inside other tags (like the service tag in your case):
<manifest ...>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
<application ...>
The <uses-library ...> element must be a direct child of the <application ...> element. However, you probably don't use this library anyways and can completely drop that.
Finally, note that the AID in your example is not valid since it does not align on full bytes. A valid AID would, for example, be A00000012345678900. (Though I assume that this just happend during masking your original AID for the example, right?)

Android manifest for USBAccesory

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>

Finding the "Android class name" in "AndroidManifest.xml" generated by Unity3D

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).

Can Manifest Receiver for In app payment be moved to Java code instead?

Google example for in-app payment suggests to add the manifest entry in order to receive the payment confirmations. But in Native Extension for AIR, the receiver will not be found as its a different package. So i moved the receiver part to code as follows
final IntentFilter filter = new IntentFilter("com.android.vending.billing.IN_APP_NOTIFY");
filter.addAction("com.android.vending.billing.RESPONSE_CODE");
filter.addAction("com.android.vending.billing.PURCHASE_STATE_CHANGED");
a.registerReceiver(billingReceiver, filter);
But the service's onreceive() method never gets called.
Is there a different way of registering the activity to get receiver calls?
According to some reference sites, adding the billing receiver in code doesn't work. So moved it to manifest file, removed the package and referred it from the root directory. So problem solved.
Manifest for AIR app would look like this for more info for those who are trying out!
<android>
<manifestAdditions>
<![CDATA[
<manifest android:installLocation="auto">
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application>
<service android:name="<package>.BillingService" />
<receiver android:name="<package>.BillingReceiver">
<intent-filter>
<action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
<action android:name="com.android.vending.billing.RESPONSE_CODE" />
<action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />
</intent-filter>
</receiver>
</application>
</manifest>]]>
</manifestAdditions>
</android>

Categories

Resources