I am working with sd card and so trying to get permission in runtime. Here is the code:
public class MainActivity extends AppCompatActivity implements FileListFragment.OnFragmentInteractionListener {
private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 111;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
...................
................
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
FileListFragment fileListFragment = FileListFragment.newInstance(0); // **Error line**
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fileListFragment)
.commit();
} else {
finish();
}
return;
}
}
}
.............................
..................................
..........................
}
As soon as I am allow the permission it is throwing "Failure delivering result ResultInfo{who=#android:requestPermissions:, request=111, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.kaushik.fileexplorer/com.kaushik.fileexplorer.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState". Here is the details logcat:
08-23 16:49:29.497 3215-3215/com.kaushik.fileexplorer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.kaushik.fileexplorer, PID: 3215
java.lang.RuntimeException: Failure delivering result ResultInfo{who=#android:requestPermissions:, request=111, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.kaushik.fileexplorer/com.kaushik.fileexplorer.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1533)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1551)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:696)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:662)
at com.kaushik.fileexplorer.MainActivity.onRequestPermissionsResult(MainActivity.java:76)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6553)
at android.app.Activity.dispatchActivityResult(Activity.java:6432)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
What is problem in that code?
You should add commitAllowingStateLoss()
FileListFragment fileListFragment = FileListFragment.newInstance(0); // **Error line**
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fileListFragment)
.commitAllowingStateLoss();
Please check this link
This Error is because the Activity State is Not Saved and you are adding Fragment before it.
Use This Code :
FileListFragment fileListFragment = FileListFragment.newInstance(0);
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fileListFragment)
.commitAllowingStateLoss();
And Override Your onSaveInstanceState() method and remove the super() from it.
using commitAllowingStateLoss() is more like a hacky fix.
This problem is very similar to this one and is well explained here.
Instead it's better to set a boolean flag in onRequestPermissionsResult and use this in onPostResume (for Activitys) or onResume (for Fragments) to commit the transaction.
Related
i'm trying to run ML Kit pose detection on a video from the phone gallery by using the following code (i tried to follow the documentation Detect Poses with ML KIT):
public class MainActivity extends AppCompatActivity {
Button pick;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pick = findViewById(R.id.elegir);
videoView = findViewById(R.id.video);
mc = new MediaController(MainActivity.this);
videoView.setMediaController(mc);
pick.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent pickintent = new Intent(Intent.ACTION_GET_CONTENT);
pickintent.setType("video/*");
startActivityForResult(pickintent, 1);
}
});
}
#Override
public void onActivityResult(int requestcode, int resultcode, Intent data){
super.onActivityResult(requestcode, resultcode, data);
if(requestcode == 1 ){
Uri videouri = data.getData();
PoseDetectorOptions options =
new PoseDetectorOptions.Builder()
.setDetectorMode(PoseDetectorOptions.STREAM_MODE)
.build();
PoseDetector poseDetector = PoseDetection.getClient(options);
InputImage image = null;
try {
image = InputImage.fromFilePath(getApplicationContext(), videouri);
} catch (IOException e) {
e.printStackTrace();
}
Task<Pose> result =
poseDetector.process(image)
.addOnSuccessListener(
new OnSuccessListener<Pose>() {
#Override
public void onSuccess(Pose pose) {
// Task completed successfully
// ...
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Task failed with an exception
// ...
}
});
}
}
}
Error log:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mlkit, PID: 11193
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/video:31 flg=0x1 }} to activity {com.example.mlkit/com.example.mlkit.MainActivity}: java.lang.NullPointerException: InputImage can not be null
at android.app.ActivityThread.deliverResults(ActivityThread.java:5015)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5056)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException: InputImage can not be null
at com.google.android.gms.common.internal.Preconditions.checkNotNull(com.google.android.gms:play-services-basement##17.6.0:2)
at com.google.mlkit.vision.common.internal.MobileVisionBase.processBase(com.google.mlkit:vision-common##16.5.0:11)
at com.google.mlkit.vision.pose.internal.PoseDetectorImpl.process(com.google.mlkit:pose-detection-common##17.1.0-beta3:2)
at com.example.mlkit.MainActivity.onActivityResult(MainActivity.java:93)
at android.app.Activity.dispatchActivityResult(Activity.java:8310)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5008)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5056)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I would like to know the proper way to run pose detection in this context. I understand something is going wrong with the InputImage, but i dont know how to fix it
The class is called InputImage instead of InputVideo, so when you use fromFilePath, it expects a file for image instead of video.
Here are some answers on Github about using video file as input: https://github.com/googlesamples/mlkit/issues?q=is%3Aissue+in%3Atitle+%22video+file%22+
Basically, you will need to break the video into separate frames and construct InputImage for each frame.
In my app I have a fragment and an imageButton inside of this fragment. When I run the app in my device (Android 8 - API 26) and click imageButton, the app crashes and throws a runtime error which I didn't see before.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mustafa.diyetisyenadmin, PID: 26366
java.lang.SecurityException: Permission Denial: null asks to run as user 1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS
at android.os.Parcel.readException(Parcel.java:1945)
at android.os.Parcel.readException(Parcel.java:1891)
at android.view.autofill.IAutoFillManager$Stub$Proxy.addClient(IAutoFillManager.java:326)
at android.view.autofill.AutofillManager.ensureServiceClientAddedIfNeededLocked(AutofillManager.java:903)
at android.view.autofill.AutofillManager.notifyViewExited(AutofillManager.java:487)
at android.view.View.notifyEnterOrExitForAutoFillIfNeeded(View.java:6983)
at android.view.View.dispatchAttachedToWindow(View.java:17594)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3332)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1792)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1515)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7266)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:981)
at android.view.Choreographer.doCallbacks(Choreographer.java:790)
at android.view.Choreographer.doFrame(Choreographer.java:721)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:967)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
So I added the required permissions in Manifest.xml and also tried every codes in the topic Android permission.INTERACT_ACROSS_USERS_FULL but I get the same error. I have solved Autofill problem with this topic but in that fragment error occurs just only I clicked ImageButton. What should I do to solve this problem?
Finally I found out the solution. Problem occurs since I had a method in my activity named getUserId() that returns String user_id and send data to fragments. I changed it's name and now everything works fine.
You have to add runtime permission. To do that follow
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!checkIfAlreadyhavePermission()) {
requestForSpecificPermission();
}
}
Module checkIfAlreadyhavePermission() is implemented as :
private boolean checkIfAlreadyhavePermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.INTERACT_ACROSS_USERS_FULL);
return result == PackageManager.PERMISSION_GRANTED;
}
Module requestForSpecificPermission() is implemented as :
private void requestForSpecificPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERACT_ACROSS_USERS_FULL}, 101);
}
and Override in Activity :
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 101:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//DO WHATEVER YOU WANTED TO DO
} else {
//not granted
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
As you can see this is my code, I built several applications in which I used several permission methods without any problem. In this case, I only have just one activity but it gives me an error while it wants to return the request permission result.
Code:
public class ActivityStartUp extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
private static final String[] PERMISSIONS = { "android.permission.CAMERA",
"android.hardware.camera", "android.hardware.camera.autofocus",
"android.hardware.camera.flash",
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE" ,
"android.permission.READ_PHONE_STATE"};
private static final int PERMISSION_CODE = 0xBAB0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_startup);
if (Utilities.hasMarshmallowApi()) {
requestPermissions(PERMISSIONS, PERMISSION_CODE);
}else{
//Open an activity
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_CODE: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
G.permissionGrantStatus = true;
Log.i("Log", "Permission Status:" + true);
if(Utilities.hasMarshmallowApi()){
// Do something
}
// Do task
} else {
G.permissionGrantStatus = false;
Log.i("Log", "Permission Status:" + false);
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
}
Error:
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=#android:requestPermissions:, request=47792, result=-1,
data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }}
to activity {com.bvapp.sh.uni.watermanagement/com.bvapp.sh.uni.watermanagement.ActivityStartUp}:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
As you can see in error "grantResults" has 0 length. I tried to find a good solution but unfortunately I couldn't fine a right one. why it's happening and how should I solve it?
Thanks in advance.
Maybe this is you'r problem (from: OnRequestPermissionsResultCallback() - Android Developer)
Note: It is possible that the permissions request interaction with the user is interrupted. In this case you will receive empty
permissions and results arrays which should be treated as a
cancellation.
I'm making an async request with retrofit, on the middle of request i minimize the app and crash the app...
My log error:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1842)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1860)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:650)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:609)
at br.com.ole.oleconsignado.util.ActivityUtils.replaceFragmentToActivityWithBackStack(ActivityUtils.java:109)
at br.com.ole.oleconsignado.ui.fragment.init.LoginFragment.notifyGetProspectSuccess(LoginFragment.java:410)
at br.com.ole.oleconsignado.ui.presenter.LoginPresenter$4.onSuccess(LoginPresenter.java:91)
at br.com.ole.oleconsignado.ui.presenter.LoginPresenter$4.onSuccess(LoginPresenter.java:88)
at br.com.ole.oleconsignado.network.RestCallback.onResponse(RestCallback.java:24)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6165)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
Here it's the method I call if the request return success:
ActivityUtils.replaceFragmentToActivityWithBackStack(getFragmentManager(), IncompleteStatusFragment.newInstance(mLogin.getCustomerId(), mCustomer, prospect, mLogin), R.id.container_login);
Can someone help me?
That is obvious, if you minimize the app then you won't be able to replace the fragment as your app is not in focus & throw java.lang.IllegalStateException. you should probable maintain a flag & in onResume of your activity if that flag is true then replace the fragment.
like
#Override
public void onPause() {
mIsActivityVisible = false;
}
#Override
public void onResume() {
mIsActivityVisible = true;
if(mShouldReplaceFragmentOnResume) {
mShouldReplaceFragmentOnResume = false;
// replace fragment
}
}
// On Success response
onSuccessOfYourCall() {
if(mIsActivityVisible) {
//replace fragment
} else {
mShouldReplaceFragmentOnResume = true;
}
}
When I try to dissmiss a FragmentDialog, my app crashes sometimes.
Here's the log:
Process: com.xxx, PID: 9981
java.lang.RuntimeException: Error receiving broadcast Intent { act=xxxx flg=0x10 (has extras) } in xxxxxx
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:893)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5438)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()' on a null object reference
at android.app.DialogFragment.dismissInternal(DialogFragment.java:296)
at android.app.DialogFragment.dismissAllowingStateLoss(DialogFragment.java:277)
at xxxxx.updateStatus(BaseAppCompatActivity.java:96)
at xxxxx.access$000(BaseAppCompatActivity.java:43)
at xxxxx$1.onReceive(BaseAppCompatActivity.java:79)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:883)
xxxxx.updateStatus(BaseAppCompatActivity.java:96)
this line is try to dismiss a DialogFragment:
mDialogFragment.dismissAllowingStateLoss();
A DialogFragment is in my Activity.
private SimpleBlockedDialogFragment mDialogFragment = SimpleBlockedDialogFragment.newInstance();
So mDialogFragment is not null.
I show dialog like this:
FragmentTransaction ft = getFragmentManager().beginTransaction();
mDialogFragment.updateMessage("xxx");
mDialogFragment.show(ft, "block_dialog");
And dismiss dialog like this:
mDialogFragment.dismissAllowingStateLoss();
Sometimes, I show dialog only once, but dismiss more than once. But I don't think that cause a crash.
Here's the dismissInternal function in the DialogFragment:
void dismissInternal(boolean allowStateLoss) {
if (mDismissed) {
return;
}
mDismissed = true;
mShownByMe = false;
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
mViewDestroyed = true;
if (mBackStackId >= 0) {
getFragmentManager().popBackStack(mBackStackId,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
mBackStackId = -1;
} else {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.remove(this);
if (allowStateLoss) {
ft.commitAllowingStateLoss();
} else {
ft.commit();
}
}
}
log tells me that getFragmentManager() return null. I don't know why this happened.
How to dismiss a FragmentDialog correctly?
update:
I try android.support.v4.app.FragmentTransaction, and still get an exception.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentTransaction android.support.v4.app.FragmentManager.beginTransaction()' on a null object reference
at android.support.v4.app.DialogFragment.dismissInternal(DialogFragment.java:196)
at android.support.v4.app.DialogFragment.dismissAllowingStateLoss(DialogFragment.java:177)
Help~
Try getSupportFragmentManager().beginTransaction(); this may help.