How to get context of class - android

I have the following class and i try to get context so as to send an intent to another activity.
public class CloudDocumentTextRecognitionProcessor
extends VisionProcessorBase<FirebaseVisionCloudText> {
public Context mContext;
private FirebaseVisionCloudDocumentTextDetector detector;
public CloudDocumentTextRecognitionProcessor() {
super();
detector = FirebaseVision.getInstance().getVisionCloudDocumentTextDetector();
}
public CloudDocumentTextRecognitionProcessor(Context context) {
this.mContext = context;
}
#Override
protected Task<FirebaseVisionCloudText> detectInImage(FirebaseVisionImage image) {
return detector.detectInImage(image);
}
#Override
protected void onSuccess(
#NonNull FirebaseVisionCloudText text,
#NonNull FrameMetadata frameMetadata,
#NonNull GraphicOverlay graphicOverlay) {
graphicOverlay.clear();
Intent i = new Intent(mContext, ResultActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("key", text.getText());
mContext.startActivity(i);
}
}
But i get an error in the line where i set the intent:
"Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference"
I ve also tried MyApplication.getContext() instead of mContext, but with no results.
Any ideas?

This class does not inherit any Android component that has a Context, so you have to inject it yourself. You have to instantiate the class with the constructor that takes a Context as a parameter, and pass it in from an Activity or other Android component that has a context/access to the app context.
Something like (pseudo-code):
Class MyActivity
{
...
imageProcessor = new CloudDocumentTextRecognitionProcessor(this);
// or imageProcessor = new CloudDocumentTextRecognitionProcessor(this.getApplicationContext());
}
How to choose the context?
If the CloudDocumentTextRecognitionProcessorinstance is supposed to exist throughout the whole lifetime of your app, use getApplicationContext();
If the CloudDocumentTextRecognitionProcessorinstance is guaranteed to only exist during the lifetime of the Activity, use this.

You already have a setter for the mContext field and you can use the secondary constructor for the class that passes the context.
Initialize the class object from your activity like this:
CloudDocumentTextRecognitionProcessor imageProcessor = new CloudDocumentTextRecognitionProcessor(this);
or
CloudDocumentTextRecognitionProcessor imageProcessor = new CloudDocumentTextRecognitionProcessor(getApplicationContext());

Related

Passing an argument from a regular class to an activity

I would like to call a method in an activity and pass an argument to it from a non activity regular class in android.
As i understand, i cant simple use the following code, plus it does not work:
int mySound = 0;
SoundsActivity soundsActivity = new SoundsActivity();
soundsActivity.playSound(mySound);
That code is located in a regular class called "MyAdapter".
There are a few ways you can do this. I can't be specific since you didn't really show any code.
You can't do what you're trying to do though. Activities can't be instantiated like that (as well as anything extending Context), and it won't do what you want.
Use a broadcast.
This will require that you have a Context object passed into your Adapter, which you can do simply by modifying the constructor and adding a global variable:
private Context context;
public MyAdapter(Context context) {
this.context = context;
}
Then you can use that Context to send a local broadcast with your own action:
Intent intent = new Intent("my_custom_action");
intent.putExtra("sound_type", 0);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
And receive that action in your Activity to call your method: See Context-registered Receivers
When you construct the Adapter, pass a Context object into it. If you're constructing from an Activity (hopefully SoundsActivity), use this:
MyAdapter adapter = new MyAdapter(this);
Use a callback.
Delcare an interface somewhere:
public interface AdapterCallback {
void onRequestPlaySound(int type);
}
Implement that interface in your Activity:
public class SoundsActivity extends Activity implements AdapterCallback {
//...
#Override
public void onRequestPlaySound(int type) {
playSound(type);
}
//...
}
Add the interface as a parameter in your Adapter's constructor:
private AdapterCallback callback;
public MyAdapter(AdapterCallback callback) {
this.callback = callback;
}
And then use callback.onRequestPlaySound(0); from wherever you need.
When you construct the Adapter, pass your SoundsActivity instance into it. This will only work if you're constructing the Adapter from SoundsActivity:
MyAdapter adapter = new MyAdapter(this);
Pass SoundsActivity directly.
This isn't the cleanest way, nor is it the recommended way, but it will work. In your Adapter:
private SoundsActivity activity;
public MyAdapter(SoundsActivity activity) {
this.activity = activity;
}
And from SoundsActivity:
MyAdapter adapter = new MyAdapter(this);
Then just call activity.playSound(0); where you need to.

This Field leaks context object

I am using Context object inside non-Activity, it is working perfectly but the problem is it shows warning
That is where I am using the context object
Here is the result of inspection
You can use WeakReferences for this case. something like this:
public class ContactsTask {
private WeakReference<Context> weakContext;
public ContactsTask(Context context){
weakContext = new WeakReference<>(context);
}
public void doSomething(){
if (weakContext!=null) weakContext.get() ... //return context without leaks
}
}

Passing MainActivity in params

I need to start AsyncTask in UI thread, but the Constructor has (MainActivity parentActivity)
parametr. I don't really understand why it should be implemented and how I must pass it.
Here Eclipse says "Cant resolve MainActivity to a variable." Same for Activity.MainActivity.
new DownloaderTask(MainActivity).execute();`
And the constructor.
public DownloaderTask(MainActivity parentActivity) {
super();
mParentActivity = parentActivity;
mApplicationContext = parentActivity.getApplicationContext();
}
Change this line...
new DownloaderTask(MainActivity).execute();
to this...
new DownloaderTask(MainActivity.this).execute();
And you are passing Context of MainActivity not the activity...so in DownloaderTask() constructor, the parameter will be Context type not MainActivity...The constructor should look like as below...
public DownloaderTask(Context context) {
super();
mApplicationContext = context;
}
you can call like following if you are calling directly from the MainActivity
new DownloaderTask(this).execute();
or if you are callling from an inner class you can call like
new DownloaderTask(MainActivity.this).execute();

Access Context from another activty in Android

I have a Main class and another two classes named WebServicesClass and DynamicHeightAdpater.
I am creating an instance of DynamicHeightAdpater in WebServicesClass for which I need the context of MainActivity but I am not sure how to point it. The way by which I am calling throws a NullPointerException.
CODE :
MainActivity :
static Context context;
context = this.context;
WebServicesClass :
new DynamicHeightAdapter(MainActivity.context, 1, rowItems);
But it throws a null pointer exception and I am sure that it is due to the context cause I tried to print it and it threw NullPointer.
I would suggest you to take a look at the Android application class. You can store context there and retrieve it, when needed:
public class TestApplication extends Application {
private static Context mAppContext;
#Override
public void onCreate() {
super.onCreate();
mAppContext = getApplicationContext();
}
/**
* Returns the application's context. Useful for classes that need a Context
* but don't inherently have one.
*
* #return application context
*/
public static Context getAppContext() {
return mAppContext;
}
I suggest passing the Context to the WebServicesClass object in it's constructor, and having a member variable to keep it... something like
public class WebServicesClass
{
private Context mContext;
...
public WebServicesClass(Context c) // constructor
{
mContext = c;
}
void someOtherFunction()
{
new DynamicHeightAdapter(mContext, 1, rowItems);
}
}

Cant pass activity Context

Hello I'm trying to use object from one of my libaries, but I can't pass my corrent context.
The constructor is:
public AmbilWarnaDialog(final Context context, int color, OnAmbilWarnaListener listener)
And in my class I use this for the constructor:
AmbilWarnaDialog dialog = AmbilWarnaDialog(this, initialColor, new OnAmbilWarnaListener()
{
public void onOk(AmbilWarnaDialog dialog, int[] color) {
// color is the color selected by the user.
}
public void onCancel(AmbilWarnaDialog dialog) {
// cancel was selected by the user
}
});
I get this error:
The method AmbilWarnaDialog(Settings, int, new AmbilWarnaDialog.OnAmbilWarnaListener(){}) is undefined for the type Settings
I also tried getApplicationContex() and Settings.this and it's not working.
My imports are:
import yuku.ambilwarna.AmbilWarnaDialog;
import yuku.ambilwarna.AmbilWarnaKotak;
import yuku.ambilwarna.AmbilWarnaDialog.OnAmbilWarnaListener;
You cannot call a constructor directly, to instantiate a class use the new keyword like this:
AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, initialColor, new OnAmbilWarnaListener() { ...
Try this:
Context context;
private methodName(Context context) {
this.context = context;
}
call method in Activity:
methodName(this);
You are calling this method somewhere inside the Settings class (I am assuming Settings doesn't extend Context). You might be doing something like this:
public class MyClass extends Context {
public myMethod(){
new Settings(){
// the keyword this references to the Settings object instance, not MyClass object instance
// to reference Context use MyClass.this
// like Henry says below, make sure you use the new keyword to initialize objects
AmbilWarnaDialog dialog = new AmbilWarnaDialog(MyClass.this, initialColor, new OnAmbilWarnaListener() {...}
}
}
}

Categories

Resources