I've a method in my activity , How do I call that method from another class (Not from activity) , since I need to pass arguments to that class . Am getting nullPointerException if I create an object for my activity , please anyone help me
Dont put your data in Activity class . Generally from activy to activity Bundle params is used to pass data . BUt if you tell me your exact problem then may be taht we can find any solution.
Well not sure if i understood correctly but,
Can't you pass around a reference from the Activity to the "other" class method? Like :
class YourClass {
//bla bla bla
public void yourMethod(Activity activity)
{
if(null != activity)
activity.method();
else
//something
}
}
cheers
Related
I'm creating a chat app and according to the tutorial I should create this:
Tutorial example
The problem is that nowadays this function (FirebaseInstanceIdService) no longer exists and therefore I cannot use it.
Would anyone advise me with what code to achieve the same result?
Thank you
FirebaseInstanceIdService has been depracated and replaced with FirebaseMessagingService
https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceIdService
onTokenRefresh is now onNewToken.
Within the class extending FirebaseMessagingService, in which you are already overriding onMessageReceived() method, override the onNewToken(token: String) method (this replaces the old onTokenRefresh(), so all the logic you had there, must be put here).
With Kotlin,
override fun onMessageReceived(remoteMessage: RemoteMessage) {
//the logic here
}
override fun onNewToken(token: String) {
//all the logic of the old FirebaseInstanceIdService.onTokenRefresh() here
//usually, to send to the app server the instance ID token
sendTokenToTheAppServer(token)
}
This question is mostly to solicit opinions on the best way to handle my app. I have three fragments being handled by one activity. Fragment A has one clickable element the photo and Fragment B has 4 clickable elements the buttons. The other fragment just displays details when the photo is clicked. I am using ActionBarSherlock.
The forward and back buttons need to change the photo to the next or previous poses, respectively. I could keep the photo and the buttons in the same fragment, but wanted to keep them separate in case I wanted to rearrange them in a tablet.
I need some advice - should I combine Fragments A and B? If not, I will need to figure out how to implement an interface for 3 clickable items.
I considered using Roboguice, but I am already extending using SherlockFragmentActivity so that's a no go. I saw mention of Otto, but I didn't see good tutorials on how to include in a project. What do you think best design practice should be?
I also need help figuring out how to communicate between a fragment and an activity. I'd like to keep some data "global" in the application, like the pose id. Is there some example code I can see besides the stock android developer's information? That is not all that helpful.
BTW, I'm already storing all the information about each pose in a SQLite database. That's the easy part.
The easiest way to communicate between your activity and fragments is using interfaces. The idea is basically to define an interface inside a given fragment A and let the activity implement that interface.
Once it has implemented that interface, you could do anything you want in the method it overrides.
The other important part of the interface is that you have to call the abstract method from your fragment and remember to cast it to your activity. It should catch a ClassCastException if not done correctly.
There is a good tutorial on Simple Developer Blog on how to do exactly this kind of thing.
I hope this was helpful to you!
The suggested method for communicating between fragments is to use callbacks\listeners that are managed by your main Activity.
I think the code on this page is pretty clear:
http://developer.android.com/training/basics/fragments/communicating.html
You can also reference the IO 2012 Schedule app, which is designed to be a de-facto reference app. It can be found here:
http://code.google.com/p/iosched/
Also, here is a SO question with good info:
How to pass data between fragments
It is implemented by a Callback interface:
First of all, we have to make an interface:
public interface UpdateFrag {
void updatefrag();
}
In the Activity do the following code:
UpdateFrag updatfrag ;
public void updateApi(UpdateFrag listener) {
updatfrag = listener;
}
from the event from where the callback has to fire in the Activity:
updatfrag.updatefrag();
In the Fragment implement the interface in CreateView do the
following code:
((Home)getActivity()).updateApi(new UpdateFrag() {
#Override
public void updatefrag() {
.....your stuff......
}
});
To communicate between an Activity and Fragments, there are several options, but after lots of reading and many experiences, I found out that it could be resumed this way:
Activity wants to communicate with child Fragment => Simply write public methods in your Fragment class, and let the Activity call them
Fragment wants to communicate with the parent Activity => This requires a bit more of work, as the official Android link https://developer.android.com/training/basics/fragments/communicating suggests, it would be a great idea to define an interface that will be implemented by the Activity, and which will establish a contract for any Activity that wants to communicate with that Fragment. For example, if you have FragmentA, which wants to communicate with any activity that includes it, then define the FragmentAInterface which will define what method can the FragmentA call for the activities that decide to use it.
A Fragment wants to communicate with other Fragment => This is the case where you get the most 'complicated' situation. Since you could potentially need to pass data from FragmentA to FragmentB and viceversa, that could lead us to defining 2 interfaces, FragmentAInterface which will be implemented by FragmentB and FragmentAInterface which will be implemented by FragmentA. That will start making things messy. And imagine if you have a few more Fragments on place, and even the parent activity wants to communicate with them. Well, this case is a perfect moment to establish a shared ViewModel for the activity and it's fragments. More info here https://developer.android.com/topic/libraries/architecture/viewmodel . Basically, you need to define a SharedViewModel class, that has all the data you want to share between the activity and the fragments that will be in need of communicating data among them.
The ViewModel case, makes things pretty simpler at the end, since you don't have to add extra logic that makes things dirty in the code and messy. Plus it will allow you to separate the gathering (through calls to an SQLite Database or an API) of data from the Controller (activities and fragments).
I made a annotation library that can do the cast for you. check this out.
https://github.com/zeroarst/callbackfragment/
#CallbackFragment
public class MyFragment extends Fragment {
#Callback
interface FragmentCallback {
void onClickButton(MyFragment fragment);
}
private FragmentCallback mCallback;
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt1
mCallback.onClickButton(this);
break;
case R.id.bt2
// Because we give mandatory = false so this might be null if not implemented by the host.
if (mCallbackNotForce != null)
mCallbackNotForce.onClickButton(this);
break;
}
}
}
It then generates a subclass of your fragment. And just add it to FragmentManager.
public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction()
.add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), "MY_FRAGM")
.commit();
}
Toast mToast;
#Override
public void onClickButton(MyFragment fragment) {
if (mToast != null)
mToast.cancel();
mToast = Toast.makeText(this, "Callback from " + fragment.getTag(), Toast.LENGTH_SHORT);
mToast.show();
}
}
Google Recommended Method
If you take a look at this page you can see that Google suggests you use the ViewModel to share data between Fragment and Activity.
Add this dependency:
implementation "androidx.activity:activity-ktx:$activity_version"
First, define the ViewModel you are going to use to pass data.
class ItemViewModel : ViewModel() {
private val mutableSelectedItem = MutableLiveData<Item>()
val selectedItem: LiveData<Item> get() = mutableSelectedItem
fun selectItem(item: Item) {
mutableSelectedItem.value = item
}
}
Second, instantiate the ViewModel inside the Activity.
class MainActivity : AppCompatActivity() {
// Using the viewModels() Kotlin property delegate from the activity-ktx
// artifact to retrieve the ViewModel in the activity scope
private val viewModel: ItemViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.selectedItem.observe(this, Observer { item ->
// Perform an action with the latest item data
})
}
}
Third, instantiate the ViewModel inside the Fragment.
class ListFragment : Fragment() {
// Using the activityViewModels() Kotlin property delegate from the
// fragment-ktx artifact to retrieve the ViewModel in the activity scope
private val viewModel: ItemViewModel by activityViewModels()
// Called when the item is clicked
fun onItemClicked(item: Item) {
// Set a new item
viewModel.selectItem(item)
}
}
You can now edit this code creating new observers or settings methods.
There are severals ways to communicate between activities, fragments, services etc. The obvious one is to communicate using interfaces. However, it is not a productive way to communicate. You have to implement the listeners etc.
My suggestion is to use an event bus. Event bus is a publish/subscribe pattern implementation.
You can subscribe to events in your activity and then you can post that events in your fragments etc.
Here on my blog post you can find more detail about this pattern and also an example project to show the usage.
I'm not sure I really understood what you want to do, but the suggested way to communicate between fragments is to use callbacks with the Activity, never directly between fragments. See here http://developer.android.com/training/basics/fragments/communicating.html
You can create declare a public interface with a function declaration in the fragment and implement the interface in the activity. Then you can call the function from the fragment.
I am using Intents to communicate actions back to the main activity. The main activity is listening to these by overriding onNewIntent(Intent intent). The main activity translates these actions to the corresponding fragments for example.
So you can do something like this:
public class MainActivity extends Activity {
public static final String INTENT_ACTION_SHOW_FOO = "show_foo";
public static final String INTENT_ACTION_SHOW_BAR = "show_bar";
#Override
protected void onNewIntent(Intent intent) {
routeIntent(intent);
}
private void routeIntent(Intent intent) {
String action = intent.getAction();
if (action != null) {
switch (action) {
case INTENT_ACTION_SHOW_FOO:
// for example show the corresponding fragment
loadFragment(FooFragment);
break;
case INTENT_ACTION_SHOW_BAR:
loadFragment(BarFragment);
break;
}
}
}
Then inside any fragment to show the foo fragment:
Intent intent = new Intent(context, MainActivity.class);
intent.setAction(INTENT_ACTION_SHOW_FOO);
// Prevent activity to be re-instantiated if it is already running.
// Instead, the onNewEvent() is triggered
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
getContext().startActivity(intent);
There is the latest techniques to communicate fragment to activity without any interface follow the steps
Step 1- Add the dependency in gradle
implementation 'androidx.fragment:fragment:1.3.0-rc01'
I'm currently writing an App, it gets JSON from a website, and then lists the contents in a listview. Now since the API itself only returns names like this: "twisted_castle" instead of "Twisted Castle", I created a new class to substitute the generic names to the right names, which I previously added to the strings.xml.
Now I can get Strings via String test = getString(R.string.key) in the MainActivity, but since I created a new class for the Substitute to happen, I somehow can't use getString somehow.
I already discovered that I'll need to get/use the context of MainActivity somehow, but really any solution I found didn't work, and also I'm a bit irritated on how the whole context thing works.
Anyone can help me with this and maybe has a good explanation on how contexts work?
You can use Context as:
mcontext.getString(R.string.something);
all you have to do is init context in the class some where like:
static Context mcontext;
public void setmContext(Context context){
this.mcontext=context;
}
and call setmContext(this) from your activity or where ever you have context attribute
I want to ask why we get this annotation:
Method invocation getContext.getContentResolver() may produce
NullPointerException
Why is it there and not in other parts of program Fragment/Activity? That approach has been used in tutorial made by Google - here is link for ContentProvider code https://github.com/udacity/Sunshine-Version-2/blob/sunshine_master/app/src/main/java/com/example/android/sunshine/app/data/WeatherProvider.java even if you create an aplication with just a blank activity and put that method in a newly created ContentProvider it is there.
Should we use getContext().getContentResolver().notifyChange(uri, null);outside ContentProvider getting the uri passed and then after the update/insert/delete is finished notifyChange? or maybe we can fix it somehow?
If you look in the source of ContentProvider (just hold SHIFT and click on the classname in Android Studio) then you will find that the implementation is holding an object of type Context as mContext.
Your solution is just the same, which means if mContext of ContentProvider is null, your reference will also be null. So there is no need for this.
To help you out, this is just a warning of your IDE if make such a construct yourself. But in this case there will always be context, because the ContentProvider is generated by your system. To avoid the error in your IDE just write #SuppressWarnings("ConstantConditions") above your class definition like:
...
#SuppressWarnings("ConstantConditions")
public class NoteProvider extends ContentProvider {
...
If you can make sure that getContext() can never be null then you can simply ignore this warning. I think the warning even disappears of you just check for null:
if (getContext() != null) {
getContext().getContentResolver();
}
You just have to keep in mind the code won't be executed if getContext() is null.
Cheers
edit:
Be careful with the answer #Shivani Gupta gave you, because you could get different contexts. See: Difference between getContext() , getApplicationContext() , getBaseContext() and "this"
Write getApplicationContext().getContentResolver()
Hope this will work.
Ok it seems I fixed it myself by declaring Context on the beggining of the class.
public class NoteProvider extends ContentProvider {
Context context;
then initializing it in onCreate()
#Override
public boolean onCreate() {
mSQLiteOpenHelper = new NoteDbHelper(getContext());
context = getContext();
return true;
}
I think that made sure that I always have Context when I use context.getContentResolver().notifyChange(uri, null); or retCursor.setNotificationUri(context.getContentResolver(), uri); in insert/update/delete/query method- retCursor being returned cursor by mentioned methods.
I have run the aplication on my phone and did not have issues yet if I will there will probably be an edit for this post.
EDIT:
It does not make a difference after all - explanationin answer by #Mate, thank you for that I think I get it now :]
According to ContentProvider getContext() docs:
Retrieves the Context this provider is running in. Only available once onCreate() has been called -- this will return null in the constructor.
So the getContext() method does not return null in insert(), update() or delete(), because onCreate() will be called before these calls.
So it's OK to disable that warning for that line if you use it in such case...
//noinspection ConstantConditions
getContext().getContentResolver().notifyChange(uri, null);
Whenever you try to use a member or a method of an object, you can have a runtime exception if the object, whose member/method you try to use is null. Let's suppose you want to use a member/method of an object, obj. If you use it like this:
if (obj != null) {
//use members/methods of obj
}
then you prevented the problem. However, you might want to handle it as an exception, like this:
try {
//use members/methods of obj
} catch (NullPointerException npe) {
//handle the NullPointerException
}
I'm having a problem with casting in Android.
I'm developing an App that handle multiple devices, and i'm trying to make a dynamic class alocation (i.e, User sets the device and the app instanciate the class according to the user settings)
Here is a Sample code:
String Usr_imput; //name of the class
Class class = Class.forName(Usr_Input);
Object o = class.newInstance();
with that I can't access methods from the Usr_Input Class. The method class.cast(o) should be the solution to my problems but I can't get it to work, does the cast statement stacks?
Isn't it suposed to work if I use:
class.cast(o);
o.Method();
Anyone has experience on that?
Usr_Input o = (Usr_Input)class.newInstance();
from java doc:
cast
public T cast(Object obj)
blahblah..
Returns:
the object after casting, or null if obj is null
From your codes, you didn't catch the return value. class is not a good name either. check the comment above.
class.cast(o);
o.Method();