how get image from gallery in fragment(jetpack navigation component) - android

I use Navigation component jetpak and in fragment need to get image from gallery.
i use this code:
ActivityResultLauncher<String> mGetContent = registerForActivityResult(new ActivityResultContracts.GetContent(),
new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(Uri uri) {
Constants.toast("return!");
imageFile = new File(getRealPathFromURI(uri));
binding.menuFragmentCircularProfileImageview.setImageURI(uri);
}
});
and after fragment attached call mGetContent
binding.menuFragmentCircularProfileImageview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mGetContent.launch("image/*");
// fromGallery();
}
});
So far everything is fine and the gallery opens well.
BUT...
But the selected image does not return.
The app is actually closed.
Where did I do wrong? Or is there another solution?
UPDATED...
this is my fragment:
public class MenuFragment extends Fragment implements LogoutDialog.Listener {
private FragmentMenuBinding binding;
private NavController navController = null;
private UserData userData;
private File imageFile;
private final androidx.activity.result.ActivityResultLauncher<String> getContent = registerForActivityResult(new ActivityResultContracts.GetContent(),
new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(requireActivity().getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
binding.menuFragmentCircularProfileImageview.setImageBitmap(bitmap);
}
});
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
navController = Navigation.findNavController(requireActivity(), R.id.main_activity_nav_host_fragment);
binding = DataBindingUtil.inflate(inflater , R.layout.fragment_menu, container, false);
return binding.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
assert getArguments() != null;
userData=MenuFragmentArgs.fromBundle(getArguments()).getUserdata();
operation();
}
private void operation(){
binding.menuFragmentCircularProfileImageview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getContent.launch("image/*");
}
});
}
}

Try using below code:
private ActivityResultLauncher startForResultFromGallery = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK){
try {
if (result.getData() != null){
Uri selectedImageUri = result.getData().getData();
Bitmap bitmap = BitmapFactory.decodeStream(getBaseContext().getContentResolver().openInputStream(selectedImageUri));
// set bitmap to image view here........
binding.menuFragmentCircularProfileImageview.setImageBitmap(bitmap)
}
}catch (Exception exception){
Log.d("TAG",""+exception.getLocalizedMessage());
}
}
}
});
And call above inside your button click like :
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startForResultFromGallery.launch(intent);

You can use this inside your onActivityResult to get the file
InputStream inputStream = requireActivity().contentResolver().openInputStream(uri)
String fileType = MimeTypeMap.getSingleton().getExtensionFromMimeType(requireContext().contentResolver().getType(uri))
imageFile = File.createTempFile(UUID.randomUUID().toString(), "." + fileType)
inputStream.copyStreamToFile(file)
I have ported this code from Kotlin let me know if some syntax is wrong.

I believe you have android:noHistory="true" in your AndroidManifest.xml, please remove it, and you should receive the result. I believe the problem has no relation with Jetpack navigation.

Related

How to startActivity() in fragment when activating other activity or fragment?

In fragment'A' when a certain condition is established, it should go to 'ChatActivity'.
Intent intent = new Intent(getContext(), ChatActivity.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("uid", matchedUid);
startActivity(intent);
The problem is when other fragment or Activity is showing on the top, the condition is established so startActivity is not executed.. occur an error
'java.lang.String android.content.Context.getPackageName()' on a null object reference
below is entire code
public class MatchFragment extends Fragment implements MatchMVP.View {
private static final String TAG = "MatchFragment";
private MatchPresenter matchPresenter;
private ToggleButton randomMatchBtn;
private ProgressBar progressBar, progressCircle;
private TextView searchingText;
private AdView adView;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v;
setupMVP();
if(matchPresenter.checkOnlineStatus(getContext())) {
v = inflater.inflate(R.layout.fragment_match, container, false);
setupView(v);
matchPresenter.isSearching();
initAd(v);
} else {
v = inflater.inflate(R.layout.fragment_offline, container, false);
}
return v;
}
private void setupMVP() {
matchPresenter = new MatchPresenter(this);
}
private void setupView(View v) {
progressBar = v.findViewById(R.id.progressbar);
progressCircle = v.findViewById(R.id.progressbar_circle);
searchingText = v.findViewById(R.id.searching_text);
progressBar.setVisibility(View.INVISIBLE);
progressCircle.setVisibility(View.INVISIBLE);
searchingText.setVisibility(View.INVISIBLE);
randomMatchBtn = v.findViewById(R.id.random_match_btn);
randomMatchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(matchPresenter.checkOnlineStatus(getContext())) {
if(randomMatchBtn.isChecked()) {
matchPresenter.searchRandomUser();
progressBar.setVisibility(View.VISIBLE);
} else {
matchPresenter.stopMatch();
progressBar.setVisibility(View.VISIBLE);
}
} else {
showSnackBar("error");
}
}
});
}
private void initAd(View v) {
MobileAds.initialize(getActivity(), "ca-app-pub-6263138384822549~5566878684");
adView = v.findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
}
#Override
public void createChatRoom(String matchedUid) {
Intent intent = new Intent(getContext(), ChatActivity.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("uid", matchedUid);
startActivity(intent);
Vibrator vibrator;
if(getContext() != null) {
vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(700);
}
}
#Override
public void showSnackBar(String msg) {
Snackbar snackbar = Snackbar.make(getActivity().findViewById(android.R.id.content), msg, 2500);
View snackBarLayout = snackbar.getView();
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
// Layout must match parent layout type
lp.setMargins(0, 300, 0, 0);
// Margins relative to the parent view.
snackBarLayout.setLayoutParams(lp);
snackbar.show();
}
#Override
public void randomMatchBtnOff() {
randomMatchBtn.setChecked(false);
}
#Override
public void randomMatchBtnDisable() {
randomMatchBtn.setEnabled(false);
}
#Override
public void randomMatchBtnEnable() {
randomMatchBtn.setEnabled(true);
progressBar.setVisibility(View.INVISIBLE);
}
#Override
public void showProgressCircle() {
progressCircle.setVisibility(View.VISIBLE);
searchingText.setVisibility(View.VISIBLE);
}
#Override
public void hideProgressCircle() {
progressCircle.setVisibility(View.INVISIBLE);
searchingText.setVisibility(View.INVISIBLE);
}
#Override
public void goAuthActivity() {
Intent intent = new Intent(getContext(), AuthActivity.class);
intent.putExtra("isSanctioned", true);
startActivity(intent);
assert getActivity() != null;
getActivity().finish();
}
#Override
public void onResume() {
super.onResume();
matchPresenter.checkIsSan();
}
#Override
public void onPause() {
super.onPause();
if(isThreadRunning) {
timeCheckThread.interrupt();
}
}
}
Cause of error is 'Fragment is not attached to its Activity'. Yeah I know. I'm making a randomChatting app with firebase. In this MatchFragment, I'm searching other users. When other users start searching, matched with me then let me know by go to 'ChatActivity'.
But if I'm in other fragment of activity, searching is activating, it can't go ChatActivity. 'Fragment is not attached to its Activity'.
Because I'm in other activity not in this MatchFragment. MatchFragment detached to its Activity.
How go to ChatActivity even if I'm in other activity.
You can either try using requireActivity() instead of getActivity() but since you only need a Context object and not necessarily an Activity object, I suggest you replace getActivity() with requireContext().
If that doesn't work out then you can try following this answer: https://stackoverflow.com/a/30498143
PS: I know this should be shared as a comment but my reputation is currently only 41 and I can't post a comment so writing this as an answer.

Save the state of a Circleimageview inside a fragment

I have fragments with a circleimageview inside used as a profile image that is saved later in a database correctly.
My problem is to save the state of the imageview with onSaveInstanceState and onPause/onStop to keep their state before saving them in the database and after, for example, performing a screen rotation.
This is my code
public class MyFragment extends Fragment implements View.OnClickListener {
private CircleImageView mPhoto;
private byte[] bytes = null;
private Bitmap photo = null;
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if(bytes!=null) {
outState.putByteArray("bytes", bytes);
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
view = lf.inflate(R.layout.my_fragment,container,false);
mPhoto = (CircleImageView) view.findViewById(R.id.photo);
view.findViewById(R.id.photo).setOnClickListener(this);
if(savedInstanceState!=null){
if(savedInstanceState.containsKey("bytes")){
bytes = savedInstanceState.getByteArray("bytes");
if(bytes != null) {
//but with a screen rotation the image is not restored
photo = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
mPhoto.setImageBitmap(photo);
}
}
}
return view;
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.photo:
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
try {
startActivityForResult(Intent.createChooser(i, "Select Picture"), 0);
}catch (ActivityNotFoundException ex){
ex.printStackTrace();
}
break;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==0 && resultCode == Activity.RESULT_OK) {
Uri path = data.getData();
Bitmap tmp = null;
try {
tmp = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), path);
} catch (IOException e) {
e.printStackTrace();
}
if(tmp != null) {
mPhoto.setImageBitmap(photo);
bytes = getBitmapAsByteArray(photo);
//tested, bytes is not null and the photo are restored correctly when saved on the database
}
}
}
#Override
public void onResume() {
super.onResume();
bytes = getActivity().getIntent().getByteArrayExtra("bytes");
if(bytes != null) {
//here bytes is null
photo = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
mPhoto.setImageBitmap(photo);
}
}
#Override
public void onStop() {
super.onStop();
if(bytes!=null)
getActivity().getIntent().putExtra("bytes",bytes);
}
}
in this way the image is not maintained during a screen rotation, how to correctly implement onsavedInstanceState, onStop and onResume?
Put code before super() method.
#Override
public void onStop() {
if(bytes!=null)
getActivity().getIntent().putExtra("bytes",bytes);
super.onStop();
}
Easiest way Use ViewModel with your fragment.
Refer: https://developer.android.com/topic/libraries/architecture/viewmodel.html
Update:
Step1: Add View Model dependency in build.gradle
def lifecycle_version = "2.0.0"
implementation "androidx.lifecycle:lifecycle viewmodel:$lifecycle_version"
Step 2: Create a ViewModel for Fragment
public class MyFragmentViewModel extends ViewModel {
}
Step 3: Set ViewModel in MyFragment
public class MyFragment extends Fragment {
public void onStart() {
MyFragmentViewModel userModel = ViewModelProviders.of(getActivity()).get(MyFragmentViewModel.class);
}
}

Restore listener after Activity recreate (pass photo to a custom view returning from camera)

I have an activity with a fragment. Inside a fragment I have 2 custom views. A custom view contains an ImageView and a listener. Listener can transform, show a photo in ImageView and upload the photo.
I want to take a photo from camera, return it to the fragment, pass to a view through listener (then show and upload inside the view). Everything works right until the activity is destroyed after camera becomes visible. So, after returning from camera, I restore the fragment, get photo in onActivityResult and try to pass to a view by listener. But a listener is null, and i don't know what view it is attached to.
How can I pass a photo to a view after recreating an activity?
Listener:
public interface Listener {
void onPhotoObtained(#Nullable Uri uri);
}
Custom view:
public class CustomView extends RelativeLayout implements Listener {
#BindView(R.id.imageview) ImageView image;
private PhotoManager photoManager;
public void setPhotoManager(#NonNull PhotoManager photoManager) {
this.photoManager = photoManager;
}
#Override
public void onPhotoObtained(#Nullable Uri uri) {
// transform and show image
}
#OnClick(R.id.imageview)
void onPhotoButtonClicked() {
photoManager.requestPhoto(this);
}
}
Fragment:
public class MainFragment extends Fragment implements PhotoManager {
#BindView(R.id.view1) CustomView view1;
#BindView(R.id.view2) CustomView view2;
// A list of listeners to communicate with custom views.
// When a user clicks an ImageView, this fragment starts a camera to obtain a photo.
private SparseArray<Listener> listeners;
private int lastRequestId;
private Uri uri;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_main, container, false);
binder = ButterKnife.bind(this, view);
listeners = new SparseArray<>();
if (savedInstanceState == null) {
lastRequestId = 0;
uri = null;
} else {
lastRequestId = savedInstanceState.getInt(BUNDLE_REQUEST_ID);
uri = savedInstanceState.getParcelable(BUNDLE_KEY_URI);
// How to create a listener list?
}
view1.setPhotoManager(this);
view2.setPhotoManager(this);
return view;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ReceivingPhotoDialogFragment.CAMERA_REQUEST) {
if (resultCode == RESULT_OK) {
if (uri != null) {
// listeners become empty after fragment reinitialization
Listener listener = listeners.get(lastRequestId);
if (listener != null)
listener.onPhotoObtained(uri);
}
}
}
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
bundle.putInt(BUNDLE_REQUEST_ID, lastRequestId);
bundle.putParcelable(BUNDLE_KEY_URI, uri);
super.onSaveInstanceState(outState);
}
#Override
public void requestPhoto(#NonNull Listener listener) {
listeners.put(++lastRequestId, listener);
// Request new photo with lastRequestId
showCamera(lastRequestId);
}
private void showCamera(int requestId) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
File file = null;
try {
file = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
uri = null;
if (file != null) {
uri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra(BUNDLE_REQUEST_ID, requestId);
startActivityForResult(intent, CAMERA_REQUEST);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
return File.createTempFile(timeStamp, ".jpg", storageDir);
}
}
A second listener to initialize first:
public interface PhotoManager {
void requestPhoto(#NonNull Listener listener);
}
I still struggle with the activity lifecycle, so this may not be the best answer.
What I do is make my listener as a static variable. This allows the variable to exist in the class instead of the instance of the class which clears when destroyed.
I think, You do not need to re-initialise listener for that,
What you need is add a property named configChanges in your AndroidManifest.xml file for that activity which has this MainFragment
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"/>
Add these tag configChanges and then run your code.

get Data to Fragment from Activity

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

What causes a fragment to get detached from an Activity?

I have a SignupActivity which will go through several fragments as users go through a signup process. On the last fragment, I'm calling
getActivity().setResult(Activity.RESULT_OK)
since SingupActivity intent was started for result. Some users are crashing at this point, because getActivity() is producing a NPE. I'm not able to figure out what is causing this. Screen rotation is disabled, so there is no reason that I know of for the fragment to detach from the Activity.
Any insight as to what may be causing this, and how I can resolve it?
public class SignupConfirmationFragment extends Fragment {
public static final String TAG = SignupConfirmationFragment.class.getSimpleName();
private User mNewUser;
private myAppClient mmyAppClient;
private Animation rotateAnimation;
private ImageView avatar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNewUser = ((SignUpActivity) getActivity()).getNewUser();
mmyAppClient = ((SignUpActivity) getActivity()).getmyAppClient();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_signup_confirmation, null);
((TextView) v.findViewById(R.id.username_textView)).setText(((SignUpActivity) getActivity()).getNewUser().getName());
avatar = (ImageView) v.findViewById(R.id.avatar);
if (mNewUser.getAvatarImage() != null) {
avatar.setImageBitmap(mNewUser.getAvatarImage());
}
rotateAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.progress_rotate);
v.findViewById(R.id.progress_loading).startAnimation(rotateAnimation);
if (mNewUser.getAvatarImage() != null) {
startAvatarUpload();
} else if (mNewUser.getNewsletter()) {
setNewsletterStatus();
} else {
pauseForOneSecond();
}
return v;
}
private void startAvatarUpload() {
mmyAppClient.uploadUserAvatar(mNewUser.getAvatarImage(), new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
if (mNewUser.getNewsletter()) {
setNewsletterStatus();
} else {
updateFragment();
}
}
},
null,
null);
}
private void setNewsletterStatus() {
mmyAppClient.setNewsletter(mNewUser.getEmail(), mNewUser.getFirstName(), mNewUser.getLastName(), new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
//Log.d(TAG, "Result: " + result);
updateFragment();
}
});
}
private void pauseForOneSecond() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
updateFragment();
}
}, 1000);
}
private void updateFragment() {
rotateAnimation.cancel();
if (isAdded()) {
getActivity().setResult(Activity.RESULT_OK);
AnalyticsManager.logUIEvent("sign up completed");
getActivity().finish();
} else {
AnalyticsManager.logUIEvent("sign up failed");
}
}
}
According to Fragment lifecycle in Android OS, you cannot get the Activity associated with the fragment in the onCreateView, because the Activity with which the Fragment is associated will not be created at that stage.
See the figure below:
Also, refer to this link, http://developer.android.com/guide/components/fragments.html
As you can see the Activity is created in onActivityCreated which is after onCreateView, hence you'll get null if you try to call the Activity in the onCreateView. Try to call it in onActivityCreated or in onStart that should solve your problem.
I hope this helps.

Categories

Resources