TransactionTooLargeException when trying to send binary content, using Intents [closed] - android

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I need to send binary content from my app to whatever app opens that file type in the device.
I'm following these instructions:
https://developer.android.com/training/sharing/send.html#send-binary-content
Here's my code:
final FileType fileType
final File file;
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(AncestryApplication.getAppContext(), AncestryApplication.getAppContext().getApplicationContext().getPackageName() + ".provider", file));
intent.setType(fileType.getMimeType());
startActivity(intent);
A few things:
If I change the intent action from ACTION_VIEW to ACTION_SEND, I get the wrong possible list of apps to open my file
ACTION_SEND seems to work, but only with small file sizes
intent.setDataAndType() seems to work fine on devices OS M and lower. On N I get the same TransactionTooLargeException
At the end, this is what I need to accomplish:
I already have a file saved, and it is stored at file:///storage/emulated/0/Download/TempFile.html
Since the file may be too large, I need to send just the location of the file to a third party app (like adobe pdf reader) to open the file
No issues on M or lower, tons of issues on N
Any ideas on what I may be doing wrong? I've been trying to solve this for a few days and I've read a ton of tutorials and SO suggestions, without any final answer.
Thanks.
EDIT: here's my stacktrace:
AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.android.apps.myapp, PID: 26785
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 27943540 bytes
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3752)
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:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.os.TransactionTooLargeException: data parcel size 27943540 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:615)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3606)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3744)
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:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
EDIT 2: Added onSaveInstanceState() code from base fragment:
#Override
public void onSaveInstanceState(final Bundle outState) {
mSaveInstanceStateCalled = true;
outState.putBoolean(KEY_PROCESSING_SAVE, mSaveInProgress);
}

The exception in the logcat you posted is caused by packing too much data into the Bundle processed by onSaveInstanceState.
Here is the method from the Android source where it is thrown, if the build version is N or greater:
private static class StopInfo implements Runnable {
ActivityClientRecord activity;
Bundle state;
PersistableBundle persistentState;
CharSequence description;
#Override public void run() {
// Tell activity manager we have been stopped.
try {
if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
ActivityManagerNative.getDefault().activityStopped(
activity.token, state, persistentState, description);
} catch (RemoteException ex) {
if (ex instanceof TransactionTooLargeException
&& activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
return;
}
throw ex.rethrowFromSystemServer(); // <<-- exception thrown here
}
}
}
I am posting this in the form of an answer because it's too long for a comment. It is not meant as a complete answer to the question, because there is not enough information in the question to answer it.

Related

Problem to integrate Jitsi Meet Sdk with linphone

I am using JItsi meet api for video call on linphone android app open source project. I have followed jitsi meet handbook for integrating on linphone.
Here is my sample code:
public class JitsiActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
URL serverURL;
try {
serverURL = new URL("https://meet.jit.si");
} catch (MalformedURLException e) {
e.printStackTrace();
throw new RuntimeException("Invalid server URL!");
}
JitsiMeetConferenceOptions defaultOptions =
new JitsiMeetConferenceOptions.Builder()
.setServerURL(serverURL)
.setWelcomePageEnabled(false)
.build();
JitsiMeet.setDefaultConferenceOptions(defaultOptions);
JitsiMeetConferenceOptions options =
new JitsiMeetConferenceOptions.Builder().setRoom("linphone").build();
JitsiMeetActivity.launch(this, options);
finish();
}
}
I have successfully made a call on debug mode, after making an apk on release mode, It refresh activity when I attempt to make a video call and go to home page. can you give me a guideline to solve this problem. I have tested apk on Android 10 OS.
--After Debugging on release mode I have found this error
020-09-24 16:50:12.383 10364-10364/org.linphone E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.linphone, PID: 10364
java.lang.IllegalArgumentException: reportSizeConfigurations: ActivityRecord not found for: Token{2329006 ActivityRecord{cf5fae1 u0 org.linphone/.activities.JitsiActivity d-1 s-1 t-1 f}}
at android.os.Parcel.createException(Parcel.java:1967)
at android.os.Parcel.readException(Parcel.java:1931)
at android.os.Parcel.readException(Parcel.java:1881)
at android.app.IActivityManager$Stub$Proxy.reportSizeConfigurations(IActivityManager.java:8621)
at android.app.ActivityThread.reportSizeConfigurations(ActivityThread.java:3360)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3318)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:113)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:71)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7096)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:928)
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.am.ActivityManagerService.reportSizeConfigurations(ActivityManagerService.java:10305)
at android.app.IActivityManager$Stub.onTransact$reportSizeConfigurations$(IActivityManager.java:12560)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2357)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3841)
at android.os.Binder.execTransact(Binder.java:750)
You need to provide a stacktrace to for anyone to help you debug it, however, this code can be simplified greatly which would lead to easier debugging..
You are supplying Jitsi with it's own default server url "https://meet.jit.si" which isn't necessary as Jitsi will use it's own server anyway. If you were planning on using your own server you can still provide that easily in the JitsiMeetActivity::launch method as the room parameter...
JitsiMeetActivity.launch(context, "https://myserver.com/linphone")
Removing all the unnecessary boiler-plate will leave you with this:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
JitsiMeetActivity.launch(this, "linphone");
}

Allow to disable Oreo Autofill service for a package

I am developer of a password manager app which provides an Android Autofill service (Android 8+).
Some users requested that it should be possible to disable this service on a per-target-app basis. In the autofill service's onFillRequest I am adding a "dataset" with "Disable autofill for [package name]" like this:
var sender = IntentBuilder.GetDisableIntentSenderForResponse(this, query, isManual, isForDisable);
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName,
GetString(Resource.String.autofill_disable , new Java.Lang.Object[] { query}), Resource.Drawable.ic_menu_close_grey);
var datasetBuilder = new Dataset.Builder(presentation);
datasetBuilder.SetAuthentication(sender);
foreach (var autofillId in autofillIds)
{
datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
}
responseBuilder.AddDataset(datasetBuilder.Build());
When the user clicks the "Disable dataset", an activity is launched which stores the package for which Autofill should be disabled and then immediately finishes itself.
My question: what should I return as a reply from that activity to indicate that Autofill should be invisible from now on?
I am currently doing
bool isManual = Intent.GetBooleanExtra(ChooseForAutofillActivityBase.ExtraIsManualRequest, false);
Intent reply = new Intent();
FillResponse.Builder builder = new FillResponse.Builder();
AssistStructure structure = (AssistStructure)Intent.GetParcelableExtra(AutofillManager.ExtraAssistStructure);
StructureParser parser = new StructureParser(this, structure);
try
{
parser.ParseForFill(isManual);
}
catch (Java.Lang.SecurityException e)
{
Log.Warn(CommonUtil.Tag, "Security exception handling request");
SetResult(Result.Canceled);
return;
}
AutofillFieldMetadataCollection autofillFields = parser.AutofillFields;
var autofillIds = autofillFields.GetAutofillIds();
builder.SetIgnoredIds(autofillIds);
Bundle state = new Bundle();
state.PutStringArray("AutoFillDisabledQueries", disabledValues.ToArray());
builder.SetClientState(state);
try
{
var response = builder.Build();
reply.PutExtra(AutofillManager.ExtraAuthenticationResult, response);
}
catch (Exception e)
{
Kp2aLog.LogUnexpectedError(e);
throw;
}
SetResult(Result.Ok, reply);
But
1.) The prompt for autofill does not disappear
2.) if I click disable again, the target app is force-closed (see end of message for details)
so that's obviously not the way to go... Any ideas? Thanks a lot!
Regarding point 2 above, I see the following in logcat:
12-17 09:48:31.865 Google Pixel Error 11711 AndroidRuntime java.lang.RuntimeException: Failure delivering result ResultInfo{who=#android:autoFillAuth:, request=16121857, result=-1, data=Intent { (has extras) }} to activity {com.sonelli.juicessh/com.sonelli.juicessh.activities.ManageConnectionActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:4361)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4403)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1809)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
setIgnoredIds() should be used for fields that are not autofillable (for example, if the screen had an username, password, and captcha fields, you could use to ignore the latter).
If you want to disable autofill for the activity, you need to return a Fillresponse with just the [disableAutofill()][1] set on it. Notice that disabling it doesn't persist after reboots, so you should keep track of it internally, and call that API if the activity triggers autofill again.

getContentResolver().delete() throws IllegalArgumentException sporadically

We released a beta of our product, it works for most users, but one user with OnePlus 5T/Android 8.1 reports a sporadic exception:
java.lang.RuntimeException: Unable to resume activity {com.ourproduct/com.ourproduct.MainActivity}: java.lang.IllegalArgumentException: Unknown URL content://com.ourproduct.data/delete
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3726)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3766)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1737)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6753)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:482)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by:java.lang.IllegalArgumentException: Unknown URL content://com.ourproduct.data/delete
at android.content.ContentResolver.delete(ContentResolver.java:1745)
<... here is our code stacktrace ...>
I contacted the user and got some additional info: the issue does not happen every time he uses the operation, just sometimes.
The content provider is defined in the same application.
The code is trivial, just for completeness of the question:
protected void unsetValue(final String group, final String name) {
myContext.getContentResolver().delete(
uri("delete"), null, new String[] { group, name }
);
}
private Uri uri(String location) {
return Uri.parse("content://com.ourproduct.data/" + location);
}
Any ideas? Maybe I can ask the user for some additional info?

Listener won't work

I'm trying to set a Listener for my custom views that I put in a LinearLayout. Those views are created by code depending on a certain files or data, so I don't know the number of views there is. The OnClickListener is being set, but onClick() is never called:
#Override
protected void onResume() {
super.onResume();
try {
setupBackEnd();
} catch (IOException e) {
Toast.makeText(this, "Error Reading or Writing data in Storage, Try to restart the App", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
Toast.makeText(DayActivity.this, "Child count: " + linearList.getChildCount(), Toast.LENGTH_SHORT).show();
for (int i = 0; i < linearList.getChildCount(); i++) {
linearList.getChildAt(i).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(DayActivity.this, "clicked", Toast.LENGTH_SHORT).show();
}
});
}
}
This is my code. To make sure the child views are already there I showed a Toast and it gave me "Child Count: 5" but "clicked" Toast never shows up. I made sure that My custom Views are clickable (The childs of linearlist). But the listener won't work for some reason. Anyone knows why?
Edit: After I tried to debug the code I got this error:
10-27 18:52:26.309 17630-17630/osm_cave.timecave E/AndroidRuntime: FATAL EXCEPTION: main
Process: osm_cave.timecave, PID: 17630
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy#672721e is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:679)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.widget.Toast$TN.handleShow(Toast.java:459)
at android.widget.Toast$TN$2.handleMessage(Toast.java:342)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
c
This error won't be shown when I launch the app without debugging it only appears when Debugging with breakpoints. This error is supposed to mean I'm trying to use a context that no longer exist but I'm not so what's the problem here??
It looks like your toast message is running into an error.
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.widget.Toast$TN.handleShow(Toast.java:459)
at android.widget.Toast$TN$2.handleMessage(Toast.java:342)
at android.os.Handler.dispatchMessage(Handler.java:102)
If I remember correctly, the new object that you are creating of type View.OnClickListener (since it is anonymous) cannot access the DayActivity.this attribute. Instead you should get the activity from the view.
public void onClick(View view) {
Activity activity = (Activity) view.getContext()
Toast.makeText(activity, "clicked", Toast.LENGTH_SHORT).show();
}
While there's nothing wrong with using a Toast message to test for an event occurring, I would recommend simplifying to just using a log message. Log messages aren't context sensitive are unlikely to fail except if you provide a null message to it.
If Log messages are not working, the next troubleshooting step should be to examine the custom views and view hierarchy. If any clickable transparent views are in front of the custom views, they would intercept the click events. Double check that the view itself is clickable as well.

Unexpected Intent with action WEB_SEARCH

I have pretty large app to inspect with a lot of activities. One of most popular exceptions is
No Activity found to handle Intent {
act=android.intent.action.WEB_SEARCH (has extras) }
What the heck? I don't see in code any "WEB_SEARCH" anywhere, I can't reproduce it, I don't even know where to look for cause (in which Activity). Below stack of Exception, without any class from my package... How to track and fix this?
Fatal Exception: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.WEB_SEARCH (has extras) }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1659)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1434)
at android.app.Activity.startActivityForResult(Activity.java:3432)
at android.app.Activity.startActivityForResult(Activity.java:3393)
at android.support.v4.app.FragmentActivity.startActivityForResult(Unknown Source)
at android.app.Activity.startActivity(Activity.java:3628)
at android.app.Activity.startActivity(Activity.java:3596)
at android.webkit.SelectActionModeCallbackSec.onActionItemClicked(SelectActionModeCallbackSec.java:390)
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onActionItemClicked(PhoneWindow.java:3264)
at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onActionItemClicked(Unknown Source)
at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onActionItemClicked(Unknown Source)
at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onActionItemClicked(Unknown Source)
at android.support.v7.view.StandaloneActionMode.onMenuItemSelected(Unknown Source)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(Unknown Source)
at android.support.v7.view.menu.MenuItemImpl.invoke(Unknown Source)
at android.support.v7.view.menu.MenuBuilder.performItemAction(Unknown Source)
at android.support.v7.view.menu.MenuBuilder.performItemAction(Unknown Source)
at android.support.v7.view.menu.MenuPopupHelper.onItemClick(Unknown Source)
at android.widget.AdapterView.performItemClick(AdapterView.java:301)
at android.widget.AbsListView.performItemClick(AbsListView.java:1490)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3275)
at android.widget.AbsListView$1.run(AbsListView.java:4518)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5283)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(NativeStart.java)
I have to answer my own question for another future searchers. For use in Activity with WebView, or for safety in some Base/MainActivity abstract layer:
#Override
public void startActivityForResult(Intent i, int reqCode, Bundle b){
boolean activityExists = i.resolveActivityInfo(getPackageManager(), 0) != null;
if(activityExists)
super.startActivityForResult(i, reqCode, b);
else{
if(Intent.ACTION_WEB_SEARCH.equals(i.getAction()) && i.getExtras()!=null){
String query = i.getExtras().getString(SearchManager.QUERY, null);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.pl/search?q="+query));
boolean browserExists = i.resolveActivityInfo(getPackageManager(), 0) != null;
if(browserExists && query!=null){
startActivity(browserIntent);
return;
}
}
Toast.makeText(this, R.string.error_no_app_for_intent, Toast.LENGTH_LONG).show();
}
}
Reason of this behaviour is (probably) custom system UI/modded Android made by hardware producer, which is adding some features related with searching. Not reproducable on "clean" Android device
Met the same issue recently, did some dig, i think snachmsm's answer is good, and i wanna make some analysis for other searchers.
Obviously no code written by me is starting an Intent with WEB_SEARCH, and according to the crash log, the intent is invoked by android.webkit.SelectActionModeCallbackSec.onActionItemClicked, so the fact is that if you use a webview, when the user long click and select some text , in some phones or themes or ROMs it will show an ActionMenu with "find" and "web search" or only one of them, depends on the various implementation. And when the user click "web search" it will start an intent with WEB_SEARCH.
Then the solution is simple, in the Activities that use a webview, override startActivityForResult to handle the certain intent. Why don't he override startActivity either? Because startActivity invoke startActivityForResult eventually.

Categories

Resources