How to use Fileprovider for sending data (using content uri) to pending intent for notification on click in android N - notificationmanager

I want to open the downloaded file on click of notification. It was working fine when content intent was set using fileUri. But in android N due to enhanced file security it is giving FileUriExposedException. But now after content uri is used , notification click just opens the file location not the file.
Below is the code.
#Override
protected void onPostExecute(String filePath) {
super.onPostExecute(filePath);
if (fileNameAndExtn != null && !fileNameAndExtn.equalsIgnoreCase("")) {
Toast.makeText(mContext, fileNameAndExtn + " downloaded successfully", Toast.LENGTH_LONG).show();
mBuilder.setProgress(100, 100, false);
Intent intent = getPendingIntent(mContext, filePath);
mBuilder.setContentTitle(fileNameAndExtn)
.setAutoCancel(true)
.setContentText("Download complete");
PendingIntent pendingIntent = null;
if (intent != null) {
pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
}
if (pendingIntent != null) {
mBuilder.setContentIntent(pendingIntent).setProgress(0, 0, false);
}
mNotifyManager.notify(mUniqueId, mBuilder.build());
}
}
public Intent getPendingIntent(Context context, String filePath) {
File file = new File(filePath);
Uri contentUri= FileProvider.getUriForFile(context, AppConstants.FILE_PROVIDER_AUTHORITY,file);
Intent intent = new Intent(Intent.ACTION_VIEW,contentUri);
intent.setType(getMimeType(filePath));
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (intent.resolveActivityInfo(context.getApplicationContext().
getPackageManager(), 0) != null) {
return intent;
} else {
Toast.makeText(context, "File not present or Explorer app not present.",
Toast.LENGTH_LONG).show();
return null;
}
}

Related

Files Chooser for Xamarin Forms Not adding the selected image taken from camera and file

I'm creating a mobile application using Xamarin forms, As part of my implementation, I have a requirement to to show file chooser on clicking on camera icon which is loaded in webView and load the image to webView. currently file chooser is being shown, but image is not getting added.
public override bool OnShowFileChooser(Android.Webkit.WebView webView, Android.Webkit.IValueCallback filePathCallback, FileChooserParams fileChooserParams) {
Intent takePictureIntent = new Intent(MediaStore.ActionImageCapture);
if (takePictureIntent.ResolveActivity(mContext.PackageManager) != null) {
Java.IO.File photoFile = null;
try {
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
photoFile = new Java.IO.File(folder, "image" + DateTime.Now.Millisecond + ".png");
takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
//photoFile = createImageFile();
//takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
} catch (Exception e) {
Console.WriteLine("catch the Exception" + e);
}
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
//pictureUri = FileProvider.GetUriForFile(mContext, "asdasd", photoFile);
takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput, photoFile);
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
contentSelectionIntent.SetType(file_type);
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[] {
takePictureIntent
};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ActionChooser);
chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
chooserIntent.PutExtra(Intent.ExtraTitle, "File chooser");
chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
//mContext.StartActivity(chooserIntent);
mContext.StartActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
private Java.IO.File createImageFile() {
// Create an image file name
string timeStamp = Android.OS.SystemClock.CurrentThreadTimeMillis().ToString();
string imageFileName = "JPEG_" + timeStamp + "_";
Java.IO.File storageDir;
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Gingerbread) {
storageDir = mContext.CacheDir;
} else {
storageDir = mContext.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures);
}
//new Java.IO.File(mContext.GetExternalFilesDir(null).AbsolutePath);
Java.IO.File imageFile = Java.IO.File.CreateTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
At first, please add the following code into the AndroidManifest.xml to declare the permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.Read_EXTERNAL_STORAGE" />
And then request the permission in the MainActivity's construction method.
var read = await Permissions.RequestAsync<Permissions.StorageRead>();
var write = await Permissions.RequestAsync<Permissions.StorageWrite>();
Finally, please override the OnActivityResult method of the Mainactivity:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (data != null)
{
if (requestCode == INPUT_FILE_REQUEST_CODE)// the value of the INPUT_FILE_REQUEST_CODE
{
if (null == this.message)
{
return;
}
this.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
this.message = null;
}
}
}

Download and open picture from url/http [Android Xamarin App]

Hello, would any of you send a working code to download a photo from a given http address on android Xamarin c #?
First, I need to create a new folder for my application files.
My goal is to download the file from the internet to my Android folder (saving this file with its original name is best).
The next step is to display the image from that folder in "ImageView". It is also important that there are permissions in android and I do not fully understand it.
Could any of you send it to me or help me understand it and explain the topic?
*Actually i have this code:
string address = "https://i.stack.imgur.com/X3V3w.png";
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted += WebClient_DownloadFileCompleted;
webClient.DownloadFile(address, Path.Combine(pathDire, "MyNewImage1.png"));
//System.Net.WebException: 'An exception occurred during a WebClient request.'
}
Loading image from url and display in imageview.
private void Btn1_Click(object sender, System.EventArgs e)
{
var imageBitmap = GetImageBitmapFromUrl("http://xamarin.com/resources/design/home/devices.png");
imagen.SetImageBitmap(imageBitmap);
}
private Bitmap GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
SavePicture("ImageName.jpg", imageBytes, "imagesFolder");
imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
return imageBitmap;
}
download image and save it in local storage.
private void SavePicture(string name, byte[] data, string location = "temp")
{
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
documentsPath = System.IO.Path.Combine(documentsPath, "Orders", location);
Directory.CreateDirectory(documentsPath);
string filePath = System.IO.Path.Combine(documentsPath, name);
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
int length = data.Length;
fs.Write(data, 0, length);
}
}
you need to add permission WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE in AndroidMainfeast.xml, then you also need to Runtime Permission Checks in Android 6.0.
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the writeexternalstorage.
}
else
{
// writeexternalstorage permission is not granted. If necessary display rationale & request.
}
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the ReadExternalStorage.
}
else
{
// ReadExternalStorage permission is not granted. If necessary display rationale & request.
}
}

WebView File Chooser stops to respond after cancelled selection

we have implement file chooser for web view. it works successfully when attachment is selected, but fails when cancelled without file specification. The file chooser just stops to react on click
any help is appreciated. Thanks
we use chrome client. it works fine if in all cases, file selection is listed. but even from the first file selection is cancelled, no longer file chooser will work. It is Xamarin.Android app based fully on webview
Our code is:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == _mUploadMessage)
return;
// Check that the response is a good one
if (resultCode == Result.Ok)
{
Android.Net.Uri[] results = null;
if (intent == null)
{
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null)
{
results = new Android.Net.Uri[] { Android.Net.Uri.Parse(mCameraPhotoPath) };
}
}
else
{
if (intent.DataString != null)
{
results = new Android.Net.Uri[] { Android.Net.Uri.Parse(intent.DataString) };
}
}
_mUploadMessage.OnReceiveValue(results);
_mUploadMessage = null;
}
}
}
Chrome client:
var chrome = new FileChooserWebChromeClient((uploadMsg) =>
{
_mUploadMessage = uploadMsg;
mCameraPhotoPath = null;
Intent takePictureIntent = new Intent(Android.Provider.MediaStore.ActionImageCapture);
//Create the File where the photo should go
File photoFile = null;
try
{
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
photoFile = new File(folder, "image" + DateTime.Now.Millisecond + ".png");
takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
}
catch (IOException ex)
{
// Error occurred while creating the File
System.Console.WriteLine("" + ex.ToString());
}
// Continue only if the File was successfully created
if (photoFile != null)
{
mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput,
Android.Net.Uri.FromFile(photoFile));
}
else
{
takePictureIntent = null;
}
Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
contentSelectionIntent.SetType("image/*");
Intent[] intentArray;
if (takePictureIntent != null)
{
intentArray = new Intent[] { takePictureIntent };
}
else
{
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ActionChooser);
chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
chooserIntent.PutExtra(Intent.ExtraTitle, this.GetStringFromResource(Resource.String.chose_photo));
chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
base.StartActivityForResult(chooserIntent, HarmonyAndroid.AndroidMainActivity.FILECHOOSER_RESULTCODE);
});
return chrome;
Part 2
class FileChooserWebChromeClient : WebChromeClient
{
Action<IValueCallback> callback;
public FileChooserWebChromeClient(Action<IValueCallback> callback)
{
this.callback = callback;
}
public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
callback(filePathCallback);
return true;
}
public override void OnCloseWindow(WebView window)
{
base.OnCloseWindow(window);
}
}
Part 3
webView.ImprovePerformance();
webView.SetWebViewClient(new HomeWebViewClient(customWebViewClientListener, clientId));
webView.SetWebChromeClient(chrome);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.DomStorageEnabled = true;
webView.SetDownloadListener(new CustomDownloadListener(activity, customDownloadListener));
webView.AddJavascriptInterface(new JavaScriptToCSharpCommunication(activity, javaScriptToCSharpCommunicationListener), Constants.JS_CSHARP_COMMUNICATOR_NAME);
Try to give a null object to the uri callback, when the resultCode is not RESULT_OK.
add in your OnActivityResult method:
if (resultCode != Result.Ok)
{
_mUploadMessage.OnReceiveValue(null);
_mUploadMessage = null;
return;
}

BarCodeEye QR Cocde Scanner implementation in my application

i am trying to integrate qr code scanner in my application in android, i am using zxing library BarcodeEye.
i have implemented below piece of code
Intent intent = new Intent("com.github.barcodeeye.scan.CaptureActivity");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
but i am getting a RuntimeException saying that unable to start activity component : android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.github.barcodeeye.scan}
can any one help me where i am going wrong
Thanks & Regards.
Nagendra
You will need to register CaptureActivity Activity in the AndroidManifest.xml
<activity
android:name="com.github.barcodeeye.scan.CaptureActivity"
android:clearTaskOnLaunch="true"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="landscape"
android:stateNotNeeded="true"
android:theme="#style/CaptureTheme"
android:windowSoftInputMode="stateAlwaysHidden" >
<intent-filter>
<action android:name="com.github.barcodeeye.SCAN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Here is how I use BarCodeEye:
private void startScanActivityForResult(Bundle extras)
{
Intent intentScan = new Intent("com.github.barcodeeye.SCAN");
intentScan.setPackage("com.github.barcodeeye");
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intentScan.putExtras(extras);
intentScan.putExtra("SCAN_MODE", "QR_CODE_MODE");
intentScan.putExtra("RESULT_DISPLAY_DURATION_MS", 1000L);
intentScan.putExtra("SAVE_HISTORY", false);
intentScan.putExtra("PROMPT_MESSAGE", "QR scan http://user:pass#server");
WtcLog.info(TAG, "startScanActivityForResult: startActivityForResult(intentScan=" + intentScan + ", REQUEST_SCAN)");
startActivityForResult(intentScan, REQUEST_SCAN);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
WtcLog.info(TAG, "onActivityResult data=" + WtcUtilsPlatform.toString(data));
Bundle extras = null;
if (data != null)
{
extras = data.getExtras();
}
switch (requestCode)
{
case REQUEST_SCAN:
{
WtcLog.info(TAG, "onActivityResult: REQUEST_SCAN");
if (resultCode == RESULT_OK)
{
WtcLog.info(TAG, "onActivityResult: resultCode == RESULT_OK");
String result = data.getStringExtra("SCAN_RESULT");
extras = validateScan(result);
/// your logic here
}
else
{
WtcLog.warn(TAG, "onActivityResult: resultCode != RESULT_OK; exiting");
// your logic here
finish();
}
break;
}
}
}
private Bundle validateScan(String result)
{
Bundle extras = new Bundle();
String[] userpass;
try
{
URI uri = new URI(result);
String userinfo = uri.getRawUserInfo();
if (WtcString.isNullOrEmpty(userinfo))
{
throw new URISyntaxException(result, "");
}
userpass = userinfo.split(":", 2);
if (userpass.length != 2)
{
throw new URISyntaxException(result, "");
}
String server = uri.getHost();
if (WtcString.isNullOrEmpty(server))
{
throw new URISyntaxException(result, "");
}
extras.putString("server", server);
}
catch (URISyntaxException e)
{
WtcLog.error(TAG, "validateScan: EXCEPTION", e);
extras.putString("error", "uri must be in format \"http://username:password#server\"");
return extras;
}
try
{
String username = URLDecoder.decode(userpass[0], "UTF-8");
extras.putString("username", username);
String password = URLDecoder.decode(userpass[1], "UTF-8");
extras.putString("password", password);
}
catch (UnsupportedEncodingException e)
{
WtcLog.error(TAG, "validateScan: EXCEPTION", e);
extras.putString("error", "username and password must be UTF-8");
return extras;
}
return extras;
}

Android camera intent does not return to onActivityResult

I am trying to save a full camera image to a specified Uri when passing the uri to the camera intent. But it does not return to onActvityResult. However, I have tried getting the image using Bundle in the onActivityResult but it returns a thumbnail. I have tried lots of tutorials and they all had this problem. Can u please help!!!
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File u = getTempFile();
picUri = Uri.fromFile(u);
camera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(u));
startActivityForResult(camera, TAKE_PICTURE);
onActivityResult
if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK && null != data)
{
Toast.makeText(this, "Image saved to:\n"+picUri, Toast.LENGTH_LONG).show();
}
Try code given below :
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment
.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, REQUEST_CAMERA);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CAMERA) {
File f = new File(Environment.getExternalStorageDirectory()
.toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
String path = f.getAbsolutePath();
} }
}

Resources