I am integrating Telr payment gateway in my app. I have used code from there dummy project which is working fine, I used their code in my fragment but it is throwing null context error. I have tried everything like "getContext" , "getApplicationContext" etc. but showing me error that context is null
Code :
public void sendMessage() {
Intent intent = new Intent(getActivity(), WebviewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.putExtra(WebviewActivity.EXTRA_MESSAGE, getMobileRequest());
intent.putExtra(WebviewActivity.SUCCESS_ACTIVTY_CLASS_NAME, "com.marketplace.activity.SuccessTransationActivity");
intent.putExtra(WebviewActivity.FAILED_ACTIVTY_CLASS_NAME, "com.marketplace.activity.FailedTransationActivity");
intent.putExtra(WebviewActivity.IS_SECURITY_ENABLED, isSecurityEnabled);
startActivity(intent);
}
There is a variable 'a' that exists in TelrApplication class.
extend your application with TelrApplication. This will resolve your problem.
public class TelrApplication extends Application {
private static Context a;
public TelrApplication() {
}
public void onCreate() {
super.onCreate();
Log.d("Hany", "Context Started....");
a = this.getApplicationContext();
}
public static Context a() {
return a;
}
}
Related
I have created a simple custom dialog class. In further code I want to run new Intent:
Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("http://maps.google.com/maps?saddr=20.344,34.34&daddr=20.5666,45.345"));
startActivity(intent);
But the problem is whenever I call to change into that Intent I always get null in getOwnerActivity() - how to properly call that method?
public class AddToQueueDialog extends Dialog implements View.OnClickListener {
Activity mActivity;
private final String android_id = Settings.Secure.getString(getContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
public Activity getmActivity() {
return mActivity;
}
public void setmActivity(Activity mActivity) {
this.mActivity = mActivity;
}
public AddToQueueDialog(Context context, WashLocation washLocation) {
super(context);
setWashLocation(washLocation);
setmActivity(getOwnerActivity());
}
If you will check the source code and the activity it returns is set only in setOwnerActivity(Activity activity) which is not called anywhere. So if you want getOwnerActivity() to return value different than null, you have to change your constructor like following
public AddToQueueDialog(Context context, WashLocation washLocation) {
super(context);
if (context instanceof Activity) {
setOwnerActivity((Activity) context);
}
setWashLocation(washLocation);
setmActivity(getOwnerActivity());
}
You cant call the getOwnerActivity() in Oncreate
If you try to get owner from the constructor, Android hasn't hooked it yet, so you have no owner yet.
try this instead
public void onAttachedToWindow() {
super.onAttachedToWindow();
// getOwnerActivity() should be defined here if called via showDialog(), so do the related init here
Activity owner = getOwnerActivity();
if (owner != null) {
// owner activity defined here
}
}
context is the owning Activity. Your constructor is called with context. This is the owning Activity.
My project have a activity named MainActivity and a BrowserActivity extend dialog service.
MainActivity will intent BrowserActivity on application started.
I would like to BrowserActivity can access MainActivity's public method.
something like that:
Method on MainActivity:
public void chooseShare(Intent intent)
{
try
{
startActivityForResult( intent , PICK_SHARE);
} catch (android.content.ActivityNotFoundException ex)
{
Log.e("Share" , ex.getMessage());
}
}
And i want to do on BrowserActivity :
(Pseudocode)
((MainActivity)BrowserActivity.this.getOwnerActivity()).chooseShare(intent);
I try to do that:
MainActivity ma = new MainActivity();
ma.chooseShare(i);
However, it not work, it throw NULLPointerException.
Because i need startActivityForResult() instead of startActivity() for callback result.
And i digg on SOF, i found startActivityForResult() should be start on Activity, but not Dialog.
thanks you.
You should be able to use getParent() if it's within the same project.
Activity parent = getParent();
if (parent instanceof MainActivity)
((MainActivity)parent).chooseShare(i);
Another option would be to bind it with an ibinder and use a service or implement interfaces.
Services | Android Developers
you can access all classes method like this:
Context context;
public ProceedDialog(#NonNull Context context) {
super(context);
this.context = context;
//do something
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//do something
}
#Override
public void onClick(View view) {
ParentActivity activity = (ParentActivity)context;
activity.method();
}
I had the same question. And I found a partial solution.
The key is that Activity is a subclass of Context.
You pass the Context paraneter to the constructor of your dialog, right?
And most people pass it by using this of MainActivity.
So, I used the following codes to get MainActivity reference.
private MainActivity getMainActivity()
{
Context c= getContext();
if( c instanceof MainActivity)
{
return (MainActivity)c;
}
return null;
}
Then you can call the desired method by
this.getMainActivity().chooseShare(intent);
In the dialog.
I tested this and it works!
Hope it helped you or forecomers.
(I saw the last modification date just now)
First, I am an android rookie, so my solution ways can be found awkward, and i am open to suggestions.
I am trying to create a game manager object that handles all transitions between activities. And my purpose is that while in an activity, menuOut method will call the changeActivity method of GameManager object with nextActivity argument and changeActivity will start that Activity. I am getting errors consistently, and did not find a solution.
Here is my source codes:
GameManager:
public class GameManager{
public SplashScreen splash = new SplashScreen();
public MainScreen main = new MainScreen();
public LoadingScreen load = new LoadingScreen();
Context tempContext;
public GameManager(Context base) {
super();
tempContext = base;
}
public void start(){
createScreens();
Intent intent = new Intent(tempContext, splash.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
tempContext.startActivity(intent);
}
public void createScreens() {
//here is the method that i am trying to find a solution
((SplashScreen)splash.getContext()).setGameClass(this);
((MainScreen)main.getContext()).setGameClass(this);
((LoadingScreen)load.getContext()).setGameClass(this);
}
public void changeMenu(MenuType nextMenu, MenuType previousMenu){
Intent intent2;
switch(nextMenu){
case MAIN_SC:
tempContext = main.getContext();
intent2.setClass(tempContext, main.getClass());
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
tempContext.startActivity(intent2);
case GAME_LOADING_SC:
tempContext = load.getContext();
intent2.setClass(tempContext, load.getClass());
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
tempContext.startActivity(intent2);
default:
break;
}
}
}
And here is SplashScreen activity:
public class SplashScreen extends Activity {
public Context context = this;
public GameManager gameman;
private static final int SPLASH_DURATION = 4000;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
splash();
menuOut();
}
public Context getContext() {
return this;
}
public void splash() {
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setBackgroundResource(R.drawable.game_loop_splash);
setContentView(ll);
Handler handler = new Handler();
// run a thread after 2 seconds to start the home screen
handler.postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
}, SPLASH_DURATION);
}
public void setGameClass(GameManager game){
gameman = game;
}
private void menuOut(){
gameman.changeMenu(MenuType.GAME_LOADING_SC, MenuType.GAME_SPLASH_SC);
this.onDestroy();
}
}
I can not return to the GameManager and call the changeMenu method.
I am very exhausted to get null pointer exceptions.
Any idea?
From what I read, you are trying to implement a singleton pattern. There are two ways I'd recommend to do that on android:
Extend the Application class, register your class in the manifest and use getApplication() in your activities to get access to it:
// In MyApplicationSubclass.java:
public final class MyApplicationSubclass extends Application {
/* ... */
public void myMethod() {
// insert some code here
}
/* ... */
}
// From your Activity:
((MyApplicationSubclass) this.getApplication()).myMethod();
Use a "normal" java singleton pattern, e.g. use a private constructor and keep one static instance within your GameManager class (this is the way the Android docs recommend, but I personally prefer the first way when having something that is logically bound to the Application).
Also, if you're only using your central class to do static stuff, you can just mark all its method as static and access them directly. Transfer Context objects as parameters to these methods, and you should be able to start activities without any static variables (which are sometimes hard to implement properly in Android, as your VM might get restarted from time to time).
I have a non-activity class that needs to launch a new activity. Right now I just pass the current context as a parameter, but I would like to access the context statically if possible. I've already tried creating a new application (MyApplication extends Application), both as a new application and the main application, and neither worked. Any suggestions?
Current Code:
public class SharedFunctions {
public static void doSomething(Context context){
Intent i = new Intent(context, NextActivity.class);
context.startActivity(i);
}
}
The cleaner way to do it is to pass in a Context to each method. It's more typing, but it helps to make sure you're not leaking the reference.
Of course, if you really need static reference to it, you can just keep a static member in your SharedFunctions class and set it for each Activity.
onResume() and onPause() may be good places to set/clear it, but depending on your needs, you might want to change it. Just try not to keep references to old Activities.
public class SharedFunctions{
private static Context context;
public static void setContext(Context ctx){
context = ctx;
}
public static void doSomething(){
context.someContextFunction();
}
}
In each Activity:
protected void onResume(){
SharedFunctions.setContext(this);
}
protected void onPause(){
SharedFunctions.setContext(null);
}
create this class:
public class MyApplication
extends Application
{
private static Context context;
#Override
public void onCreate()
{
super.onCreate();
context = getApplicationContext();
}
public static Context getContext()
{
return context;
}
}
after that you must add this class to field name in application (Manifest)
<application
android:name="yourPackageName.MyApplication"
........
</application >
As a result you can call MyApplication.getContext() anywhere in your application and get the context.
hope, I help you.
I've made a separate class to launch and intent as the class I would like to launch the intent from is a thread and does not inherit from activity and would not launch startActivity. Every time I launch the app I get a null pointer exception for the context.
public class ToLaunch extends Activity {
public void launchScoreloop() {
con.getApplicationContext();
startActivity(new Intent(this, LeaderboardsScreenActivity.class));
}
}
You Are writing an Activity , and you didn't override the method onCreate().
public class ToLaunch extends Activity {
#override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Call your method here after a button click cor example or something else
}
public void launchScoreloop() {
con.getApplicationContext();
startActivity(new Intent(this, LeaderboardsScreenActivity.class));
}
}
refer this two tutorials about using intents to start another Activity :
tuto 1
tuto 2
And if you want to launch the Activity from another Class , you should pass the context to the second Class like this :
SecondClass instance = new SecondClass(this);
and the contructor of your SecondClass will be something like this :
public void SecondClass(Context _context){
this.context = _context;
}
and then you can start the Avtivity by using the context that you passed to your SecondClass like this :
this.context.startActivity(....);
If thread is a inner class inside your activity you can use
startActivity(new Intent(YourActivity.this, LeaderboardsScreenActivity.class));
If it is a separate class you can make a constructor that take context has constructor as argument and you can pass your activity context into that constructor
Context con;
public YourThread(Context context){
con = context;
}
and from inside your activity, while making thread object
YourThread thread = new YourThread(this);