I am developing the android application in which using Kaltura native android sdk to play the video. android-native-kaltura-sdk
I am able to play the video. but when i change the orientation of mobile (Portrait to Landscape) player is not resumed.
Issue is player get restart.
VideoDetailActivity Class
public class VideoDetailActivity extends AppCompatActivity implements DraggableListener, OnTaskFinishedListener, KPEventListener {
public boolean isPlaying;
private static final int FULL_SCREEN_FLAG = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
private PlayerFragment mPlayerFragment;
// TODO: Rename and change types of parameters
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_detail);
ButterKnife.bind(this);
if (getFragmentManager().findFragmentByTag(PlayerFragment.class.getName()) == null) {
Log.d(TAG, this + ": Existing fragment not found.");
isPlaying = false;
mPlayerFragment = new PlayerFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();//.setCustomAnimations(R.anim.slide_up, R.anim.slide_down);
// transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
transaction.add(R.id.fragment_container, mPlayerFragment, PlayerFragment.class.getName());
transaction.addToBackStack(mPlayerFragment.getClass().getName());
transaction.commit();
} else {
if (savedInstanceState != null) {
isPlaying = savedInstanceState.getBoolean("isPlaying");
}
mPlayerFragment = (PlayerFragment) getFragmentManager().findFragmentByTag(PlayerFragment.class.getName());
Log.d(TAG, this + ": Existing fragment found.");
}
}
/**
* Pause the VideoView content.
*/
private void pauseVideo() {
if (player != null) {
player.releaseAndSavePosition();
}
}
/**
* Resume the VideoView content.
*/
private void startVideo() {
if (player != null) {
player.resumePlayer();
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//player.releaseAndSavePosition();
mPlayerFragment.pausePlayer();
// mPlayerFragment.killPlayer();
outState.putBoolean("isPlaying", isPlaying);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//player.resumePlayer();
//isPlaying = savedInstanceState.getBoolean("isPlaying");
/* if (isPlaying) {
mPlayerFragment.resumePlayer();
}*/
}
public void isPlaying(boolean value) {
isPlaying = value;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mPlayerFragment != null) {
mPlayerFragment.killPlayer();
}
// if (player != null)
//player.resumePlayer();
}
#Override
protected void onPause() {
super.onPause();
if (!isFinishing() && mPlayerFragment != null) {
//mPlayerFragment.killPlayer();
/* mPlayerFragment = null;*/
isPlaying = true;
}
}
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
mPlayerFragment.pausePlayer();
} else {
super.onBackPressed();
}
}
}
PlayerFragment Class
public class PlayerFragment extends Fragment implements KPEventListener {
private boolean isResumed = false;
private View mFragmentView = null;
private PlayerViewController mPlayerView;
private boolean mFullScreen = true;
private OnFragmentInteractionListener mListener;
public PlayerFragment() {
// Required empty public constructor
}
public static PlayerFragment newInstance(String param1, String param2) {
PlayerFragment fragment = new PlayerFragment();
/* Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);*/
return fragment;
}
public void pausePlayer() {
mPlayerView.releaseAndSavePosition();
}
public void killPlayer() {
mPlayerView.removePlayer();
mPlayerView = null;
//getActivity().getFragmentManager().beginTransaction().remove(this).commit();
}
public void resumePlayer() {
mPlayerView.resumePlayer();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
/* if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}*/
// getActivity().getActionBar().hide();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
mFragmentView = inflater.inflate(R.layout.fragment_player, container, false);
return mFragmentView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mPlayerView = (PlayerViewController) mFragmentView.findViewById(R.id.player);
mPlayerView.loadPlayerIntoActivity(getActivity());
if (!((VideoDetailActivity) getActivity()).isPlaying) {
((VideoDetailActivity) getActivity()).isPlaying(true);
KPPlayerConfig config = new KPPlayerConfig("http://cdnapi.kaltura.com", "Player Cofig ID", "Kaltura Partner ID");
config.setEntryId("Video EntryID");
mPlayerView.initWithConfiguration(config);
mPlayerView.addEventListener(this);
} else {
mPlayerView.resumePlayer();
}
}
public void setFullScreen(boolean fullScreen) {
fullScreen = false;
if (mFullScreen) {
Log.v("FullScreen", "-----------Set full screen SCREEN_ORIENTATION_LANDSCAPE------------");
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
/* int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
android.widget.FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) videoSurface.getLayoutParams();
params.width = width;
params.height=height;
params.setMargins(0, 0, 0, 0);*/
//set icon is full screen
mFullScreen = fullScreen;
} else {
Log.v("FullScreen", "-----------Set small screen SCREEN_ORIENTATION_PORTRAIT------------");
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
/* final FrameLayout mFrame = (FrameLayout) findViewById(R.id.videoSurfaceContainer);
// int height = displaymetrics.heightPixels;
int height = mFrame.getHeight();//get height Frame Container video
int width = displaymetrics.widthPixels;
android.widget.FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) videoSurface.getLayoutParams();
params.width = width;
params.height= height;
params.setMargins(0, 0, 0, 0);*/
//set icon is small screen
mFullScreen = !fullScreen;
}
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
#Override
public void onKPlayerStateChanged(PlayerViewController playerViewController, KPlayerState state) {
switch (state) {
case READY:
Log.e("KPlayer State Changed", "Player State READY :- " + state.toString() + "###################################################################");
((VideoDetailActivity) getActivity()).isPlaying(true);
break;
case LOADED:
Log.e("KPlayer State Changed", "Player State LOADED :- " + state.toString() + "###################################################################");
break;
case PAUSED:
Log.e("KPlayer State Changed", "Player State PAUSED :- " + state.toString() + "###################################################################");
break;
case SEEKED:
Log.e("KPlayer State Changed", "Player State PAUSED :- " + state.toString() + "###################################################################");
break;
case SEEKING:
Log.e("KPlayer State Changed", "Player State PAUSED :- " + state.toString() + "###################################################################");
break;
}
}
#Override
public void onKPlayerPlayheadUpdate(PlayerViewController playerViewController, float currentTime) {
Log.e("KPlayer State Changed", "Player State PAUSED :- " +currentTime + "###################################################################");
}
#Override
public void onKPlayerFullScreenToggeled(PlayerViewController playerViewController, boolean isFullscreen) {
setFullScreen(isFullscreen);
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
Related
I've been facing issues with my MoviesApp for a while now and I feel that I've exhausted all my knowledge on this; I am quite new with Android so bear with me :-)
MoviesApp is a simple movie listing app, in which the user can scroll through the list of films, see details for each one and save their favorites in an SQLite DB.
I use SharedPreference to sort movies based by popularity, rating and favorites (the only list saved in the database), but when I change through each one, the UI is not updating at all.
I am really stuck and honestly, I could do with another pair of eyes, because, even if the answer is staring me in the face, I wouldn't be able to see it 😫😫😫
I pasted the link to the project below:
https://drive.google.com/file/d/1SweLpwfo5RntXrbtLPP3N_xS1bVs32Ze/view?usp=sharing
Thank you!!
Update: I believe the problem would in the MainActivity class, where the RecyclerView Loader is declared - specifically in onLoadFinished().
#SuppressWarnings({"WeakerAccess", "unused", "CanBeFinal"})
public class MainActivity extends AppCompatActivity implements
LoaderManager.LoaderCallbacks,
MovieAdapter.MovieDetailClickHandler, SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = MainActivity.class.getSimpleName();
public static final String MOVIE_ID = "movieId";
private final static String LIFECYCLE_CALLBACKS_LAYOUT_MANAGER_KEY = "KeyForLayoutManagerState";
Parcelable savedLayoutManagerState;
public RecyclerView movieListRV;
private GridLayoutManager gridLayoutManager =
new GridLayoutManager(this, 1);
Context context = this;
// Loader IDs for loading the main API and the poster API, respectively
private static final int ID_LOADER_LIST_MOVIES = 1;
private static final int ID_LOADER_CURSOR = 2;
// adapter
private MovieAdapter adapter;
// detect internet connection
NetworkDetection networkDetection;
// swipe to refresh
SwipeRefreshLayout swipeRefreshLayout;
// sortOption
String sortOption = null;
// movie projection
private final String[] projection = new String[]{
MoviesContract.MovieEntry.COLUMN_MOVIE_POSTER,
MoviesContract.MovieEntry.COLUMN_MOVIE_ID
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Stetho.initializeWithDefaults(this);
Toolbar toolbar = findViewById(R.id.settings_activity_toolbar);
setSupportActionBar(toolbar);
toolbar.setTitleTextColor(Color.WHITE);
networkDetection = new NetworkDetection(this);
swipeRefreshLayout = findViewById(R.id.discover_swipe_refresh);
swipeRefreshLayout.setOnRefreshListener(MainActivity.this);
swipeRefreshLayout.setColorScheme(android.R.color.holo_red_dark);
movieListRV = findViewById(R.id.recycler_view_movies);
movieListRV.setLayoutManager(gridLayoutManager);
movieListRV.setHasFixedSize(true);
ViewTreeObserver viewTreeObserver = movieListRV.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
calculateSize();
}
});
adapter = new MovieAdapter(this, this);
movieListRV.setAdapter(adapter);
RecyclerViewItemDecorator itemDecorator = new RecyclerViewItemDecorator(context,
R.dimen.item_offset);
movieListRV.addItemDecoration(itemDecorator);
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences
(context);
SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = new
SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
adapter.deleteItemsInList();
onRefresh();
if (key.equals(getString(R.string.pref_sort_by_key))) {
initializeloader();
}
}
};
preferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
initializeloader();
}
private static final int sColumnWidth = 200;
private void calculateSize() {
int spanCount = (int) Math.floor(movieListRV.getWidth() / convertDPToPixels(sColumnWidth));
((GridLayoutManager) movieListRV.getLayoutManager()).setSpanCount(spanCount);
}
#SuppressWarnings("SameParameterValue")
private float convertDPToPixels(int dp) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float logicalDensity = metrics.density;
return dp * logicalDensity;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(LIFECYCLE_CALLBACKS_LAYOUT_MANAGER_KEY, gridLayoutManager
.onSaveInstanceState());
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
savedLayoutManagerState = savedInstanceState.getParcelable
(LIFECYCLE_CALLBACKS_LAYOUT_MANAGER_KEY);
movieListRV.getLayoutManager().onRestoreInstanceState(savedLayoutManagerState);
}
}
#Override
public Loader onCreateLoader(int id, Bundle args) {
adapter.deleteItemsInList();
String urlMovieActivity;
switch (id) {
case ID_LOADER_CURSOR:
return new CursorLoader(context, MoviesContract.MovieEntry.MOVIES_CONTENT_URI,
projection, null, null, null);
case ID_LOADER_LIST_MOVIES:
urlMovieActivity = NetworkUtils.buildUrlMovieActivity(context, sortOption);
return new MovieLoader(this, urlMovieActivity);
default:
return null;
}
}
#Override
public void onLoadFinished(Loader loader, Object data) {
adapter.deleteItemsInList();
TextView noMoviesMessage = findViewById(R.id.no_movies_found_tv);
switch (loader.getId()) {
case ID_LOADER_CURSOR:
adapter.InsertList(data);
break;
case ID_LOADER_LIST_MOVIES:
//noinspection unchecked
List<MovieItem> movieItems = (List<MovieItem>) data;
if (networkDetection.isConnected()) {
noMoviesMessage.setVisibility(View.GONE);
adapter.InsertList(movieItems);
movieListRV.getLayoutManager().onRestoreInstanceState(savedLayoutManagerState);
} else {
noMoviesMessage.setVisibility(View.VISIBLE);
}
break;
}
adapter.notifyDataSetChanged();
}
#Override
public void onLoaderReset(Loader loader) {
switch (loader.getId()) {
case ID_LOADER_CURSOR:
adapter.InsertList(null);
break;
case ID_LOADER_LIST_MOVIES:
adapter.InsertList(null);
break;
}
}
#Override
public void onPostResume(Loader loader) {
super.onPostResume();
getLoaderManager().initLoader(ID_LOADER_CURSOR, null, this);
}
#Override
public void onSelectedItem(int movieId) {
Intent goToDetailActivity = new Intent(this, DetailMovieActivity.class);
goToDetailActivity.putExtra(MOVIE_ID, movieId);
startActivity(goToDetailActivity);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_general, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
int id = menuItem.getItemId();
if (id == R.id.action_general_settings) {
Intent goToSetting = new Intent(this, SettingsActivity.class);
startActivity(goToSetting);
return true;
} else if (id == R.id.action_refresh) {
onRefresh();
}
return super.onOptionsItemSelected(menuItem);
}
/**
* Called when a swipe gesture triggers a refresh.
*/
#Override
public void onRefresh() {
adapter.deleteItemsInList();
swipeRefreshLayout.setRefreshing(false);
restartloader();
adapter.notifyDataSetChanged();
}
private void restartloader() {
adapter.deleteItemsInList();
if (MoviePreferences.getSortByPreference(context).equals(getString(R.string
.pref_sort_by_favourite))) {
getLoaderManager().restartLoader(ID_LOADER_CURSOR, null, MainActivity
.this);
}
if (MoviePreferences.getSortByPreference(context).equals(getString(R.string
.pref_sort_by_popularity))) {
sortOption = NetworkUtils.MOST_POPULAR_PARAM;
getLoaderManager().restartLoader(ID_LOADER_LIST_MOVIES, null,
MainActivity.this);
}
if (MoviePreferences.getSortByPreference(context).equals(getString(R.string
.pref_sort_by_rating))) {
sortOption = NetworkUtils.TOP_RATED_PARAM;
getLoaderManager().restartLoader(ID_LOADER_LIST_MOVIES, null,
MainActivity.this);
}
adapter.notifyDataSetChanged();
}
public void initializeloader() {
restartloader();
if (MoviePreferences.getSortByPreference(context).equals(getString(R.string
.pref_sort_by_favourite))) {
getLoaderManager().initLoader(ID_LOADER_CURSOR, null, MainActivity
.this);
}
if (MoviePreferences.getSortByPreference(context).equals(getString(R.string
.pref_sort_by_popularity))) {
onRefresh();
sortOption = NetworkUtils.MOST_POPULAR_PARAM;
getLoaderManager().initLoader(ID_LOADER_LIST_MOVIES, null,
MainActivity.this);
}
if (MoviePreferences.getSortByPreference(context).equals(getString(R.string
.pref_sort_by_rating))) {
onRefresh();
sortOption = NetworkUtils.TOP_RATED_PARAM;
getLoaderManager().initLoader(ID_LOADER_LIST_MOVIES, null,
MainActivity.this);
}
adapter.notifyDataSetChanged();
}
}
I want to get data from activity but I keep getting error this error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference.
TrafficActivity.class (Activity)
public class TrafficActivity extends AppCompatActivity {
public static final String FRAGMENT_PDF_RENDERER_BASIC = "pdf_renderer_basic";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_traffic);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_traffic);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(TrafficActivity.this, IpuclariSayfasi.class));
}
});
if (savedInstanceState == null)
{
getFragmentManager().beginTransaction()
.add(R.id.container, new PdfRendererBasicFragment(), FRAGMENT_PDF_RENDERER_BASIC)
.commit();
}
}}
PdfRendererBasicFragment.class(Fragment)
public class PdfRendererBasicFragment extends Fragment implements
View.OnClickListener
{
private static final String O_ANKI_SAYFA_DURUMU = "guncel_sayfa_index";
private ParcelFileDescriptor mFileDescriptor;
private PdfRenderer mPdfRenderer;
private PdfRenderer.Page mGuncelSayfa;
private ImageView mImageView;
private ImageButton mOncekiButon;
private ImageButton mSonrakiButon;
public static String FILENAME;
public PdfRendererBasicFragment()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_pdf_renderer_basic, container, false);
}
#Override
public void onClick(View view)
{
switch (view.getId()) {
case R.id.onceki: {
//onceki sayfaya geç
showPage(mGuncelSayfa.getIndex() - 1);
break;
}
case R.id.sonraki: {
// sonraki sayfaya geç
showPage(mGuncelSayfa.getIndex() + 1);
break;
}
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mImageView = (ImageView) view.findViewById(R.id.pdf_goruntusu);
mOncekiButon = (ImageButton) view.findViewById(R.id.onceki);
mSonrakiButon = (ImageButton) view.findViewById(R.id.sonraki);
mOncekiButon.setOnClickListener(this);
mSonrakiButon.setOnClickListener(this);
int index = 0;
if (null != savedInstanceState) {
index = savedInstanceState.getInt(O_ANKI_SAYFA_DURUMU, 0);
}
showPage(index);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
openRenderer(activity);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(activity, "Beklenmedik hata: " + e.getMessage(), Toast.LENGTH_SHORT).show();
activity.finish();
}
}
#Override
public void onDetach() {
try {
closeRenderer();
} catch (IOException e) {
e.printStackTrace();
}
super.onDetach();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mGuncelSayfa) {
outState.putInt(O_ANKI_SAYFA_DURUMU, mGuncelSayfa.getIndex());
}
}
private void openRenderer(Context context) throws IOException
{
// bu ornekte, asset klasöründeki PDF'i okuyoruz.
FILENAME= getArguments().getString("file_name");
File file = new File(context.getCacheDir(), FILENAME);
if (!file.exists())
{
InputStream asset = context.getAssets().open(FILENAME);
FileOutputStream output = new FileOutputStream(file);
final byte[] buffer = new byte[1024];
int size;
while ((size = asset.read(buffer)) != -1) {
output.write(buffer, 0, size);
}
asset.close();
output.close();
}
mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
mPdfRenderer = new PdfRenderer(mFileDescriptor);
}
private void closeRenderer() throws IOException {
if (null != mGuncelSayfa) {
mGuncelSayfa.close();
}
mPdfRenderer.close();
mFileDescriptor.close();
}
private void showPage(int index) {
if (mPdfRenderer.getPageCount() <= index) {
return;
}
if (null != mGuncelSayfa) {
mGuncelSayfa.close();
}
mGuncelSayfa = mPdfRenderer.openPage(index);
// ÖNEMLİ: Hedef bitmap ARGB olmalı, RGB olmamalı.
Bitmap bitmap = Bitmap.createBitmap(mGuncelSayfa.getWidth(), mGuncelSayfa.getHeight(),
Bitmap.Config.ARGB_8888);
mGuncelSayfa.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
mImageView.setImageBitmap(bitmap);
sayfayıGuncelle();
}
private void sayfayıGuncelle() {
int index = mGuncelSayfa.getIndex();
int pageCount = mPdfRenderer.getPageCount();
mOncekiButon.setEnabled(0 != index);
mSonrakiButon.setEnabled(index + 1 < pageCount);
getActivity().setTitle(getString(R.string.app_name_with_index, index + 1, pageCount));
}
public int sayfaSayisiniGetir()
{
return mPdfRenderer.getPageCount();
}
You are setting the argument on the Fragment but calling the Activity
#Override
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putString("file_name", "sample3.pdf");
PdfRendererBasicFragment ff=new PdfRendererBasicFragment();
ff.setArguments(bundle);
startActivity(new Intent(IpuclariSayfasi.this,TrafficActivity.class));
}
And when you really commit the Fragment, you creating a new instance, without any argument:
if (savedInstanceState == null)
{
getFragmentManager().beginTransaction()
.add(R.id.container, new PdfRendererBasicFragment(), FRAGMENT_PDF_RENDERER_BASIC)
.commit();
}
Make the first implementation on the real Fragment call, like this:
if (savedInstanceState == null) {
Bundle bundle = new Bundle();
bundle.putString("file_name", "sample3.pdf");
PdfRendererBasicFragment ff=new PdfRendererBasicFragment();
ff.setArguments(bundle);
getFragmentManager().beginTransaction()
.add(R.id.container, ff, FRAGMENT_PDF_RENDERER_BASIC)
.commit();
}
You have the problem here
FILENAME= getArguments().getString("file_name");
getArguments() is null since you are setting arguments for
PdfRendererBasicFragment ff=new PdfRendererBasicFragment();
ff.setArguments(bundle);
but then you're creating a new Fragment in TrafficActivity.class
.add(R.id.container, new PdfRendererBasicFragment(), FRAGMENT_PDF_RENDERER_BASIC)
and this is the one you're using, but this one does not have any arguments in it
I am trying to implement callback between AsyncTask and Fragment but cannot find correct info how to do it. The issue is that all callback implementations are between activity and asynctask but I need between fragment and asynctask. Could someone give me small working example how to implement it without activity.
My action structure: Fragment call DialogFragment -> choose something and send server request to async task -> async task process everything and update view and some variables. My main problem is that I call prepareData() only once in onCreate and when I walk between other fragment and returns come back I see old data. That is to say there is not enough to update only view in onPost of asynctask. It will be good to have callback which will update the whole variables.
public class TermsAndConditionsFragment extends SherlockFragment implements OnClickListener, OnTouchListener, OnItemClickListener, onTaskListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fm = getSherlockActivity().getSupportFragmentManager();
prepareData();
}
public void prepareData() {
termsAndConditionsM = new TermsAndConditionsManager(getSherlockActivity());
termsAndConditions = termsAndConditionsM.getTermsAndConditions();
if (termsAndConditions != null) {
int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
if (totalPayments > 0) {
paymentsData = termsAndConditionsM.getpayments();
if (paymentsData != null) {
payments = new ArrayList<Payment>();
for (int i = 1; i <= totalPayments; i++) {
paymentValues = new Payment();
paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i)));
paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i));
paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i));
payments.add(paymentValues);
}
}
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = init(inflater, container);
if (payments != null || termsAndConditions != null)
updateTermsAndConditionsView();
return rootView;
}
private View init(LayoutInflater inflater, ViewGroup container) {
rootView = inflater.inflate(R.layout.fragment_terms_and_conditions, container, false);
...
return rootView;
}
public void updateTermsAndConditionsView() {
etHowMuch.setText("£" + termsAndConditions.get(ServerAPI.AMOUNT_OF_CREDIT));
etForHowLong.setText(Helpers.ConvertDays2Date(Integer.valueOf(termsAndConditions.get(ServerAPI.TERM_OF_AGREEMENT_IN_DAYS))));
PaymentAdapter adapter = new PaymentAdapter(getSherlockActivity(), R.layout.custom_loan_item, payments);
lvPayments.setAdapter(adapter);
tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE));
tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE));
}
#Override
public void onClick(View v) {
ft = fm.beginTransaction();
howMuch = etHowMuch.getText().toString();
forHowLong = etForHowLong.getText().toString();
switch (v.getId()) {
case R.id.etHowMuch:
f = new NumberPaymentsPickerFragment();
args = new Bundle();
args.putInt(Const.HOW_MUCH, Integer.valueOf(howMuch.replace("£", "")));
args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP);
args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS);
f.setArguments(args);
f.setTargetFragment(this, DIALOG_FRAGMENT);
f.show(getActivity().getSupportFragmentManager(), Const.HOW_MUCH);
break;
case R.id.etForHowLong:
f = new NumberPaymentsPickerFragment();
args = new Bundle();
args.putInt(Const.FOR_HOW_LONG, Integer.valueOf(Helpers.ConvertDate2Days(forHowLong)));
args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP);
args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS);
f.setArguments(args);
f.setTargetFragment(this, DIALOG_FRAGMENT);
f.show(getActivity().getSupportFragmentManager(), Const.FOR_HOW_LONG);
break;
case R.id.tvPersonalDetails:
sfm.saveCurFragment(ServerAPI.PERSONAL_DETAILS, 0);
ft.replace(android.R.id.content, new PersonalDetailsFragment(), ServerAPI.PERSONAL_DETAILS).addToBackStack(null).commit();
break;
case R.id.tvAgreementDetails:
sfm.saveCurFragment(ServerAPI.AGREEMENT_DETAILS, 0);
ft.replace(android.R.id.content, new AgreementDetailsFragment(), ServerAPI.AGREEMENT_DETAILS).addToBackStack(null).commit();
break;
case R.id.bApply:
break;
}
#Override
public void onUpdateData() {
Log.d(TAG, "Update data");
}
}
DialogFragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
...
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
return createDialog(v, R.string.for_how_long, etHowMuch, etForHowLong, etPromotionCode);
}
return null;
}
private Dialog createDialog(View view, int titleResID, final EditText howMuchField, final EditText forHowLongField, final EditText promotionCodeField) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(titleResID);
builder.setView(view);
builder.setPositiveButton(R.string.set, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
doShowProgress();
}
private void doShowProgress() {
ExecuteServerTaskBackground task = new
ExecuteServerTaskBackground(getActivity());
task.action = ServerAPI.GET_TERMS_AND_CONDITIONS;
onTaskListener listener = new onTaskListener() {
#Override
public void onUpdateData() {
Log.d(TAG, "Updaaate");
}
};
task.setListener(listener);
task.args = args;
task.execute();
}
}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
return builder.create();
}
AsyncTask:
onTaskListener mListener;
public interface onTaskListener {
void onUpdateData();
}
public void setListener(onTaskListener listener){
mListener = listener;
}
public ExecuteServerTaskBackground(Activity activity) {
this.mActivity = activity;
this.mContext = activity.getApplicationContext();
}
#Override
protected void onPreExecute() {
pb = (ProgressBar) mActivity.findViewById(R.id.progressBar1);
pb.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(Void... params) {
ServerAPI server = new ServerAPI(mContext);
if (!args.isEmpty())
server.serverRequest(action, args);
else
server.serverRequest(action, null);
return null;
}
#Override
protected void onPostExecute(Void result) {
mListener.onUpdateData();
//There is I just update view but how to update whole variables throughtout callback?
// tvNoOfPayments = (TextView) mActivity.findViewById(R.id.tvNoOfPaymentsValue);
// tvFirstPayment = (TextView) mActivity.findViewById(R.id.tvFirstPaymentValue);
// tvTotalRepayable = (TextView) mActivity.findViewById(R.id.tvTotalRepayableValue);
//
// lvPayments = (ListView) mActivity.findViewById(R.id.lvData);
//
// termsConditionsM = new TermsAndConditionsManager(mContext);
//
// termsAndConditions = termsConditionsM.getTermsAndConditions();
//
// int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
//
// if (totalPayments > 0) {
// if (termsAndConditions != null) {
// tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
// tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE));
// tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE));
// }
//
// paymentsData = termsConditionsM.getpayments();
//
// if (paymentsData != null) {
// Log.d(TAG, paymentsData.toString());
//
// payments = new ArrayList<Payment>();
//
// for (int i = 1; i <= totalPayments; i++) {
// paymentValues = new Payment();
// paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i)));
// paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i));
// paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i));
// payments.add(paymentValues);
// }
//
// PaymentAdapter adapter = new PaymentAdapter(mContext, R.layout.custom_loan_item, payments);
// lvPayments.setAdapter(adapter);
// }
//
}
pb.setVisibility(View.GONE);
super.onPostExecute(result);
}
Without taking your code in consideration I will post the most essential to make a functional callback.
TestFragment:
public class TestFragment extends Fragment {
/* Skipping most code and I will only show you the most essential. */
private void methodThatStartsTheAsyncTask() {
TestAsyncTask testAsyncTask = new TestAsyncTask(new FragmentCallback() {
#Override
public void onTaskDone() {
methodThatDoesSomethingWhenTaskIsDone();
}
});
testAsyncTask.execute();
}
private void methodThatDoesSomethingWhenTaskIsDone() {
/* Magic! */
}
public interface FragmentCallback {
public void onTaskDone();
}
}
TestAsyncTask:
public class TestAsyncTask extends AsyncTask<Void, Void, Void> {
private FragmentCallback mFragmentCallback;
public TestAsyncTask(FragmentCallback fragmentCallback) {
mFragmentCallback = fragmentCallback;
}
#Override
protected Void doInBackground(Void... params) {
/* Do your thing. */
return null;
}
#Override
protected void onPostExecute(Void result) {
mFragmentCallback.onTaskDone();
}
}
I am using XWalkView to show a mobile web site as an application. My problem is when application goes background and comes back it reloads the page it shows. I want to keep it state and continue from that state when it comes from background. Here is my code:
public class MainActivity extends AppCompatActivity {
static final String URL = "https://www.biletdukkani.com.tr";
static final int MY_PERMISSIONS_REQUEST_ACCESS_LOCATION = 55;
static final String SHOULD_ASK_FOR_LOCATION_PERMISSION = "shouldAskForLocationPermission";
static final String TAG = "MainActivity";
static final String COMMAND = "/system/bin/ping -c 1 185.22.184.184";
static XWalkView xWalkWebView;
TextView noInternet;
static Bundle stateBundle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
stateBundle = savedInstanceState.getBundle("xwalk");
}
setContentView(R.layout.activity_main);
initNoInternetTextView();
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
stateBundle = savedInstanceState.getBundle("xwalk");
Log.d(TAG, "onRestoreInstanceState");
}
/**
* İnternet yok mesajı gösteren TextVidew'i ayarlar.
*/
private void initNoInternetTextView() {
Log.d(TAG, "initNoInternetTextView");
noInternet = (TextView) findViewById(R.id.no_internet);
if (noInternet != null) {
noInternet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
checkInternetConnection();
}
});
}
}
/**
* WebView'i ayarlar.
*/
private void initWebView() {
Log.d(TAG, "initWebView");
if (xWalkWebView == null) {
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
xWalkWebView = (XWalkView) findViewById(R.id.webView);
//xWalkWebView.clearCache(true);
xWalkWebView.load(URL, null);
xWalkWebView.setResourceClient(new BDResourceClient(xWalkWebView, progressBar));
}
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
checkLocationPermissions();
checkInternetConnection();
if (xWalkWebView != null && stateBundle != null) {
xWalkWebView.restoreState(stateBundle);
}
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
if (xWalkWebView != null) {
stateBundle = new Bundle();
xWalkWebView.saveState(stateBundle);
}
}
public void onSaveInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onSaveInstanceState");
// Save the user's current game state
savedInstanceState.putBundle("xwalk", stateBundle);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onBackPressed() {
Log.d(TAG, "onBackPressed");
if (xWalkWebView != null && xWalkWebView.getNavigationHistory().canGoBack()) {
xWalkWebView.getNavigationHistory().navigate(XWalkNavigationHistory.Direction.BACKWARD, 1);
} else {
super.onBackPressed();
}
}
}
I have also tried to add following lines to manifest but didn't work.
android:launchMode="singleTask"
android:alwaysRetainTaskState="true"
How can i do that?
Thanks in advcance.
One way would be to initialize the view inside a fragment which is set to retain it's instance.
I am trying to implement callback between AsyncTask and Fragment but cannot find correct info how to do it. The issue is that all callback implementations are between activity and asynctask but I need between fragment and asynctask. Could someone give me small working example how to implement it without activity.
My action structure: Fragment call DialogFragment -> choose something and send server request to async task -> async task process everything and update view and some variables. My main problem is that I call prepareData() only once in onCreate and when I walk between other fragment and returns come back I see old data. That is to say there is not enough to update only view in onPost of asynctask. It will be good to have callback which will update the whole variables.
public class TermsAndConditionsFragment extends SherlockFragment implements OnClickListener, OnTouchListener, OnItemClickListener, onTaskListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fm = getSherlockActivity().getSupportFragmentManager();
prepareData();
}
public void prepareData() {
termsAndConditionsM = new TermsAndConditionsManager(getSherlockActivity());
termsAndConditions = termsAndConditionsM.getTermsAndConditions();
if (termsAndConditions != null) {
int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
if (totalPayments > 0) {
paymentsData = termsAndConditionsM.getpayments();
if (paymentsData != null) {
payments = new ArrayList<Payment>();
for (int i = 1; i <= totalPayments; i++) {
paymentValues = new Payment();
paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i)));
paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i));
paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i));
payments.add(paymentValues);
}
}
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = init(inflater, container);
if (payments != null || termsAndConditions != null)
updateTermsAndConditionsView();
return rootView;
}
private View init(LayoutInflater inflater, ViewGroup container) {
rootView = inflater.inflate(R.layout.fragment_terms_and_conditions, container, false);
...
return rootView;
}
public void updateTermsAndConditionsView() {
etHowMuch.setText("£" + termsAndConditions.get(ServerAPI.AMOUNT_OF_CREDIT));
etForHowLong.setText(Helpers.ConvertDays2Date(Integer.valueOf(termsAndConditions.get(ServerAPI.TERM_OF_AGREEMENT_IN_DAYS))));
PaymentAdapter adapter = new PaymentAdapter(getSherlockActivity(), R.layout.custom_loan_item, payments);
lvPayments.setAdapter(adapter);
tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE));
tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE));
}
#Override
public void onClick(View v) {
ft = fm.beginTransaction();
howMuch = etHowMuch.getText().toString();
forHowLong = etForHowLong.getText().toString();
switch (v.getId()) {
case R.id.etHowMuch:
f = new NumberPaymentsPickerFragment();
args = new Bundle();
args.putInt(Const.HOW_MUCH, Integer.valueOf(howMuch.replace("£", "")));
args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP);
args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS);
f.setArguments(args);
f.setTargetFragment(this, DIALOG_FRAGMENT);
f.show(getActivity().getSupportFragmentManager(), Const.HOW_MUCH);
break;
case R.id.etForHowLong:
f = new NumberPaymentsPickerFragment();
args = new Bundle();
args.putInt(Const.FOR_HOW_LONG, Integer.valueOf(Helpers.ConvertDate2Days(forHowLong)));
args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP);
args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS);
f.setArguments(args);
f.setTargetFragment(this, DIALOG_FRAGMENT);
f.show(getActivity().getSupportFragmentManager(), Const.FOR_HOW_LONG);
break;
case R.id.tvPersonalDetails:
sfm.saveCurFragment(ServerAPI.PERSONAL_DETAILS, 0);
ft.replace(android.R.id.content, new PersonalDetailsFragment(), ServerAPI.PERSONAL_DETAILS).addToBackStack(null).commit();
break;
case R.id.tvAgreementDetails:
sfm.saveCurFragment(ServerAPI.AGREEMENT_DETAILS, 0);
ft.replace(android.R.id.content, new AgreementDetailsFragment(), ServerAPI.AGREEMENT_DETAILS).addToBackStack(null).commit();
break;
case R.id.bApply:
break;
}
#Override
public void onUpdateData() {
Log.d(TAG, "Update data");
}
}
DialogFragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
...
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
return createDialog(v, R.string.for_how_long, etHowMuch, etForHowLong, etPromotionCode);
}
return null;
}
private Dialog createDialog(View view, int titleResID, final EditText howMuchField, final EditText forHowLongField, final EditText promotionCodeField) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(titleResID);
builder.setView(view);
builder.setPositiveButton(R.string.set, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
doShowProgress();
}
private void doShowProgress() {
ExecuteServerTaskBackground task = new
ExecuteServerTaskBackground(getActivity());
task.action = ServerAPI.GET_TERMS_AND_CONDITIONS;
onTaskListener listener = new onTaskListener() {
#Override
public void onUpdateData() {
Log.d(TAG, "Updaaate");
}
};
task.setListener(listener);
task.args = args;
task.execute();
}
}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
return builder.create();
}
AsyncTask:
onTaskListener mListener;
public interface onTaskListener {
void onUpdateData();
}
public void setListener(onTaskListener listener){
mListener = listener;
}
public ExecuteServerTaskBackground(Activity activity) {
this.mActivity = activity;
this.mContext = activity.getApplicationContext();
}
#Override
protected void onPreExecute() {
pb = (ProgressBar) mActivity.findViewById(R.id.progressBar1);
pb.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(Void... params) {
ServerAPI server = new ServerAPI(mContext);
if (!args.isEmpty())
server.serverRequest(action, args);
else
server.serverRequest(action, null);
return null;
}
#Override
protected void onPostExecute(Void result) {
mListener.onUpdateData();
//There is I just update view but how to update whole variables throughtout callback?
// tvNoOfPayments = (TextView) mActivity.findViewById(R.id.tvNoOfPaymentsValue);
// tvFirstPayment = (TextView) mActivity.findViewById(R.id.tvFirstPaymentValue);
// tvTotalRepayable = (TextView) mActivity.findViewById(R.id.tvTotalRepayableValue);
//
// lvPayments = (ListView) mActivity.findViewById(R.id.lvData);
//
// termsConditionsM = new TermsAndConditionsManager(mContext);
//
// termsAndConditions = termsConditionsM.getTermsAndConditions();
//
// int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
//
// if (totalPayments > 0) {
// if (termsAndConditions != null) {
// tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS));
// tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE));
// tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE));
// }
//
// paymentsData = termsConditionsM.getpayments();
//
// if (paymentsData != null) {
// Log.d(TAG, paymentsData.toString());
//
// payments = new ArrayList<Payment>();
//
// for (int i = 1; i <= totalPayments; i++) {
// paymentValues = new Payment();
// paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i)));
// paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i));
// paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i));
// payments.add(paymentValues);
// }
//
// PaymentAdapter adapter = new PaymentAdapter(mContext, R.layout.custom_loan_item, payments);
// lvPayments.setAdapter(adapter);
// }
//
}
pb.setVisibility(View.GONE);
super.onPostExecute(result);
}
Without taking your code in consideration I will post the most essential to make a functional callback.
TestFragment:
public class TestFragment extends Fragment {
/* Skipping most code and I will only show you the most essential. */
private void methodThatStartsTheAsyncTask() {
TestAsyncTask testAsyncTask = new TestAsyncTask(new FragmentCallback() {
#Override
public void onTaskDone() {
methodThatDoesSomethingWhenTaskIsDone();
}
});
testAsyncTask.execute();
}
private void methodThatDoesSomethingWhenTaskIsDone() {
/* Magic! */
}
public interface FragmentCallback {
public void onTaskDone();
}
}
TestAsyncTask:
public class TestAsyncTask extends AsyncTask<Void, Void, Void> {
private FragmentCallback mFragmentCallback;
public TestAsyncTask(FragmentCallback fragmentCallback) {
mFragmentCallback = fragmentCallback;
}
#Override
protected Void doInBackground(Void... params) {
/* Do your thing. */
return null;
}
#Override
protected void onPostExecute(Void result) {
mFragmentCallback.onTaskDone();
}
}