Android application crashes when USB device is removed - android

I am sending an excel file into a USB device in an activty via send Intent, and i can manage this process as it's supposed to be. After sending data, when i remove the USB device my current Activity (regardless of the which Activity is active) is closing without any warning or error with a code line. I just get the error below.
Unknown bits set in runtime_flags: 0x8000
The export excel file code:
private void exportFile(File file) {
ArrayList<Uri> pickedFileUris = new ArrayList<>();
if (android.os.Build.VERSION.SDK_INT >= 27) {
Uri imageUri = FileProvider.getUriForFile(getApplicationContext(), provider, file);
pickedFileUris.add(imageUri);
} else {
pickedFileUris.add(Uri.fromFile(file));
}
Intent sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
sendIntent.setType("application/excel");
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Export Items");
sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, pickedFileUris);
sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{});
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
FileSaverActivity.firstInit = false;
Intent chooser = Intent.createChooser(sendIntent, null);
List<ResolveInfo> resInfoList = this.getPackageManager().queryIntentActivities(chooser, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
this.grantUriPermission(packageName, pickedFileUris.get(0), Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
startActivity(chooser);
}
I am using that export function for export image and pdf files and never gets an error like that. I really don't know what is the problem. When i search about the runtime_flags: 0x8000 there are so many different things but found nothing to help me.

Related

Xamarin Android Sharing Intent under Marshmallow

In my Application I try to share an Image with the Intent (Intent.ActionSend).
For the guaranteed Access I use a Fileprovider which creates the Uri to the file.
Under Android Nougat my code works but with Marshmallow not. It shows no errors but the Image is not sent to the recieving App.
The Output from VisualStudio also shows no errors or somthing like that.
I couldn't find any answer online so far. What is the problem with Marshmallow?
public void SendPhoto(IEnumerable<string> photos, string text)
{
var files = new List<Android.Net.Uri>();
//creates for every photo an own ContentURI
foreach (var path in photos)
{
var file = new Java.IO.File(path);
files.Add(FileProvider.GetUriForFile(Context, "com.testapp.fileprovider", file));
}
//Checks if Photolist are empty
if (!files.Any())
throw new Exception("Photos not found");
Intent intent = new Intent(Intent.ActionSend);
intent.SetFlags(ActivityFlags.GrantReadUriPermission);
intent.SetType("image/jpeg");
intent.PutExtra(Intent.ExtraSubject, "Subject");
intent.PutExtra(Intent.ExtraStream, files.First());
//creates the sharemessage
var shareMessage = files.Count == 1 ? "Send photo from TestApp" : "Send photos from TestApp";
//start Intent chooser
Context.StartActivity(Intent.CreateChooser(intent, shareMessage));
}

Android Filter Intent Chooser

I would like to filter the list you see below. Only file-explorer should be choosable.
intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse(Environment.getExternalStorageDirectory() + "/Android/data/" + getContext().getPackageName() + "/Files");
intent.setDataAndType(uri, "*/*");
startActivity(Intent.createChooser(intent, getString(R.string.openFolder)));
EDIT:
This is not possible. There is no magic Intent that always only opens some magic app category.
First, anyone can write any app to respond to any desired implicit Intent.
Second, there is no universal definition of "file explorer". What you think a "file explorer" is may differ from what other developers think a "file explorer" is, which in turn may differ from what users think a "file explorer" is. A user's device may not even have a "file explorer", from anyone's definition.
Add this in your Intent, it would open a ES File Explorer
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filePath)));
intent.setPackage("com.estrongs.android.pop");
startActivity(shareIntent);
You can call the below function
type is the package name of file-explorer
like if you want to share data to Twitter call it like initShareIntent("com.twitter.android");
private void initShareIntent(String type) {
boolean found = false;
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/jpeg");
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = getActivity().getPackageManager().queryIntentActivities(share, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase().contains(type) ||
info.activityInfo.name.toLowerCase().contains(type)) {
//Share Data here
share.setPackage(info.activityInfo.packageName);
found = true;
break;
}
}
if (!found) {
Toast.makeText(getActivity(), share_type + " not found in Device", Toast.LENGTH_SHORT).show();
return;
}
startActivity(Intent.createChooser(share, "Select"));
}
}
It will only open the particular app to share data. Try this and let me know if it helped you
Make sure that the directory exists then try this :
Intent fileManagers = new Intent();
fileManagers.setAction(Intent.ACTION_GET_CONTENT);
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
.getAbsolutePath());
Uri uri = Uri.fromFile(dir);
fileManagers.setDataAndType(uri, "file/*");
startActivity(Intent.createChooser(fileManagers, null));

how to find my android application's storing path of apk file

I want to make an application that could send itself (apk file) by bluetooth. but i have trouble with finding the apk file path. i tried this code:
final PackageManager pm = this.getPackageManager();
List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_META_DATA);
String st = null;
for (PackageInfo packageInfo : packages) {
if(packageInfo.packageName.contains("testbutton"))
st=packageInfo.packageName;
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/*");
String uri = "/data/app/";
uri+=st;
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(uri)));
startActivity(intent);
but st returns null value.
please help me with this. thanks in advance
finally i'd found the right answer that works in this purpose, thanks to #Kanak for her help :)
PackageManager pm = getPackageManager();
String uri = null;
for (ApplicationInfo app : pm.getInstalledApplications(0)) {
if(!((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1))
if(!((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1)){
uri=app.sourceDir;
if(uri.contains("com.example.test"))
break;
}
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(uri)));
startActivity(intent);
There is no need to iteration. Getting the application itself APK file uri is as easy as this:
String appUri = getApplicationInfo().publicSourceDir;
Also note that doc says this about publicSourceDir:
Full path to the publicly available parts of sourceDir,
including resources and manifest. This may be different from
sourceDir if an application is forward locked.
And also note that to send an APK file, you need to set the type to application/vnd.android.package-archive instead of image/*
So the complete snippet would be:
String appUri = getApplicationInfo().publicSourceDir;
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("application/vnd.android.package-archive");
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(appUri)));
startActivity(Intent.createChooser(sharingIntent, "Share via"));

Android: How to open a specific folder via Intent and show its content in a file browser?

I thought this would be easy but as it turns out unfortunately it's not.
What I have:
I have a folder called "myFolder" on my external storage (not sd card because it's a Nexus 4, but that should not be the problem). The folder contains some *.csv files.
What I want:
I want to write a method which does the following: Show a variety of apps (file browsers) from which I can pick one (see picture). After I click on it, the selected file browser should start and show me the content of "myFolder". No more no less.
My question:
How exactly do I do that? I think I came quite close with the following code, but no matter what I do - and I'm certain that there must be something I didn't get right yet - it always opens only the main folder from the external storage.
public void openFolder()
{
File file = new File(Environment.getExternalStorageDirectory(),
"myFolder");
Log.d("path", file.toString());
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(Uri.fromFile(file), "*/*");
startActivity(intent);
}
This should help you:
Uri selectedUri = Uri.parse(Environment.getExternalStorageDirectory() + "/myFolder/");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(selectedUri, "resource/folder");
if (intent.resolveActivityInfo(getPackageManager(), 0) != null)
{
startActivity(intent);
}
else
{
// if you reach this place, it means there is no any file
// explorer app installed on your device
}
Please, be sure that you have any file explorer app installed on your device.
EDIT: added a shantanu's recommendation from the comment.
LIBRARIES:
You can also have a look at the following libraries https://android-arsenal.com/tag/35 if the current solution doesn't help you.
I finally got it working. This way only a few apps are shown by the chooser (Google Drive, Dropbox, Root Explorer, and Solid Explorer). It's working fine with the two explorers but not with Google Drive and Dropbox (I guess because they cannot access the external storage). The other MIME type like "*/*" is also possible.
public void openFolder(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath()
+ File.separator + "myFolder" + File.separator);
intent.setDataAndType(uri, "text/csv");
startActivity(Intent.createChooser(intent, "Open folder"));
}
Here is my answer
private fun openFolder() {
val location = "/storage/emulated/0/Download/";
val intent = Intent(Intent.ACTION_VIEW)
val myDir: Uri = FileProvider.getUriForFile(context, context.applicationContext.packageName + ".provider", File(location))
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
intent.setDataAndType(myDir, DocumentsContract.Document.MIME_TYPE_DIR)
else intent.setDataAndType(myDir, "*/*")
if (intent.resolveActivityInfo(context.packageManager, 0) != null)
{
context.startActivity(intent)
}
else
{
// if you reach this place, it means there is no any file
// explorer app installed on your device
CustomToast.toastIt(context,context.getString(R.string.there_is_no_file_explorer_app_present_text))
}
}
Here why I used FileProvider - android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
I tested on this device
Devices: Samsung SM-G950F (dreamltexx), Os API Level: 28
Intent chooser = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getDownloadCacheDirectory().getPath().toString());
chooser.addCategory(Intent.CATEGORY_OPENABLE);
chooser.setDataAndType(uri, "*/*");
// startActivity(chooser);
try {
startActivityForResult(chooser, SELECT_FILE);
}
catch (android.content.ActivityNotFoundException ex)
{
Toast.makeText(this, "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
In code above, if setDataAndType is "*/*" a builtin file browser is opened to pick any file, if I set "text/plain" Dropbox is opened. I have Dropbox, Google Drive installed. If I uninstall Dropbox only "*/*" works to open file browser. This is Android 4.4.2. I can download contents from Dropbox and for Google Drive, by getContentResolver().openInputStream(data.getData()).
Thread is old but I needed this kind of feature in my application and I found a way to do it so I decided to post it if it can help anyone in my situation.
As our device fleet is composed only by Samsung Galaxy Tab 2, I just had to find the file explorer's package name, give the right path and I succeed open my file explorer where I wanted to. I wish I could use Intent.CATEGORY_APP_FILES but it is only available in API 29.
Intent intent = context.getPackageManager().getLaunchIntentForPackage("com.sec.android.app.myfiles");
Uri uri = Uri.parse(rootPath);
if (intent != null) {
intent.setData(uri);
startActivity(intent);
}
As I said, it was easy for me because our clients have the same device but it may help others to find a workaround for their own situation.
this code will work with OI File Manager :
File root = new File(Environment.getExternalStorageDirectory().getPath()
+ "/myFolder/");
Uri uri = Uri.fromFile(root);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setData(uri);
startActivityForResult(intent, 1);
you can get OI File manager here : http://www.openintents.org/en/filemanager
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, DocumentsContract.Document.MIME_TYPE_DIR);
startActivity(intent);
Will open files app home screen
Today, you should be representing a folder using its content: URI as obtained from the Storage Access Framework, and opening it should be as simple as:
Intent i = new Intent(Intent.ACTION_VIEW, uri);
startActivity(i);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("text/csv");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(Intent.createChooser(intent, "Select a File to Upload"), 0);
} catch (android.content.ActivityNotFoundException ex) {
ex.printStackTrace();
}
then you just need to add the response
public void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode) {
case 0: {
//what you want to do
//file = new File(uri.getPath());
}
}
}
You seem close.
I would try to set the URI like this :
String folderPath = Environment.getExternalStorageDirectory()+"/pathTo/folder";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
Uri myUri = Uri.parse(folderPath);
intent.setDataAndType(myUri , "file/*");
startActivity(intent);
But it's not so different from what you have tried.
Tell us if it changes anything ?
Also make sure the targeted folder exists, and have a look on the resulting Uri object before to send it to the intent, it may not be what we are expected.
File temp = File.createTempFile("preview", ".png" );
String fullfileName= temp.getAbsolutePath();
final String fileName = Uri.parse(fullfileName)
.getLastPathSegment();
final String filePath = fullfileName.
substring(0,fullfileName.lastIndexOf(File.separator));
Log.d("filePath", "filePath: " + filePath);
fullfileName:
/mnt/sdcard/Download_Manager_Farsi/preview.png
filePath:
/mnt/sdcard/Download_Manager_Farsi

Limiting Android PackageManager to a single choice

My application evokes the android PackageManager when a file is chosen and the user is presented with a choice of applications to handle how the file should be dealt with. I want to limit this choice to Bluetooth. Currently Bluetooth comes up as the first option which is fine and this all works. I was wondering if its possible to only present the user with this single option.
case REQUEST_FILE_SELECT:
if (requestCode == REQUEST_FILE_SELECT) {
// Get the Uri of the selected file
Uri uri = data.getData();
Log.d(TAG, "File Uri: " + uri.toString());
// Get the path
String path = null;
try {
path = FileUtils.getPath(this, uri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
Log.d(TAG, "File Path: " + path);
// Get the file instance
File mFile = new File(path);
// Evoke the file chooser
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent shareIntent = new Intent(
android.content.Intent.ACTION_SEND);
shareIntent.setType("*/*");
// Evoke the package manager
List<ResolveInfo> resInfo = getPackageManager()
.queryIntentActivities(shareIntent,
PackageManager.GET_ACTIVITIES);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
if (packageName.equals("com.android.bluetooth")) {
Intent targetedShareIntent = new Intent(
android.content.Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM,
Uri.fromFile(mFile));
targetedShareIntent.setPackage(packageName);
targetedShareIntents.add(targetedShareIntent);
startActivity(Intent.createChooser(shareIntent,
"Share File"));
}
}
}
}
Solution: find out which apps does the device support for your intent, find the one that is bluetooh, invoke it directly.
This article answers your question:
http://tsicilian.wordpress.com/2012/11/06/bluetooth-data-transfer-with-android/
From the article:
We can see that the BT application is among those handlers. We could of course let the user pick that application from the list and be done with it. But if we feel we should be a tad more user-friendly, we need to go further and start the application ourselves, instead of simply displaying it in a midst of other unnecessary options…But how?
One way to do that would be to use Android’s PackageManager this way:
//list of apps that can handle our intent
PackageManager pm = getPackageManager();
List appsList = pm.queryIntentActivities( intent, 0);
if(appsList.size() > 0 {
// proceed
}
The above PackageManager method returns the list we saw earlier of all activities susceptible to handle our file transfer intent, in the form of a list of ResolveInfo objects that encapsulate information we need:
//select bluetooth
String packageName = null;
String className = null;
boolean found = false;
for(ResolveInfo info: appsList){
packageName = info.activityInfo.packageName;
if( packageName.equals("com.android.bluetooth")){
className = info.activityInfo.name;
found = true;
break;// found
}
}
if(! found){
Toast.makeText(this, R.string.blu_notfound_inlist,
Toast.LENGTH_SHORT).show();
// exit
}
We now have the necessary information to start BT ourselves:
//set our intent to launch Bluetooth
intent.setClassName(packageName, className);
startActivity(intent);
What we did was to use the package and its corresponding class retrieved earlier. Since we are a curious bunch, we may wonder what the class name for the “com.android.bluetooth” package is. This is what we would get if we were to print it out: com.broadcom.bt.app.opp.OppLauncherActivity. OPP stands for Object Push Profile, and is the Android component allowing to wirelessly share files.
Also in the article, how to enable the bluetooth from your application.

Categories

Resources