OnRequestPermissionsResultCallback not triggering in PreferenceFragment - java

import android.preference.PreferenceFragment;
import android.support.v13.app.FragmentCompat;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
public class Preferences extends PreferenceFragment implements OnPreferenceClickListener, FragmentCompat.OnRequestPermissionsResultCallback {
if (ContextCompat.checkSelfPermission(activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity,
new String[]{ android.Manifest.permission.WRITE_EXTERNAL_STORAGE },
Constant.WRITE_STORAGE_PERMISSION);
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grants) { }
I'm trying to get the new permissions. The dialog shows up requesting the permission when it should, but onRequestPermissionResult it's never called, be it rejection or acceptance.
Any idea? The examples are all using Activity and not a Fragment, so that might be the problem. Also, I'm not sure which Compat I should be using (v4 vs v13). Min SDK is 14.

full code for you:
public interface PermissionResultListener {
public void onPermissionResult(int requestCode,
String permissions[], int[] grantResults);
}
public class Preferences extends PreferenceFragment implements Preference.OnPreferenceClickListener,
PermissionResultListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void requestPermission() {
Activity activity = getActivity();
if (activity != null && activity instanceof MainActivity) {
MainActivity mainActivity = (MainActivity) activity;
mainActivity.requestPermissionStorage();
mainActivity.setPermissionResultListener(this);
}
}
#Override
public boolean onPreferenceClick(Preference preference) {
return false;
}
#Override
public void onPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
// request permission result here
}
}
public class MainActivity extends AppCompatActivity {
private PermissionResultListener mPermissionResultListener;
public void setPermissionResultListener(PermissionResultListener mPermissionResultListener) {
this.mPermissionResultListener = mPermissionResultListener;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
Preferences preferences = new Preferences();
// In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
preferences.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, preferences).commit();
}
}
public void requestPermissionStorage() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
Constant.WRITE_STORAGE_PERMISSION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (mPermissionResultListener != null) {
mPermissionResultListener.onPermissionResult(requestCode, permissions, grantResults);
}
}
}

Related

How to detect other permission in mi phone in android studio?

#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = findViewById(R.id.btncheck);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
intent.putExtra("extra_pkgname", getPackageName());
startActivity(intent);
}
});
}
It code only navigate and display other permission screen but not working in require permission.
How to enable and disav other permission in mi phone in android studio
Image here
What kind of permissions do you need?
If I understand you correctly, this should help.
in MainActivity:
private final int REQUEST_CODE_PERMISSIONS = 1001;
private final String[] REQUIRED_PERMISSIONS = new String[]{
"android.permission.CAMERA",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.RECORD_AUDIO",
"android.permission.INTERNET",
"android.permission.WRITE_EXTERNAL_STORAGE"};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (!allPermissionsGranted()) {
createToast(getString(R.string.error_permission));
finish();
}
}
}
private boolean allPermissionsGranted(){
for(String permission : REQUIRED_PERMISSIONS){
if(ContextCompat.checkSelfPermission(this , permission)
!= PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
if(allPermissionsGranted()){
Log.d("TAG", "OK");
} else{
ActivityCompat.requestPermissions(this,
REQUIRED_PERMISSIONS,
REQUEST_CODE_PERMISSIONS);
}
...
}

registerForActivityResult with RequestPermission in Fragment not working

I'm changing old styled code for Activity Results, and got stuck on permission results. In fragment where users can pick one contact from a list and copy it's data, permission callback is not working at all, however activity result is firing callback... Here is simplified fragment class:
public class PeopleAddEdit_SubVen_Fragment extends Fragment {
private ActivityResultLauncher<Intent> mActivityResult;
private ActivityResultLauncher<String> mPermissionResult;
#Override
public View onCreateView(#NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_addedit_ppl_subven, container, false);
ImageView contacticon = view.findViewById(R.id.contacticon_container);
contacticon.setImageDrawable(AppLib.getAppDrawable(R.drawable.icons_88));
contacticon.setOnClickListener(view1 -> processContact());
return view;
}
#Override
public void onAttach(#NotNull Context context) {
super.onAttach(context);
AppCompatActivity activity = (AppCompatActivity) context;
mActivityResult = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
//processing data here
...
}
}
});
mPermissionResult = registerForActivityResult(
new ActivityResultContracts.RequestPermission(),
new ActivityResultCallback<Boolean>() {
#Override
public void onActivityResult(Boolean result) {
if (result) {
PeopleAddEdit_SubVen_Fragment.this.startProcessingContacts();
} else {
Toast.makeText(PeopleAddEdit_SubVen_Fragment.this.getActivity(), "No permission.", Toast.LENGTH_SHORT).show();
}
}
});
}
private void processContact() {
int getContacts = ContextCompat.checkSelfPermission(thisContext, Manifest.permission.READ_CONTACTS);
if (getContacts != PackageManager.PERMISSION_GRANTED) {
mPermissionResult.launch(Manifest.permission.READ_CONTACTS);
} else {
startProcessingContacts();
}
}
private void startProcessingContacts() {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
mActivityResult.launch(intent);
}
}
When Contacts are not granted, after displaying popup to deny or allow Contacts, nothing happens regardless of choice. If I click button again (after I allow Contacts), I get contacts displayed, so activity result is firing callback, but permission callback is not fired at all, but permission is granting or denying, depending on choice, but not firing result.
In the build.gradle ​I have
implementation 'androidx.activity:activity:1.4.0'
implementation 'androidx.fragment:fragment:1.4.0-rc01'
Any ideas why is not firing?
Problem solved. I just needed to remove from parent activity
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
...
}
and it works now.

Clicking on an image in RecycleView

I am really new to AndroidStudio and I'm trying to make a sharing app. My purpose is to have an app that automatically loads up all the images on my phone(or in my phone's gallery, not that important) and display them on screen. Afterwards, I want to click on one of the images over there, and then use a Share button I made to send that photo to another person (it can be an MMS or any other application, the main problem is that this share button transmit the picture I clicked on most recently).
I don't know a lot about the specifics of Android Studio, meaning I know how to code (sort of) but I am unfamiliar with the possibilities of implementing this. My code is below.
GalleryAdapter.java:
public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.ViewHolder> {
private Context context;
private List<String> images;
protected PhotoListener photoListener;
public GalleryAdapter(Context context, List<String> images, PhotoListener photoListener) {
this.context = context;
this.images = images;
this.photoListener = photoListener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(
LayoutInflater.from(context).inflate(R.layout.gallery_item, parent, false)
);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
String image=images.get(position);
Glide.with(context).load(image).into(holder.image);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
photoListener.onPhotoClick(image);
}
});
}
#Override
public int getItemCount() {
return images.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
public ViewHolder(#NonNull View itemView) {
super(itemView);
image=itemView.findViewById(R.id.image);
}
}
public interface PhotoListener{
void onPhotoClick(String path);
}
}
ImagesGallery.java:
public class ImagesGallery {
public static ArrayList<String> listofImages(Context context){
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
ArrayList<String> listofAllImages=new ArrayList<>();
String absolutePathOfImage;
uri= MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection={MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
String orderBy= MediaStore.Video.Media.DATE_TAKEN;
cursor=context.getContentResolver().query(uri, projection, null, null, orderBy+" DESC");
column_index_data=cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
while(cursor.moveToNext()){
absolutePathOfImage=cursor.getString(column_index_data);
listofAllImages.add(absolutePathOfImage);
}
return listofAllImages;
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
GalleryAdapter galleryAdapter;
List<String> images;
TextView gallery_number;
private static final int MY_READ_PERMISSION_CODE=101;
#Override
protected void onCreate(Bundle savedInstanceState) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 101);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gallery_number=findViewById(R.id.gallery_number);
recyclerView=findViewById(R.id.recyclerview_gallery_images);
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_READ_PERMISSION_CODE);
} else {
loadImages();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if(item.getItemId()==R.id.share_menu){
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
Uri uriToImage=Uri.parse("android.resource://com.example.tutorialpaper5/"+R.drawable.test);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.app_name)));
} else{
return super.onOptionsItemSelected(item);
}
return true;
}
private void loadImages(){
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
images=ImagesGallery.listofImages(this);
galleryAdapter=new GalleryAdapter(this, images, new GalleryAdapter.PhotoListener() {
#Override
public void onPhotoClick(String path) {
Toast.makeText(MainActivity.this, ""+path, Toast.LENGTH_LONG).show();
}
});
recyclerView.setAdapter(galleryAdapter);
gallery_number.setText("Photos +("+images.size()+")");
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==MY_READ_PERMISSION_CODE){
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "read external storage permission granted", Toast.LENGTH_LONG).show();
loadImages();
} else {
Toast.makeText(this, "Read external storage permission denied", Toast.LENGTH_LONG).show();
}
}
}
}
You will notice that in my onOptionsItemSelected class I just threw in a picture I had in the drawable directory to see if the share button actually works. It does, now I just need some way for it memorize my last clicked photo and throw it in that Intent. But again, I am not sure if that is possible.
There are multiple options, here are two simple solutions just to link your code parts.
Suggestion with minimal changes in your logic:
You can just save the onPhotoClick(String path) to a field that will defined in the activity class scope and then use this field in the onOptionsItemSelected adding some code parts:
public class MainActivity extends AppCompatActivity {
String clickedImagePath = null
// ...
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if(item.getItemId()==R.id.share_menu){
if (clickedImagePath != null) {
// The code you had for sharing with changing line for uriToImage
Uri uriToImage=Uri.parse(clickedImagePath);
} else {
// maybe show some error than nothing selected
}
}
}
// ...
public void onPhotoClick(String path) {
Toast.makeText(MainActivity.this, ""+path, Toast.LENGTH_LONG).show();
clickedImagePath = path
}
// ...
Maybe a better UX
Remove the onOptionsItemSelected completely and move the intent code to the onPhotoClick listener.
#Override
public void onPhotoClick(String path) {
Toast.makeText(MainActivity.this, ""+path, Toast.LENGTH_LONG).show();
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
Uri uriToImage=Uri.parse(path); // <-- Don't forget to fix the path
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
MainActivity.this.startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.app_name)));
}

Parent Activity of a Fragment is NULL upon Square Receipt Payment Signature

I have a MasterActivity that has a few fragments. One fragment allows the user to open up Square to pay. After the user signs their name in Square and the data is returned to my app, my app crashes because the Payment fragment can't find the MasterActivity as it is null.
This only happens when the user signs the receipt. If the user pays cash (no signature) the My App works fine.
I have noticed that the when the Square App is ready for a signature it rotates the screen, just before the signature capture activity is view-able, I can see my app rotate too.
After the Square application has returned to my app, I can see the successful upload of the data to my server from my app. Then, it is only when the payment fragment asks the MasterActivity to refresh the data, I get a null pointer exception for the DISP_KEY in MasterAcitvity .
Can any see what I might be doing wrong?
MasterActivity
public class MasterActivity extends AppCompatActivity {
private String TAG = getClass().getSimpleName();
private String DISP_KEY = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master);
Intent intent = getIntent();
DISP_KEY = (String) intent.getSerializableExtra("SELECTED_DISPATCH");
initView();
refreshData();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
public void refreshData() {
//Do some network download data stuff using the DISP_KEY
}
private void initView() {
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
//JUST TEXT
tabLayout.addTab(tabLayout.newTab().setText("Details"));
tabLayout.addTab(tabLayout.newTab().setText("Sections"));
tabLayout.addTab(tabLayout.newTab().setText("Area"));
tabLayout.addTab(tabLayout.newTab().setText("Notes"));
tabLayout.addTab(tabLayout.newTab().setText("Payments"));
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new TabPagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
}
}
PaymentFragment
public class PaymentFragment extends Fragment {
private static final int SQUARE_CHARGE_REQUEST_CODE = 1;
private String TAG = getClass().getSimpleName();
private PosClient posClient;
public PaymentFragment() {
// Required empty public constructor for fragments
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_payment, container, false);
initGUI(view);
return view;
}
#Override
public void onStart() {
super.onStart();
mVehicle = ((MasterActivity) this.getActivity()).getCurrentVehicle();
if (mVehicle != null) {
reloadData();
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (this != null) {
((MasterActivity) context).registerDataReloadListener(this);
posClient = PosSdk.createClient(getActivity(), AppConfig.SQUARE_APP_ID);
} else {
((MasterActivity) context).onBackPressed();
}
}
#Override
public void onDetach() {
super.onDetach();
if (this != null) {
((MasterActivity) getActivity()).unregisterDataReloadListener(this);
}
}
public void reloadData() {
//Ask the master activity to reload data
}
// SQUARE
private void acceptSquarePayment() {
ChargeRequest.TenderType types;
ChargeRequest request = new ChargeRequest.Builder(Integer.parseInt(square_balance), CurrencyCode.USD)
.enforceBusinessLocation(square_location_id)
.restrictTendersTo(types)
.requestMetadata(square_call_num)
.autoReturn(3200, TimeUnit.MILLISECONDS)
.build();
Intent intent = posClient.createChargeIntent(request);
startActivityForResult(intent, SQUARE_CHARGE_REQUEST_CODE);
}
// GET SQAURE RESULTS
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
ChargeRequest.Success success = posClient.parseChargeSuccess(data);
sendReceiptToAPIServer(success.serverTransactionId, success.clientTransactionId, success.requestMetadata);
}
}
private void sendReceiptToAPIServer(String serverTransactionId, String clientTransactionId, String callNum) {
//Do some data upload stuff
//After the successufull upload, this is where the crash happens
reloadData();
}
#Override
public void onDataReload() {
mVehicle = ((MasterActivity) this.getActivity()).getCurrentVehicle();
if (getView() != null) {
reloadData();
}
}
}

Updating ImageView in a Fragment Android

I've one MainActivity, and few fragments on it.
I am trying to change a ImageView in a fragment using Gallery. But once image is selected, the MainActivity get refresh, which changes the MainActivity back to the default fragment.
Getting permission
textViewChangeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG,"Select Image executed");
requestPermissions(
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE);
}
});
On Request permission
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.d(TAG,"Select Image Permission executed");
if(requestCode == REQUEST_CODE){
progressDialogUploadDp.setMessage("Uploading...");
progressDialogUploadDp.show();
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
intent.putExtra("imageUpdate","true");
startActivityForResult(intent,REQUEST_CODE);
}else{
Toast.makeText(getActivity(), "No Permission Granted", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
On Activity Result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null){
try {
Uri uri = data.getData();
StorageReference filepath =
storageReference.child("Photos").child("DPs").child(ID).child("profilepicture.jpg");
InputStream inputStream = getActivity().getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageviewpropic.setImageBitmap(bitmap);
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialogUploadDp.hide();
progressDialogUploadDp.dismiss();
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Looking forward for a solution!
Updated ---
MainActivity
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null) {
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("questioners")) {
adapter = new SectionStatePagerAdapter(getSupportFragmentManager());
adapter.addFragment(new HomeFragment(), "HomeFragment");
viewPager.setAdapter(adapter);
}}
}
Back form gallery , activity will run onActivityResult then it will run onResume .
so you can set a FLAG at onActivityResult and make an IF in onResume to set your fragment.
From what you've said it looks like your activity is calling onCreate method and setting default fragment again. What you can do is to in onCreate() create new fragment only if there is no saved state.
if(savedInstanceState==null) setFragment(fragment);

Categories