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>
Related
So, I made an update in my android app and uploaded the new APK file in the console. Unfortunately, I got this after a few hours
I am using firebase, so maybe that's why I get this problem. Here is my manifest.xml file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="theodosios.tziomakas.news">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher_foreground"
android:label="#string/app_name"
android:largeHeap="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!--Disable Analytics collection -->
<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
<activity android:name="theodosios.tziomakas.news.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="theodosios.tziomakas.news.StartActivity"
/>
<activity
android:name="theodosios.tziomakas.news.RegisterActivity"
android:parentActivityName="theodosios.tziomakas.news.StartActivity" />
<activity
android:name="theodosios.tziomakas.news.LoginActivity"
android:parentActivityName="theodosios.tziomakas.news.StartActivity" />
<activity
android:name="theodosios.tziomakas.news.ForgotPasswordActivity"
android:parentActivityName="theodosios.tziomakas.news.LoginActivity" />
<receiver android:name="theodosios.tziomakas.news.widget.NewsAppWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/news_app_widget_info" />
</receiver>
<service android:name="theodosios.tziomakas.news.widget.UpdateNewsWidgetService" />
<service
android:name="theodosios.tziomakas.news.widget.GridWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<activity
android:name="theodosios.tziomakas.news.DetailActivity"
android:parentActivityName="theodosios.tziomakas.news.MainActivity" />
<provider
android:name="theodosios.tziomakas.news.data.FavouriteProvider"
android:authorities="theodosios.tziomakas.news"
android:exported="false" />
<activity
android:name="theodosios.tziomakas.news.FavouriteNewsActivity"
android:parentActivityName="theodosios.tziomakas.news.MainActivity" />
<activity android:name="theodosios.tziomakas.news.CommentActivity" />
</application>
Make sure you follow these policies listed here link
Also read all these and make change to your app if you app did not follow any of these policy link
As in the email they do not mention the reason for rejection clearly. So you have to hit and try what changes you made in this app which are agains the policy.
Before submiting another update check your dashboard of that app, if previous app is still under processing or not. If it is still under update process. Do not submit another update. Wait for sometime to reflect some changes.
After making changes in your app after reading the policies then make new update. Now after update rejection this new update will take 7 to 10 days. Be calm and have patience.
Bonus tip: Also make sure your app store listing do not go against any policy. SO make sure you are not using any icon, discription or short discription which are related to any brand like youtube, facebook, whatsapp any brand name should not be there. Also your long discription should be readable like a normal paragraph and it should not be spammy which is filled with full of tags only.
I have a live wallpaper which displays an image. I change that image in an activity. I then need to notify the live wallpaper, so it knows to reload the resources.
Intents seemed like the perfect, simple, solution:
Intent intent = new Intent(MyActivity.this, MyWallpaperService.class);
startService(intent);
I and in MyWallpaperService
#Override
public int onStartCommand (Intent intent, int flags, int startId) {...}
I also need to know, in another service, when the user taps the screen. I use the exact same mechanism of sending and receiving the intent.
Everything is working perfectly on Android 4.0+ devices and emulators.
But I tested on Android 2.2 and 2.3.3 emulator and get the following error:
java.lang.SecurityException: Not allowed to start service Intent { cmp=com.domain.name/.liveWallpaper.MyWallpaperService } without permission android.permission.BIND_WALLPAPER
My manifest contains the correct android:permission inside the service tag:
<service
android:name=".liveWallpaper.MyWallpaperService"
android:label="#string/app_name"
android:permission="android.permission.BIND_WALLPAPER" >
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/livewallpaper_data" />
</service>
Why do I get this error only on old versions(Android 2.2 and 2.3.3)? Is sending Intents to a WallpaperService not allowed or recommended? Does it have something to do with the fact that only the system can bind to a service with the BIND_WALLPAPER permission?
In the end, if intents do not work, what is an alternative, simple, solution?
try to add the permission to your Service in the manifest file , like the following :
<service android:name=".LiveWallpaper"
android:label="#string/app_name"
android:icon="#drawable/icon"
android:permission="android.permission.BIND_WALLPAPER">
Hope that Helps
java.lang.SecurityException: Not allowed to start service Intent {
cmp=com.domain.name/.liveWallpaper.MyWallpaperService } without
permission android.permission.BIND_WALLPAPER
means you probably forgot to declare the BIND_WALLPAPER permission within your AndroidManifest.xml like this:
<service
android:enabled="true"
android:name="MyWallpaperService"
android:permission="android.permission.BIND_WALLPAPER" />
Android Livewallpaper settings fail to load from 'configure...' menu
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.RrD"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<uses-feature android:name="android.software.live_wallpaper" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BIND_WALLPAPER" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
>
<service android:name=".LiveWallpaper"
android:label="#string/app_name"
android:icon="#drawable/icon"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper"
android:resource="#xml/livewallpaper" />
</service>
<activity android:label="PAM_Prefs"
android:name=".PAM_Prefs"
android:exported="true" android:icon="#drawable/icon">
<intent-filter>
<category android:name="android.intent.category.PREFERENCE" />
</intent-filter>
</activity>
</application>
</manifest>
I still haven't found a exact explanation for why this isn't working, but I found a solution:
Creating a BroadcastReceiver that will receive my custom Intents. This means I will no longer be using startService(intent), but sendBroadcast(intent), which will not cause permission issues.
See the references for more explanations and code.
References:
https://groups.google.com/forum/#!topic/android-developers/N8TzbbKwd5o
Permission to BIND_WALLPAPER required when messaging WallpaperService from Settings Activity
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).
I am trying to build an application that would replace a default action on Android. The problem is that when action should be performed i get "Select Action" dialog with no checkbox to select it as default. I think i should be getting "Complete Action Using" dialog (which in turn has the checkbox). I do not understand how I can make Android to offer me the "Complete ..." dialog. My manifest file is as:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="si.cetrtapot.mobiris"
android:versionName="1.0"
android:versionCode="1" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc"
android:required="true" />
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:debuggable="true" >
<activity android:name=".ReadTagActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc" />
</activity>
</application>
</manifest>
Can anybody tell me what is wrong?
The way intent-filters work is that the PackageManager has all these applications registered with it via the Manifest that is found per application. Specifically when an application falls un a certain Intent-Filter, it will then be added to the list of applications that have those kinds of Intent-Filters declared in their Manifest.
For instance say my application, handles the: Intent.ACTION_SEND this means that my application will show up in the list of application that hand particular action. Which would include, the default MMS/SMS application and any other applications the user has that has this, including MY application if the user has it installed.
You should begin by understanding what "default action" even means. Understanding this will help you how to solve your problem.
For your reference:
Intent
Intent.CATEGORY_DEFAULT
I do not believe that anything is wrong. I don't believe NFC intents were meant to have a default app unless you have very specific intent filtering for Ndef formatted cards. I did this for my job because we wanted just our app to pop up with our tag. Otherwise it would just be in a list all the time (which is annoying).
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.