Android: access internal storage from another app with same signature - java

Context: I have two apps, both signed with the same signature. The first app has data stored in internal storage that I would like to migrate to the second app.
Question: How can I access the data in the first app from the second app? The Android documentation makes reference to "signature permissions" (https://developer.android.com/guide/topics/permissions/overview#signature and https://developer.android.com/training/articles/security-tips#StoringData) and hints that it is possible to share data between apps with the same signature, but I cannot find clear guidelines about how to do this.
It seems like it might be possible by creating a content provider? Or is it possible to directly access the files, since I understand from the docs that they will be running with the same user / same process?
Ideally this process can happen with minimal intervention from the user, and can all happen from the second app (e.g. the second app can recognize that the first app is installed, prompt the user to migrate, and then read the data from the first app and move it to the second). It would be even better if it was possible to move the files (rather than copy) because we potentially have a lot of data and the user may not have enough disk space to copy the data.

It seems like it might be possible by creating a content provider?
Yes. You can create a signature-level permission and use that to protect access to any of the standard IPC options in Android, including ContentProvider and Service.
Or is it possible to directly access the files, since I understand from the docs that they will be running with the same user / same process?
No, two apps signed by the same signing key to not run as the same user, let alone in the same process. android:sharedUserId has the apps run as the same user. This was never a great idea, is deprecated, and is likely to go away soon.
It would be even better if it was possible to move the files (rather than copy) because we potentially have a lot of data and the user may not have enough disk space to copy the data.
That suggests that having two apps is a bug, not a feature, from the standpoint of the user. The closest you will be able to do to a "move" operation is "delete-after-copy", so plan your copies to be as granular as possible so you can delete as you go.

Related

How to Save the system state in Java and resume the system when I recompile the project?

I have a system in Java where different classes stores different information. There is a main class where the user will input the information of these classes and make them interact with each other. After the user is done, he will exit the system. The Next time the user recompile the project, all the previously entered data should be there. The user can use that same data or add more information.
So Simply, How to pause/save the system on close and resume it when I execute it again?
PS. I can't use Database in this. It must be something else.
The Next time the user recompile the project
Users dont recompile projects. They just run your app.
You keep saying 'not DB', so, then, the answer is trivially: impossible.
A database, by definition, persists some data, hence the name: It's a base of data. If that's off the table, you're out of luck and what you want is not possible.
Perhaps you are careless in your wording there as well and all you mean is perhaps:
I do not want to bother with forcing the user to install a database
Okay, then, don't. Use an in-process database, such as h2. The user doesn't know an SQL-based database system is involved, all they see is a file appear. No extra processes are launched.
I hate SQL
Okay, then, don't. There are tools out there that turn an entire object structure into a bag o bytes which you can then save to a file, for example Jackson which can turn one object (which can contain all the relevant user data if you want) into JSON data, which you can then save to a file, and restore later. Of course, if someone trips over a powercable halfway through writing it, the file is corrupted. There are ways to fix that (save to .tmp, then move it into place, as that's usually atomic), but you're sort of committed to re-inventing the wheel here, due to your insistence you don't want databases.
I just want to save the entire system state
You can't. Not how java works.
Can't I do it with zero dependencies?
There's java's built in serialization system, which sucks, has a list of caveats as long as my leg on how to use it, and is more or less disliked by the maintainers of the java platform itself. This is not the way to go. It also still won't 'save the entire system state', it just saves one object, and does a much worse job at this than e.g. jackson.

Reserve internal storage of Android device for future application critical logs

I'm developing an app which is going to save important logs for each operation that the user is doing.
These logs are critical and I need to reserve an space on the installation of the application, so if the device does not have the required space, he can't install the app.
I need to overwrite or use the reserved space for logging the operation.
I don't know the best method to implement this need.
If I put a massive file in the asset folder, the app needs this space on the installation,but as you know, asset folder is read-only!
Actually I'm asking you for helping me find a way to reserve space for future use in my application.
Thanks in advance
The most simple solution that I can think of is creating an empty file when the app is first lunched, and if you fail you present the user this information.
If you do want to do it due the install process you can use APK Expansion Files those are used for extra big size apks but you can also use them as they are saved in external storage, so you can override them.

How do I deploy and manage a small scale Java desktop application?

Some relevant background:
My application is a Java app compiled into a .exe via JSmooth. The anticipated user base would likely be a few hundred users, but could grow well beyond that, as it's a community specific application.
How it works:
2 .jar files, one that preforms initial checks, another with the meat of the application.
Ideally, the init jar displays the splash, checks the version in desktop.txt against server.txt, if they differ, it prompts the user to update.
What I need to figure out:
1) What is a cheap, scalable hosting service that I could use as the file host for updates?
2) How can I create an "updater" to actually preform the jar replacement? My current solution is simply writing an updater in Java, but I was hoping for something like the installers people are more familiar with.
All of the research I've done has resulted in lackluster results, as 99% of hosting searches result in site hosting results. I just need an update repository with reasonable security. i.e., decent DDoS resistance and not left wide open to the Internet.
Edit: formatting
Easy to do and very foolish cheap with Amazon S3 or Joyent Manta as both support time-limited signed URLs and headers (which can contain a SHA-1 of the file) to check to see if the update is needed before downloading
On startup your app would check the update URL to see if it has changed. If it has changed, download the JARs. Do this before the app loads classes from those JARs. Updating the updater itself will be trickier so consider that an update might need a new update URL to prevent expiry.

Is there a way to sandbox parts of a java process on Android?

I want to use an SDK in android, but I don't want that SDK to have any access to permissions that I haven't explicitly given it. On top of that, if the SDK throws an uncaught exception, I don't want it to bring down my entire application.
In C# there is the concept of an AppDomain where you can treat the code running inside of it like a sandbox, granting (or limiting) permissions, and only providing access to data that you explicitly want to share.
Is there anything that works like this in Java for the Android platform?
There are two questions here. The first one deals with handling exceptions in a piece of untrusted code; a carefully written try/catch block should take care of that, as long as the untrusted piece is pure Java. If native code is allowed, then nothing short of process level isolation would help. For running code in a separate process, read up on Android services; you can designate a service to run in a designated process. Then exceptions (the nonmanaged kind) won't bring down the main app. You'll just get a "service has died" exception.
A whole another issue is lowering the permission set. To the best of my knowledge, there's no way to lower the permission set within an app. Even a surrogate process won't help. If you ship a whole application (in the Android sense of the word) for wrapping and running custom code, that might help. But the logistics of app installation would get tricky. Google Market does not readily support the notion of app interdependence or prerequisites.
All the permissions you give to your app are the permissions that are allowed to otherwise it wont have permissions for almost nothing.
you set your permissions in your Manifest.xml otherwise than that you cannot set other kind of permissions.

Run SQLite commands on database in one app from another

I have an SQLite database stored in the assets resources of one application used to load UI and other stuff into the app, mainly just holding text nothing out of the ordinary. I want to be able to get a writable version of this database so I can modify it from another application.
Example:
First application is on the market with limited number of enabled features. User gets to a certain point where they need to buy extra content to do more stuff in the app. The original app has these features but they are not enabled in the app using the database. I want the user then to download a second app from the market which is just used to change one field in the database from disabled to enabled thus unlocking the new features.
I have an idea I may need to use content providers but my understanding is once created they are accessible to all applications. I need it, for piracy reasons I guess, to only be able to communicate with apps signed off by my key.
Thanks
Sam,
I understand what you intend to do, but you are going about it the wrong way. Your 'Unlock App' would not be able to modify the Database in the assets folder of your 'Free App'. That's just general android security model stuff.
You may want to look at this question: How can I use the paid version of my app as a "key" to the free version?
It describes how you can create a 'Unlock App' on the market to unlock features of your 'Free app' without needing to actually modify any of the original data in the 'Free App'.
Good luck

Categories