I have an application A that launches an intent to install application B(which is present in app A's data folder).
Once application B is installed, file managers like ASTRO can backup Application B's apk file.
So I want to prevent the user from manually installing it(say if he clicks on the backup apk file of Application B it should not install).
Is there a way to disable manual installation...?
But there are two ways to monitor the app.one is, you can use File Observer to
monitor the apps. whenever the apps been taken as back up do stuffs to prevent it. Another way is
For eg: if it's storing in sdcard\am\ use like this.
File f=new File("\mnt\sdcard\am\abc.apk");// file location of your app
{
if(f.exists)
{
f.delete();
}
}
For File Observer,have a glance of this.It might help you.
http://developer.android.com/reference/android/os/FileObserver.html
Can you find the location where the backup is taken and delete the apk.
If APk is available to the file manager then it can open it and install it, I am not aware of any way to stop it as its out of your application scope.
This isn't possible on AOSP Android.
The Install from unknown sources option is a setting in Settings.Global (previously in Settings.Secure) and cannot be controlled by third party applications.
However, it is possible do achieve this if you're willing to modify and compile Android itself for each and every device you want to use this on, as is done by AT&T on some of their devices.
The best you can do is try to find the backup file and delete it if you have access to that part of the storage.
Not sure if it's feasible, but I would solve this by having application A spit out a code that has to be manually entered (like a two step verification) on application B is installed, and then verify it server side. So that way the rogue install like you mentioned would be rendered useless. Maybe you could pop up an error to the user informing them of this.
Related
By "permanent" I mean that it resists the application uninstall option that the Android OS offers. Obviously you cannot make a file not deletable in the user's terminal, at the very least, the user will always be able to delete it via the file manager if he wishes so.
I'd need this because in my app when some actions have been performed the app forbids from doing some more. So far this is controlled via a file, but there's nothing that prevents the user from uninstalling the app, and with a new fresh install this doesn't happen anymore.
I could implement some type of server-side logic to prevent the user from continueing but:
1) It's way easier to prevent just by checking the file.
2) It's not that important what happens if the user manages to bypass this security measure, so I don't really mind if a few of them are able to bypass the protection, as long as the file can be "permanent" and is in some obscure directory, not many users are going to be able to perform the mentioned behavior.
Is there any way to do this?
Just get the write file permission and write the file to the root file directory. As described here: https://developer.android.com/training/data-storage/files#WriteExternalStorage
After you request storage permissions and verify that storage is
available, you can save two different types of files:
Public files: Files that should be freely available to other apps and to the user. When the user uninstalls your app, these files should
remain available to the user. For example, photos captured by your app
or other downloaded files should be saved as public files.
Private files: Files that rightfully belong to your app and will be deleted when the user uninstalls your app. Although these files are
technically accessible by the user and other apps because they are on the external storage, they don't provide value to the user outside of your app.
this can be done by configuring auto-backup, assuming that the user has it enabled.
for example, here I've explained how to disable that behavior in debug mode.
the advance is, that it works across several devices, bound to the account.
instead of file , I would suggest to use following intent to catch uninstalling your app and put your logic to allow or deny for uninstall
ACTION_PACKAGE_REMOVED -: Broadcast Action: An existing application package has been removed from the device. The data contains the name of the package. The package that is being installed does not receive this Intent.
ACTION_PACKAGE_FULLY_REMOVED - : Broadcast Action: An existing application package has been completely removed from the device. The data contains the name of the package. This is like ACTION_PACKAGE_REMOVED, but only set when EXTRA_DATA_REMOVED is true and EXTRA_REPLACING is false of that broadcast.
I need to place a file inside of another application's specific folder. Is there a best practice, or related expected behavior for this?
To solve the issue, I have created the desired file during my APK's installation, then written its contents. While this works (since I have root rights), I want to know if is there a way to "request" another application to "create the file themself", this is mostly to guarantee that when that other application is removed, that it removes its files (since my app is the owner of that file).
I am unsure if this is considered good behavior, and could not "phrase" the question in a way that showed related results (I am not an native English speaker).
I need to place a file, inside of another applications specific folder
If by "applications specific folder", you mean internal storage, this is not possible, except perhaps on rooted devices.
I want to know if is there a way to "request" another application to "create the file themselfs"
Not in general. Some developers might have an API for this in their apps.
The official way of sharing data between apps is ContentProviders.
There is no limit to what may back the specific provider - a file, database or some other data source. I think this is the best way to go in your situation.
The approach you have described is indeed strongly advised against. The whole Android security is based on the idea that you can't directly access the data of other apps.
Ok, here is my proposal. I will assume that you can add functionality to the server app or define some technical guidelines for it at least, so that it's developers have to add the functionality.
A - Server App
B - Client App
[B] Create the html file in the common storage
[B] Save its location to some String variable
(Optional) [A] If there are more server apps that the user can choose from, make sure they all have a BroadcastReceiver with a common INTENT_ACTION.
[B] Send a broadcast Intent with the path saved in 2. as an extra value.
[A] Receive the Intent, check if the path in the extra is present.
[A] Get the file from the received path and copy it into the internal storage.
(Optional) [A] Add a BroadcastReceiver to monitor app uninstalls. When notified about the client app being uninstalled, remove the html file you received from it.
This is the basic algorithm, but I guess the implementation is obvious enough. Let me know if it solves your problem.
Is there any way to signal Android OS to open the package installer upon download of an .apk file?
Perhaps by Content-Type? or maybe an APK specific url protocol, like apk://apk.location?
Are you doing the download yourself in your own app, or are you trying to create some behavior in an external app?
I don't think you'll be able to trigger behavior upon download outside of your app (since the user would have to select the downloaded file in order to open it), but if you're handling the download yourself, I think you want this post on how to install an application programmatically.
Edit: Addressing your comment in which you said you are writing a website and want to be able to force the APK to be opened by a native app: I can think of a way to do something like it, but you would have to handle the download in the native app because you won't get the browser to do the download for you.
You'll need to register your native app to receive ACTION_VIEW Intents with URIs in whatever format you choose; I recommend using something like yourappname://localhost/escaped_download_url_to.apk. In your Activity get the path from the URI in the Intent and grab the last part of it (URI handling is broken into a few components: protocol, host, and path). Unescape it as necessary and then start the download manually in the app, and then upon completion you open the downloaded APK from wherever your app put it, using the link I provided.
So long as you make sure your mobile website provides an href to yourappname://localhost/escaped_download_url_to.apk, you'll be able to trigger this behavior. When the user clicks that link, it should provide a dialog to choose which app to use to open it (if they have more than one app capable of doing so) which when they select your app will launch the Activity that you registered with the Intent filter.
Edit the second: you probably don't need to do any escaped URIs; just using a made-up URI protocol as you suggest in your own post should work, so long as your app registers to receive Intents with that protocol. yourappname://yourserver.com/my/location.apk will work. All that really matters is being able to pull the download URL out of the data you give to the app in the URI.
What is the best way to discover an Android application's API or hooks into/from the application?
Specifically, I am looking to pass a parameter or data to an application, utilize the application's specific functions, and return data or a parameter to the calling application.
A few ideas come to mind, but I am unfamiliar with what is available, specifically to Android.
Contact an application's developer directly
Somehow decompile the APK to browse the source
Read any available documentation
Some ways to check out what is available for :
Tool to re-engineer closed APK files
http://code.google.com/p/android-apktool/
Review intent filters for actions
Lookup the app in some sort of application manager on your phone. Android System Info. If you go to the details of the app it will tell you where the apk is and the name of it. For instance, under the Email app you can see "Source: /system/app/Email.apk".
To pull that off just do "adb pull /system/app/Email.apk Email.apk", to pull it to your current directory.
Look at the Manifest.xml. Rename the apk to zip and unpack.
Follow the instructions here: http://android.amberfog.com/?p=582
Then you can read the decompiled Manifest.xml and look at the intent filters they are registering.
Android applications are all in their own sandbox, so you can not just arbitrarily call some other Android applications' functions, they would need to be made public to you somehow.
If you are looking to execute some function that is provided by another Android application, you would most likely need to hear about it from the developer, most likely from their public documentation if they have any.
The correct way to do this is to use "intents". With an intent, you can launch another application (such as a barcode scanner) and the user interacts with it. Then, the application exits returning some data (such as the barcode). Try googling or see:
http://www.vogella.com/articles/AndroidIntent/article.html
To preface my question, couple things to note. I don't want to store said file on the sdcard in this case. The file also cannot be storage directly in the apps local files directory. It needs to be in a subdirectory, so it cannot write the file using openFileOutput() and MODE_WORLD_READABLE.
The app may download files small files like pdfs and store them locally in a subdirectory. I would like to be able to have the user open these files if they have an app that can open them.
For example here is an intent for sending a pdf:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(path), "application/pdf");
startActivity(intent);
path being something like: /data/data/packagename/files/subdir/example.pdf
That intent will open a pdf viewer, but the viewer is unable to open the file. I assume this is a permissions issue. I tried Mark Murphy's suggestion here: http://groups.google.com/group/android-developers/browse_thread/thread/4e55d869213483a9/b7270078ac1a2744?lnk=raot of using Runtime.getRuntime().exec("chmod 755 " + fileName); but it didn't make any difference. He also suggested a Content Provider but I would like to avoid it if I can because it seems like a lot just to get this file over to another app.
If the content provider is the only option, do I have to save the file to the content provider or can I just use the content provider as a pass through to get it to the other app when I need to?
Thanks, let me know if I'm not being clear.
I also tried all the options you mentioned (and more) and a content provider was the only way that worked for me. I'm not exactly sure what you mean by "save the file to the content provider", but you don't actually need anything in a database for the provider to serve up the file to the other application.
You might like to look at the android:sharedUserId manifest property:
The name of a Linux user ID that will be shared with other
applications. By default, Android assigns each application its own
unique user ID. However, if this attribute is set to the same value
for two or more applications, they will all share the same ID —
provided that they are also signed by the same certificate.
Application with the same user ID can access each other's data and, if
desired, run in the same process.
Be aware that your applications already have a default one that you can't determine (AFAIK). It may be as well to define the same sharedUserId for both apps, then install them on a new emulator.
As a second point, are you sure that you will be able to view a PDF file? I thought that there was no support for it in Android yet.