Android App should NOT launch on receiving Intent - android

I have written an Android Application and the generated .APK file I uploaded in Android Market. So, a User can download that apk and install in his device.How can I restrict my apk to launch , if he calls from other application through Intent. That means my application should not respond to any intents from other outside Applications.
Is there any possible way to restrict my application's launch from intents from other application.?
I will be waitinig for reply.
Thanks in Advance,

Try setting android:exported="false" to all activities defined at AndroidManifest.xml
That's from activity element description:
android:exported Whether or not the activity can be launched by components of other applications — "true" if it can be, and "false" if not. If "false", the activity can be launched only by components of the same application or applications with the same user ID.
The default value depends on whether the activity contains intent filters. The absence of any filters means that the activity can be invoked only by specifying its exact class name. This implies that the activity is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the activity is intended for external use, so the default value is "true". This attribute is not the only way to limit an activity's exposure to other applications. You can also use a permission to limit the external entities that can invoke the activity (see the permission attribute).
Also here are good paragraphs about application permissions https://developer.android.com/training/articles/security-tips.html I guess you can use that to restrict access to your app.

Related

Why do we get these "invalid" intents?

We have an app with an Activity that can be started in two ways:
From another Activity - always with some extra data filled in
From deep linking
As far as I can see this is always working just fine. We either get the Intent.ACTION_VIEW with a data URI, or we get some string extras.
However, we have a very few instances where action is Intent.ACTION_MAIN and there are no extra data.
The toString() of the Intent is as follows (class name changed):
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10400000 cmp=com.example.OurActivity }
Intent.getExtras() returns null, Intent.getDataString() returns null.
In which cases can this happen? Why is the category for the Activity Intent.CATEGORY_LAUNCHER? How can we get the data needed to show the user the right contents?
launchMode is not specified for the Activity. The only IntentFilter in AndroidManifest.xml is for the deep linking (and not the launcher category).
The issue happens on Android 4-6 on a wide range of devices.
Edit: Forgot to mention the flags:
As the print out suggests the flags for the Intent are FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_BROUGHT_TO_FRONT. I suppose that could be relevant here.
I believe, I nailed it:
There're launchers, like Nova Launcher which allows users to start with any of app's Activities, instead of the normal flow:
For example, you can add a shortcut on your desktop to start Gmail client with Account setup Activity.
And in this case, Activity is being started with empty Extras and technically it becomes a launcher's Activity.
Now that AndroidManifest.xml is manipulated by the build system, it often happens that libraries that you include also add things to the manifest, which I suspect may be happening here.
Although you state that there is only one IntentFilter in the manifest, have you actually checked the installed app to see what its manifest says (rather than relying on what you think you put in your source code)?
Various apps are available in the Play Store to show you the manifest of an installed app - including App Detective (which I wrote).

Can an app start a component in another app through explicit intent?

Can App A start a component in App B through explicit intent?
I understand that general use of an explicit intent is to start a component within the same app. Implicit intents are used to cross process boundary.
Scenario:
App B defines and uses a custom permission "foo"
App A uses
PackageManager API to identify App B (app which defined "foo")
Can App A start a component within App B through explicit intent?
I don't think this is possible because explicit intent needs- app package and component name.
if (PackageManager.PERMISSION_GRANTED == packageManager
.checkPermission("foo",
pk.packageName))
results.add("package name: "+pk.applicationInfo.packageName+ " class name:
"+pk.applicationInfo.classNa);
}
Class name is null. So, per my understanding there is no way inter-app communication is possible through explicit intent just by relying on PackageManager APIs. In Android 5, you can call AIDL Services only through explicit intent but at dev-time the caller needs to know package and component name of app exposing the AIDL. Is my understanding correct?
Can App A start a component within App B?
App A can try. Whether App A will succeed depends on several things, including whether the component is exported and whether the component is secured by a permission.
I don't think this is possible because explicit intent needs- app package and component name.
The application ID and component name are both strings. Apps can use strings. Correctly getting the application ID and component name may take some work, depending upon the relationship between App A and App B.
As a counter-example, the only way to bind to a service on Android 5.0+ is via an explicit Intent. Hence, if App A wishes to bind to a service exported by App B, App A has no choice but to create an explicit Intent.
No way. If you want to start something that's outside your app you have to declare a implicit intent. Otherwise android will look for it inside your package, probably not gonna find anything and crash.
From the docs:
You'll typically use an explicit intent to start a component in your
own app, because you know the class name of the activity or service
you want to start.
Under "Intent Types" - http://developer.android.com/guide/components/intents-filters.html
So, typically you will not... but you can do this however it is not straightforward. To create a proper explicit intent, you will need the application context and the class.
To get the context of another application:
createPackageContext (String packageName, int flags)
http://developer.android.com/reference/android/content/Context.html#createPackageContext(java.lang.String,%20int)
For the class, you can request 'Activity' and 'Service' classes from package manager. You could also try to use reflection. You can also use the fully qualified string name of the package and assume it is correct and/or will not change. If you want, you can include a stub of the class in your app, thereby obtaining a reference to it (if you have access to the source or a stub library).
If there are permission restrictions, you will need to request permission.

why we must declare activities and service in android manifest file?

if I have a Service or an Activity that I want to be started only by another Activity in my app, do I need to declare it in the manifest? I.e., I always launch a secondary activity from the primary activity of my app that directly points the secondary activity's class (no intent filter resolution), is still necessary to declare the secondary activity in the manifest?
And what if I don't want anyone outside my app to be able to launch my secondary activity?
1.YES
2.YES
3.set exported false in the manifest.
Read here for more information
What is Manifest?
Manifest file for an android application is a resource file which contains all the details needed by the android system about the application. It is a key file that works as a bridge between the android developer and the android platform. It helps the developer to pass on functionality and requirements of our application to Android. This is an xml file which must be named as AndroidManifest.xml and placed at application root. Every Android app must have AndroidManifest.xml file. AndroidManifest.xml allows us to define,
The packages, API, libraries needed for the application.
Basic building blocks of application like activities, services and etc.
Details about permissions.
Set of classes needed before launch.
Do I need to declare it in the manifest?
Yes
Is still necessary to declare the secondary activity in the manifest?
Yes
What if I don't want anyone outside my app to be able to launch my secondary activity?
android:exported="false"
We must declare in AndroidManifresh according to https://developer.android.com/guide/topics/manifest/activity-element.html
Declares an activity (an Activity subclass) that implements part of
the application's visual user interface. All activities must be
represented by elements in the manifest file. Any that are
not declared there will not be seen by the system and will never be
run.

why acitivies have to be registered in manifest file

we worked for exam with our friends. I tried to explain manifest file, talking about how to do things. But I see that I did know why to register activities to androidManifest.xml. Still do not know :). Does anyone have an idea?
The manifest file is used by the system to know what kind of components do the application have. Without registering your Activities/Services/Receivers/Content Providers the system would have to scan and parse the whole apk every time someone wants to use a specific component to find it. This would be really slow, that's why there is the AndroidManifest.xml, which is a small file, and it can be parsed fast to find the required component.
Manifest file describes the following features...
Version Number and Version Code:
This is useful, when you are uploading the application in Google play or go for upgrade the existing published apk.
2.minSdk and targetSdk:
mentioned your min and max version number your application supports.
3.application tag:
used to set the first activity or home activity when you launch an application from laucher.
4.activity tag:
the list of all activities in the application declared as child tag in application tag for the easier navigation to activity manager.
When we switch one activity to another activity, the activity manager checks whether this activity is declared in manifest file or not. If not found throws exception.
Uses: Developer can have look at all the activities at a glance (By Manifest file)
5.Filter tags: By intent filters in activity tag, User can open any kind of application activity.
Uses permission and Uses features:
All application resources are declared here.
example: Internet connectivity is needed for your application, Uses WIFI in your application.

In Android How can I specify which activity should handle my intent

I have 2 applications A and B.
I want to start an activity in B from A. So I am using an implicit intent. Is there any way to make sure that only the activity in B is invoked by the intent?
i.e In the event that a hacker puts his application on the device trying to receive the same intent, I want to prevent that.
Use the setPackage method to specify whicj app should handle the intent. Here is an example using ZXing:
final String ZXING = "com.google.zxing.client.android";
Intent intent = new Intent(ZXING + ".SCAN");
intent.setPackage(ZXING);
as documention says about android:exported=false:
android:exported
Whether or not the activity can be launched by components of other applications — "true" if it can be, and "false" if not. If "false", the activity can be launched only by components of the same application or applications with the same user ID.
The default value depends on whether the activity contains intent filters. The absence of any filters means that the activity can be invoked only by specifying its exact class name. This implies that the activity is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the activity is intended for external use, so the default value is "true".
This attribute is not the only way to limit an activity's exposure to other applications. You can also use a permission to limit the external entities that can invoke the activity (see the permission attribute).
so ,use android:exported=false in Activity B and use IntentSender in Activty for getting infromation of Intent means from which component want to start your Activty B
If you are using explicit intent, activity specified in intent would be invoked only.
You can add Data, Action, Categories, to limit filtering of component to target only your activity, in case of implicit intent.
You could encrypt any data sent in the intent using a simple Public/Private key encryption. A common approach is to use PGP encryption and Im sure there is a library that is compatible with Android out there.
This would make sure that any hacker would not be able to steal the data sent via intents, as long as they don't have the private key.
That being said, it may be tricky to handle the private key as a good hacker may be able to de-obfuscate/de-compile your application and grab your key. Therefore you may need to keep said key on a central server.

Categories

Resources