What is sharedUserId in Android, and how is it used?
SharedUserId is used to share the data,processes etc between two or more applications.
It is defined in AndroidManifest.xml like,
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android.uid.shared"
android:sharedUserLabel="@string/sharedUserLabel"
...>
and define the shared parameter in Android.mk for that app, like
LOCAL_CERTIFICATE := shared
Hope its helpful to you.
Two app with shared UserID
You can use android:sharedUserId
in AndroidManifest.xml to let your application share the same user id with another application.
android:sharedUserId
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.
Notice that they need to be signed by the same certificate.
Two applications share the same user id may access each other's resource.
For example:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.shareusertesta"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="com.example">
Then we can init a new context of com.example
by:
Context friendContext = this.createPackageContext( "com.example",Context.CONTEXT_IGNORE_SECURITY);
And access some resources of that application:
friendContext.getResources().getString(id);
friendContext.getResources().getDrawable(id);
friendContext.registerReceiver(...);
android:sharedUserId= android.uid.system Obtaining Files from SDCard
A system app can't read from external storage? That's news to me, but anyway.
You can always just create a pipe and pass the read end back over the IPC mechanism of your choice (ContentProvider.call()
for example). The service-side starts a thread and writes the file to the write end, and passes the read end back to the client. Something like this on the service side:
ParcelFileDescriptor[] fds;
try {
fds = ParcelFileDescriptor.createPipe();
} catch (IOException e) {
e.printStackTrace();
return false;
}
final ParcelFileDescriptor readFd = fds[0];
final ParcelFileDescriptor writeFd = fds[1];
// TODO: start a thread to write file to writeFd
Bundle result = new Bundle();
extras.putParcelable(EXTRA_READ_FD, readFd);
return result; // Return from call() to client
Obviously there is a lot of boilerplate code left as an exercise for the reader.
security in using shareduserid
Shared user IDs are enforced by the certificate signature. The platform will grant/assign same user ID only if the applications are signed with the same certificate. Ref.:
android:sharedUserId
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.
Content Provider vs SharedUserId vs Global Process for sharing data across applications
I found three ways to share data across applications.
#2 and #3 are the same, insofar as #3 (shared process) requires #2 (sharedUserId
).
You also missed all other forms of standard Android IPC, including:
- starting activities
- starting services
- binding to services
- sending broadcasts
I am confused what to use when
Ordinary app developers should use #1 (ContentProvider
) or one of the other standard Android IPC mechanisms that I outlined above. You have no control over when users update apps, and using formal IPC enforces a clear separation between the apps, forcing you to think through things like API contracts, API versioning, and related concerns.
sharedUserId
and shared processes are really there for device manufacturers, where apps are pre-installed and then updated in unison via a firmware update. Personally, I recommend to device manufacturers that they too use standard IPC, for most scenarios. For example, if App A modifies App B's files directly, how does App B find out? What if App B then overwrites App A's changes, because App B did not know about those changes? In many other areas of computer programming, we have gotten away from having multiple processes from multiple apps work with each others files directly.
which is more efficient?
Efficiency should not be an issue in this case, as you should be using any of these techniques infrequently. If you have two apps that need to communicate with each other frequently, then you really have one app, and you should implement it that way.
sharedUserId: safe to change when app is already in market?
And to answer my own question again:
No, it's not safe. Since updating an app via Android Market will not remove the database and preference files, the new version will not be able to read or write these files (since they were created under a different Linux user ID), and the app will crash after the update. You would have to ask your users to completely uninstall and reinstall the app, which is certainly not recommended.
As a general rule I conclude from this:
Whenever you start out developing a new app, make sure to set a manual android:process
and android:sharedUserId
attribute! It doesn't hurt in case you don't need it, but it gives you full control over which apps have access to this app's private resources.
SharedUserId & Files
Can sharedUserId provide access to files in the data/data/com.example/files dir?
Yes, if and only if:
Both apps have the same non-empty
sharedUserId
valueBoth apps have always had the same non-empty
sharedUserID
value (i.e., you cannot update an app from not havingsharedUserId
to having asharedUserId
)Both apps are signed by the same signing key
That being said, sharedUserId
is almost never the right answer, for the simple reason that neither app will know about what the other app is doing with the files. Use a ContentProvider
(or some other form of IPC) to share content between apps, using signature
-level permissions or other identity checks to ensure that only the right apps can interact over the IPC channel.
Related Topics
How to Get the Current Screen Orientation
Java - Process.Destroy() Source Code for Linux
What's the Syntax for Mod in Java
Creating a Variable Name Using a String Value
Singleton Design Pattern VS Singleton Beans in Spring Container
How to Iterate an Arraylist Inside a Hashmap Using Jstl
Is It Expensive to Use Try-Catch Blocks Even If an Exception Is Never Thrown
How to Get Pid of Process I'Ve Just Started Within Java Program
How to Update a Textview of an Activity from Another Class
Https Get (Ssl) with Android and Self-Signed Server Certificate
Inputstream.Available() Is 0 Always
Why Does Priorityqueue.Tostring Return the Wrong Element Order
How to Convert an Int Array to String with Tostring Method in Java
How to Mark Jtable Cell Input as Invalid
Jpql Create New Object in Select Statement - Avoid or Embrace
Unsupportedoperationexception When Trying to Remove from the List Returned by Array.Aslist