Search code examples
androiddependency-injectiondaggerbutterknife

Dagger and ButterKnife - Can i inject Android AudioManager instance


How do i inject an AudioManager instance ? I need a context and i dont have one ?

Here is my class that uses a Dagger injection:

public abstract class ListPageActivity extends BaseActivity {

private SoundPool mSoundPool;
private int mSoundID;
boolean plays = false, loaded = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

//ButterKnife.inject(this);
}


public void loadBrandSound(){
mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);

mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {

    @Override
    public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
        loaded = true;
    }
});
mSoundID = mSoundPool.load(this, R.raw.ducksound, 1);

}

@Inject AudioManager am; //i want to inject this
public void playBrandSound() {



     /*AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE); commented out as i want to
inject it*/
    int volume_level= am.getStreamVolume(AudioManager.STREAM_MUSIC);

    // Is the sound loaded already ?
    if (loaded && !plays) {
        mSoundPool.play(mSoundID, volume_level, volume_level, 1, 0, 1f);
        plays = true;

    }
}

public void stopBrandSound() {

    if (mSoundPool != null && plays) {
        mSoundPool.stop(mSoundID);
        mSoundPool.release();
        plays = false;
    }

}

}

and here is my failing module called ActivityModule.java which i want to declare an audioManager instance that can be injected into my ListPageActivity:

@Module(
        library = true,
        injects= {
                ListPageActivity.class,
                MainActivity.class
        }
) public class ActivityModule {

    @Provides
    AudioManager provideAudioManager(){return (AudioManager) getSystemService(AUDIO_SERVICE);
//the above fails to compile as i need a context, how can i get one ?
}
}

My dagger modules are already working so i have that set up right. Also is there a easier way to inject System Services since there so common instead of this way ? ButterKnife i was thinking might have something that i could simply inject a systemService just like i can inject a view.


Solution

  • Assuming that BaseActivity handles the Activity injection for you, you should be able to:

    Pass context as a parameter to your "provideAudioManager" method, and then have a provideContext() method that provides context from either the activity, or from the application.

    Something like this

    private Activity mActivity;
    
    public ActivityModule(Activity activity){
        mActivity = activity;
    }
    
    Context provideContext(){
        return mActivity;
    }
    
    AudioManager provideAudioManager(Context context){
       return (AudioManager) context.getSystemService(AUDIO_SERVICE);
    }