So, I'm trying to use a running application and have it access code of a not yet installed application through its .apk file. I need to access things such as the secondary applications packagename, provider, bundles, data, etc all without installing it onto the phone.
So far from what I understand I can use either one of two things.
1) dexClassLoader. With this option I need to be able to access the .apk file from some sort of storage such as an SD card.
2) pathClassLoader. Seems like the correct option here. Can use JAR/ZIP/APK files with this option.
Essentially I'm trying to load the second application into the first one by binding its code to a running process, I'm just having trouble accessing its code without decompiling it. I guess my question is should I be using/trying the first or second option here, or is a third option available?
While you can dynamically load code from the second application using dexClassLoader, etc., you cannot dynamically add new components to your application. Any component must be statically declared in the AndroidManifest.xml.
So you cannot, for example, "import" an activity from the second apk into your main application. You can access the class for that Activity, but you can't directly start an activity using it.
Depending on your requirements, it might be possible to create a "placeholder" activity in your main application, which creates an instance of the Activity class from the secondary apk and forwards all method calls to that instance. In general, I would not actually suggest this. I suspect it would be very difficult (if not impossible in some cases) to actually do correctly.
Related
I want to extend the features of my android app by adding few screens in the app when the user chooses to download the screens and without making the user reinstall or upgrade the app. I have explored the option of making the user install another android app which will act as a plugin, but I want to avoid forcing the user to install another app via google play as he can he reluctant.
Is there a way download only the required XML layout and attached java code file only?
You can try create a ActivityHolder (cause Activity must be declared on Manifest) and use a Interface to implement the methods from Activity, use the getClassLoader().loadClass to instantiate your file and hold the instance of it in the activity.
And you cant use XML layout cause the ids are generated in compile time into the class .R.
Worth trying.
I have an android app that is able to open a certain file type via a VIEW intent.
After a file is opened using my app for the first time, I would like the app to "remember" the file so that the user can choose to open it again from a list of "recent" files inside the app...
My question is: what is the best way to implement this kind of "remembering" - should I:
Automatically copy any files passed to my app into my app's own storage area, and then list "recent/old" files there?
Or, should I record a list of files that my app has been passed previously, and access them via the same path later if necessary? If that is recommended, is there any guarantee that I will be able to access them again later? (I guess not!)
Option 1. seems like more work and doubles the storage space needed for all files passed to my app, but will guarantee the files will be accessible in future. Option 2. is easy if the files are always readable by my app in future, and are not renamed/deleted for some reason - it seems there's no guarantee of that though...
If it helps, I expect most files passed to my app to come from "Downloads" via the user's browser, but some might come from email/other apps etc.
Thanks
I would go with Option #3: drop the proposed feature.
As DeeV pointed out in a now-deleted answer, Option #1 is not a great solution for a "recent files" list. It would be the right option for other verbs than "remember", such as "import".
Option #2 will not work much of the time. Your app needs to support the content scheme, in addition to (or even instead of) the file scheme. By default, you will only have rights to access the content at a content Uri until your process terminates (at best). You may be able to takePersistableUriPermission() to get durable access, but that will not work much of the time — it depends upon whether the other app is granting you such access. Hence, you might have a Uri that you can remember, but remembering will do you little good.
I am attempting to create a free, configurable version of my EGMaps Android app which anyone can use to easily create their own map-based apps. The goal is to provide a framework so people with little programming knowledge can just fill in blanks, provide their data, and have it work.
There are two apps involved:
App #1 (EGMaps) does pretty much all the work. It needs access to data provided, or pointed to, by other App #2. I'm the only one working on this one.
App #2 will be created by multiple, maybe lots of other people, all with different app signatures. This is a very small, simple app which does very little other than passing data to EGMaps. I'll be providing source code and instructions on what to fill in. The other programmers can either use it directly, or modify it however they want for their app, which will then eventually call EGMaps.
App #2 needs to pass a lot of data like GPS coordinates, GPS tracks, marker locations, etc, which it's already doing. It also needs to pass an unknown, but potentially large number of small drawables. Due to space considerations, I'd prefer to use the drawables directly from the calling app, rather than copying them over or downloading and storing them inside of EGMaps. These drawables will eventually be Google Maps Marker icons.
Since the apps are written by different programmers, the app signatures are different, so setting the same user ID doesn't help.
This is as close as I've come:
iconString=callingPackage+":drawable/"+iconName;
iconValue=getResources().getIdentifier(iconString, "drawable", null);
callingPackage = name of calling app (ie: App #2). I have verified this is correct.
iconName = name of icon, as found in the drawable resources.
Without the callingPackage part, and with the drawables saved directly in the app, this works fine. It's just accessing the external drawable that doesn't work. iconValue always returns 0. I have also tried putting callingPackage into the third parameter of getIdentifier, with and without adding it to iconString, but that didn't make any difference.
Is there any way to directly (or indirectly, I suppose) access these drawables from the calling app without actually copying them from somewhere?
I would have expected getResources().getIdentifier(iconName, "drawable", callingPackage) to have worked, assuming that callingPackage is an actual package name.
You can try createPackageContext() and calling getResources() on it to get a Resources object referencing the other package.
I am very new to Android development.
Suppose my application has a few static HTML files that I expect will need frequent updates. Suppose I do not want to publish a new version of my application every time a file changes, but I do want to keep these files up-to-date.
What I imagine I could do, is to write a piece of code within the app to go to a known URL and check for updates every few days. If the updated resources bundle is available, the code will download and unpack it, replacing old files, so that the user will see the most resent content.
Questions I have:
- is such approach a good/bad idea? In other words, are their specific disadvantages to doing update in such manner or is it a commoin practice?
- how can I implement something like that? Service? Is there an existing sample piece of code that I could reuse?
Thanks!
If the updated resources bundle is available, the code will download and unpack it, replacing old files, so that the user will see the most resent content.
This is fine, except for the "replacing old files" part. Resources are read-only and cannot be modified at runtime. However, you can adjust your code that uses these files to look for your downloaded-and-cached updated files first and use those, falling back to the resources if updates are not available.
how can I implement something like that?
If your app involves other data synchronization, and you are using something like SyncManager for that, just include these files as part of the synchronization work.
Otherwise, use AlarmManager to arrange to get control every so often to check for updates. You will probably need to use WakefulBroadcastReceiver or my WakefulIntentService to do the actual downloading, as the device will want to fall asleep right away otherwise, if the user is not using the device right then. Use HttpUrlConnection or your favorite HTTP wrapper library to download the files to getFilesDir() or getCacheDir().
I want to be able to package data in a apk, which is read by my main app.
Is there a way that I can put the data in apk, and then upon install automatically hook that data into the ContentProvider in my main app?
The other possibility is to have each add-on be a content-provider, and have the app look for it, but then I fragment the authorities and I don't have a pre-built list, although I suppose I could "reserve" authorities for expansions if this is the best option.
The other option I understand I might be able to use for data sharing is to run the separate apk's with the same user_id? Any thoughts how I could get this to work would be great too, I tried this but reflection didn't show my addons classes, and it brings up all kinds of dynamic loading questions.
Edit: If it helps, I already have it working using zip files in a folder in the SD, but I want to be able to put that zip into a apk, and write a simple wrapper so that it can be read by my other app.
I plan to do something similar with each add-on being a content provider. My plan is to have each add-on/content-provider have a common meta-data tag that the main app can look for when iterating through the list of all content providers.
I actually achieved this, by using a set authority and then iterating over all the content providers.
So every addon is in addons.myapp.blah1... and then if it matches the beginning addons.myapp I do the load.