PreferenceFragment does not receive an onActivityResult request from a request request

I have a preferences screen that provides the user with a checkbox to disable ads. When a user clicks on this for the first time, they are given the option to purchase in-app purchases to disable ads.

The problem I am facing is that I see no way to get the onActivityResult callback to the fragment.

So, I have a PreferenceActivity, loading a PreferenceFragment (from which I cannot get the link). In the application, Billing requires a call to startIntentSenderForResult , in which there are no fragments, only actions.

When I start the shopping stream using startIntentSenderForResult , the Activity onActivityResult , but I need this in the fragment.

Since I loaded the PreferenceFragment into the PreferenceActivity with the following, I don’t think I can get a fragment reference to pass the call.

 @Override public void onBuildHeaders(List<Header> target) { loadHeadersFromResource(R.layout.preferences_headers, target); } @Override public Intent getIntent() { final Intent modIntent = new Intent(super.getIntent()); modIntent.putExtra(EXTRA_SHOW_FRAGMENT, SyncPreferencesFragment.class.getName()); modIntent.putExtra(EXTRA_NO_HEADERS, true); return modIntent; } 

What am I missing here? I do not want to share the whole logic of the purchase, so how can I get my fragment for calling onActivityForResult ?

+1
source share
2 answers

The initial launch request must come from Fragment so that Android returns the result back to the same Fragment . If an Activity starts a query, the result is not essentially passed to each Fragment that can be attached to the dispatcher. In addition to this, you must make sure that if onActivityResult() overridden at the top level of the Activity , you call super.onActivityResult() and the message will not be delivered to Fragment .

The problem with the IAB is that for PendingIntent instead of the standard Intent the Fragment method is not set to initiate the initial action, even if you can move your code there. To keep things as they are, you may need to see a bit. One thing you can do is use the user interface inside the onAttach() method of your Fragment and use it to let the Fragment pass itself before the Activity . Sort of:

 public class SyncPreferencesActivity extends PreferenceActivity implements SyncPreferencesFragment.OnAttachCallback { SyncPreferencesFragment mTargetFragment; @Override public void onAttachSyncFragment(SyncPreferencesFragment fragment) { mTargetFragment = fragment; } } 

... with some additions to the corresponding Fragment ...

 public class SyncPreferencesFragment extends PreferenceFragment { public interface OnAttachCallback { public void onAttachSyncFragment(SyncPreferencesFragment fragment); } @Override public void onAttach(Activity activity) { try { OnAttachCallback callback = (OnAttachCallback) activity; callback.onAttachSyncFragment(this); } catch (ClassCastException e) { throw new ClassCastException("You Forgot to Implement the Callback!"); } } } 

With something like this, at least you have a reference to the instance so that you can redirect the result or something else that might be required. If you want to be super clean, you can also implement the corresponding β€œbreakaway” that clears the link in the Activity .

+5
source

Here is a simpler way that I use to get a link to a fragment of preferences from a select operation:

 private WeakReference<GeneralPreferenceFragment> mGeneralFragment; @Override public void onAttachFragment(Fragment fragment) { super.onAttachFragment(fragment); // "id" might be arbitrary and "tag" can be null Log.d(TAG, "onAttachFragment: "+fragment.getId()+","+fragment.getTag()); // however class can be used to identify different fragments Log.d(TAG, "onAttachFragment: "+fragment.getClass()+","+(fragment instanceof GeneralPreferenceFragment)); if(fragment instanceof GeneralPreferenceFragment) { mGeneralFragment=new WeakReference<>((GeneralPreferenceFragment)fragment); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Fragment f=mGeneralFragment.get(); if(f!=null) { // can now use findPreference, etc } } 

This method is convenient because it does not require the use of interfaces or modifications to fragment classes.

0
source

Source: https://habr.com/ru/post/1384208/


All Articles