13

I'm writing a library class to encapsulate some of my logic in my first Android app. One of the functions which I want to encapsulate is a function which queries the address book. As such, it needs a ContentResolver. I'm trying to figure out how to keep the library functions black-boxed... that is, to avoid having each Activity pass in its own context to get a ContentResolver.

Problem is I cannot for the life of me figure out how to get a ContentResolver from within my library function. I can't find an import that contains getContentResolver. Googling said to use getContext to get a Context on which to call getContentResolver, but I can't find an import containing getContext either. Next posts said to use getSystemService to get an object to call getContext. BUT - I can't find any import containing getSystemService either!

So I'm stuck wondering, how can I get a ContentResolver within an encapsulated library function, or am I pretty much stuck having every calling Activity pass in a reference to its own context?

My code is something basically like this:

public final class MyLibrary {
    private MyLibrary() {  }

    // take MyGroupItem as a class representing a projection
    // containing information from the address book groups
    public static ArrayList<MyGroupItem> getGroups() {
        // do work here that would access the contacts
        // thus requiring the ContentResolver
    }
}

getGroups is the method where I was looking to avoid having to pass in a Context or ContentResolver if I could, as I was hoping to have it cleanly black-boxed.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
eidylon
  • 7,068
  • 20
  • 75
  • 118

4 Answers4

10

You can use like this:

getApplicationContext().getContentResolver() with the proper context.
getActivity().getContentResolver() with the proper context.
codercat
  • 22,873
  • 9
  • 61
  • 85
8

Have each library function call pass in a ContentResolver... Or extend Application to keep hold of a context and access it statically.

techi.services
  • 8,473
  • 4
  • 39
  • 42
  • What would be any other potential side-effects or "gotchas" of extending `Application`? Would there be anything I would need to clean up in a destructor method or anything, or ? – eidylon Feb 04 '11 at 22:06
  • Okay, so I'm trying to go this route. I have a class which `extends Application` and I have added the fully qualified class name as `android:name` in the app manifest file. So now in my library class, I am trying to call `getApplication()`, but it does not find it as a method, and gives me no refactoring hints of a needed import to add. How can I call `getApplication()` to get the app handle? – eidylon Feb 06 '11 at 01:29
5

Here is how I wound up doing this, for any who may find this thread in the future:

I used sugarynugs' method of creating a class that extends Application, and then added the appropriate registration in the application manifest file. The code for my application class is then:

import android.app.Application;
import android.content.ContentResolver;
import android.content.Context;

public class CoreLib extends Application {
    private static CoreLib me;

    public CoreLib() {
        me = this;
    }

    public static Context Context() {
        return me;
    }

    public static ContentResolver ContentResolver() {
        return me.getContentResolver();
    }
}

Then, to get a ContentResolver in my library class, my function code is such:

public static ArrayList<Group> getGroups(){
    ArrayList<Group> rv = new ArrayList<Group>();

    ContentResolver cr = CoreLib.ContentResolver();
    Cursor c = cr.query(
        Groups.CONTENT_SUMMARY_URI, 
        myProjection, 
        null, 
        null, 
        Groups.TITLE + " ASC"
    );

    while(c.moveToNext()) {
        rv.add(new Group(
            c.getInt(0), 
            c.getString(1), 
            c.getInt(2), 
            c.getInt(3), 
            c.getInt(4))
        );          
    }

    return rv;
}
eidylon
  • 7,068
  • 20
  • 75
  • 118
  • 1
    How can you manage the permissions for this? If you want to restrict data exposure for some apps that use your library, how can we achieve that? – Manohar Jul 12 '12 at 16:24
2

A bit hard without seeing more of how you are coding your library, but I don't see another option then to use the context, and so pass that when calling that class.

A 'random' class does not have the environment to get a contentresolver: you need a context.

Now it's not too strange to actually pass your (activity) context to your class. From http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html

On Android, a Context is used for many operations but mostly to load and access resources. This is why all the widgets receive a Context parameter in their constructor. In a regular Android application, you usually have two kinds of Context, Activity and Application. It's usually the first one that the developer passes to classes and methods that need a Context

(emphasis mine)

Sean O'Toole
  • 4,304
  • 6
  • 35
  • 43
Nanne
  • 64,065
  • 16
  • 119
  • 163