Team,
Trying to Work on Camera Taking Picture but everytime getting result as Android.App.Result.Canceled and data as null on OnActivityresult function.
TakePicture.Click += delegate
{
if (slabDetails != null)
{
File SlabFile = new File(Constants.INVENTORY_PATH, slabDetails.ExtSlabNo + ".jpg");
//if (SlabFile.Exists()) { SlabFile.Delete(); }
//SlabFile.CreateNewFile();
imageUri = Uri.FromFile(SlabFile);
//var documentsDirectry = ApplicationContext.GetExternalFilesDir(Environment.DirectoryPictures);
//File cameraFile = new Java.IO.File(documentsDirectry, "default_image" + ".jpg");
//Uri photoURI = Uri.FromFile(cameraFile);
Intent camIntent = new Intent(MediaStore.ActionImageCapture);
camIntent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
camIntent.PutExtra(MediaStore.ExtraOutput, imageUri);
camIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
camIntent.AddFlags(ActivityFlags.GrantWriteUriPermission);
StartActivityForResult(camIntent, 2);
}
};
On Activity Result Function
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
switch (requestCode)
{
case 2:// From Camera
if (resultCode == Result.Ok)
{
try
{
new SyncDataTask(this, data, 1, db).Execute();
}
catch (Exception ex)
{
var method = System.Reflection.MethodBase.GetCurrentMethod();
var methodName = method.Name;
var className = method.ReflectedType.Name;
MainActivity.SaveLogReport(className, methodName, ex);
}
catch (OutOfMemoryError ex)
{
ex.PrintStackTrace();
}
}
}
}
Using Xamarin Native Android deploying in Android API 33 and Android 12 Version tablets. It Return the Image and Works good on android version 11 tablets.
Provided permissions in android manifest file as per Android 13 Tutorials
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.MANAGE_MEDIA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
So, I would like to return Android.App.Result.Ok and data in ActivityResult. So, Do anybody faced the issue. Please help me in this Case. Thanks in Advance.
I have implemented a download manager that works on Android 7 and above. However, this does not work on Android 6. Is the download manager not available on Android 6 ? The download process does not start!
private long startDownload(URL fileURL, String fileName) {
Uri uri=Uri.parse(fileURL.toString());
return this.downloadManager.enqueue(new DownloadManager.Request(uri)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |
DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName));
}
I use this method to check if the download is started and completed.
private void waitForDownload(long downloadId , Cursor cursor)
{
try
{
while (this.activeDownload)
{
this.messageController.showMessage(new DownloadMessage());
cursor = this.downloadManager.query(new DownloadManager.Query().setFilterById(downloadId));
if (cursor.moveToFirst())
{
#SuppressLint("Range") int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
#SuppressLint("Range") int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
Timber.i("DOWNLOAD " + downloadId + " RUNNING - Progress: " + dl_progress + "%");
}
Thread.sleep(500);
}
}
catch (Exception e)
{
Timber.e(e);
}
}
The following permissions are set.
<uses-permission android:name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<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.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.ACTION_CLOSE_SYSTEM_DIALOGS" />
In my App, there is provision of taking picture through Camera and send it for Crop but when the Camera App opens with the sent image and the user crops and clicks on OK, a toast is displayed by the Camera App,
"Unable to save cropped images"
Here is the code I have written for it:
public static void sendImageForCrop(final Activity activity, final Uri mImageCaptureUri){
final ArrayList<CropOption> cropOptions = new ArrayList<>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = activity.getPackageManager().queryIntentActivities(
intent, 0);
int size = list.size();
if (size == 0) {
Toast.makeText(activity, "Can not find image crop app",
Toast.LENGTH_SHORT).show();
} else {
//intent.setData(mImageCaptureUri);
intent.setDataAndType(mImageCaptureUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
try{
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File.createTempFile("temp", null, activity.getCacheDir())));
}catch(IOException ioe){
// It is unfortunate that the Photo can't be cropped.
// Show a Toast for this.
Toast.makeText(activity, "The photo couldn't be saved :(. Try clearing the App data.", Toast.LENGTH_SHORT).show();
return;
}
activity.startActivityForResult(i, CROP_FROM_CAMERA);
}
}
And here is the toString() of the Intent object:
Intent { act=com.android.camera.action.CROP dat=file:///storage/emulated/0/Snap_1508218098533.jpg typ=image/* flg=0x2 (has extras) }
What might be the problem here?
EDIT: As requested, here is the manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.example"
android:versionCode="156"
android:versionName="1.2.54">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>
<uses-sdk tools:overrideLibrary="com.braintreepayments.api.core,com.android.volley,com.paypal.android.sdk.onetouch.core,com.braintreepayments.api" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.location.network"
android:required="false" />
<uses-feature
android:name="android.hardware.location"
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<uses-feature
android:name="android.hardware.microphone"
android:required="false" />
<!-- Tell the system this app requires OpenGL ES 2.0. -->
<uses-feature
android:glEsVersion="0x00015000"
android:required="true" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<application
android:name="com.example.example.UILApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#drawable/applicationlogo"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/Theme.MyTheme">
<!-- List of Activities here -->
<provider
android:name=".provider.GenericFileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
</application>
</manifest>
I think the problem is may be with the path where your trying to save,
try to use like below
public void choosePhoto(View view) {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", int_Width_crop);
intent.putExtra("outputY", int_Height_crop);
intent.putExtra("scale", false);
intent.putExtra("return-data", true);
File photo = new File(Environment.getExternalStorageDirectory(), "cropped_image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, CHOOSE_PICTURE);
}
I had same problem but I fixed by changing the path of saved image directory as below -:
File croppedImageDirectory = new File(Environment.getExternalStorageDirectory()+"/croppedImage");
Or, see this answer may help you-: stackoverflow.com/a/1976115
May help you
I know this would be a considered a hack approach by many of you but it works!
intent.putExtra(MediaStore.EXTRA_OUTPUT, (String)null);
Reasoning
Well, I looked up the source of Gallery App in MarshMallow(one of the places the crop was failing; other was the Photos App) and found this method that handles a CROP request:
private void saveOutput(Bitmap croppedImage) {
if (mSaveUri != null) {
OutputStream outputStream = null;
try {
outputStream = mContentResolver.openOutputStream(mSaveUri);
if (outputStream != null) {
croppedImage.compress(mOutputFormat, 75, outputStream);
}
} catch (IOException ex) {
// TODO: report error to caller
Log.e(TAG, "Cannot open file: " + mSaveUri, ex);
} finally {
Util.closeSilently(outputStream);
}
Bundle extras = new Bundle();
setResult(RESULT_OK, new Intent(mSaveUri.toString())
.putExtras(extras));
} else if (mSetWallpaper) {
try {
WallpaperManager.getInstance(this).setBitmap(croppedImage);
setResult(RESULT_OK);
} catch (IOException e) {
Log.e(TAG, "Failed to set wallpaper.", e);
setResult(RESULT_CANCELED);
}
} else {
Bundle extras = new Bundle();
extras.putString("rect", mCrop.getCropRect().toString());
File oldPath = new File(mImage.getDataPath());
File directory = new File(oldPath.getParent());
int x = 0;
String fileName = oldPath.getName();
fileName = fileName.substring(0, fileName.lastIndexOf("."));
// Try file-1.jpg, file-2.jpg, ... until we find a filename which
// does not exist yet.
while (true) {
x += 1;
String candidate = directory.toString()
+ "/" + fileName + "-" + x + ".jpg";
boolean exists = (new File(candidate)).exists();
if (!exists) {
break;
}
}
try {
int[] degree = new int[1];
Uri newUri = ImageManager.addImage(
mContentResolver,
mImage.getTitle(),
mImage.getDateTaken(),
null, // TODO this null is going to cause us to lose
// the location (gps).
directory.toString(), fileName + "-" + x + ".jpg",
croppedImage, null,
degree);
setResult(RESULT_OK, new Intent()
.setAction(newUri.toString())
.putExtras(extras));
} catch (Exception ex) {
// basically ignore this or put up
// some ui saying we failed
Log.e(TAG, "store image fail, continue anyway", ex);
}
}
final Bitmap b = croppedImage;
mHandler.post(new Runnable() {
public void run() {
mImageView.clear();
b.recycle();
}
});
finish();
}
You see the statement, if (mSaveUri != null) {. It handles the case where we provide a null Uri. The assumption is that the 3rd party App is likely to handle the case where we provide a null Uri.
Now, I tested it with a couple of Apps and it worked. But by no means, this solution is an ideal one.
There are some similar questions on StackOverflow but the situations they happened a little bit different.
I need to read a file (in Service) that user shared with a standard share mechanism.
There are no problems reading files from gallery or files shared by File Managers or Google Drive. But there are problems when I try to share files from Downloads.
I receive:
java.lang.SecurityException: Permission Denial: opening provider
com.android.providers.downloads.DownloadStorageProvider from
ProcessRecord{432abf50 8550:clipboard.clipboardtest/u0a167} (pid=8550,
uid=10167) requires android.permission.MANAGE_DOCUMENTS or
android.permission.MANAGE_DOCUMENTS
My manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="virtualclipboard.copytodesktop"
android:installLocation="internalOnly">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED" />
<application>
...
</application>
</manifest>
The code to read a file. I receive Uri in intent while share operation.
InputStream input = getContentResolver().openInputStream(fileUri);
byte[] fileData = Converter.InputStreamToByteArray(input);
// ...
public class Converter {
public static byte[] InputStreamToByteArray(InputStream inputStream) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int reads = inputStream.read();
while(reads != -1){
baos.write(reads);
reads = inputStream.read();
}
return baos.toByteArray();
}
catch (Exception e) {
return null;
}
}
}
Reproduced on Nexus 5, 4.4.4, KitKat.
I cannot copy a file to the external sdcard. Does not show up any error, in-fact shows success, but the file is not on the sd card. Code is as follows:
window.resolveLocalFileSystemURI(fileURI, step1,fail);
function step1(tmp_file)
{
file = tmp_file;
window.resolveLocalFileSystemURI("file:///mnt/extsd", step2,fail); //resolve destinaion
}
function step2(destination)
{
file.moveTo(destination,"example.jpg",move_success, move_fail);
}
So on the end it calls move_success.
NOTE: IT WORKS IF I CHANGE PATH FROM 'file:///mnt/extsd' to the internal sdcard path 'file:///mnt/sdcard'
Permissions in manifest
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
You should build your path, not define it as default, cause not in all devices the sdcard is called "sdcard", for example, i have a chinnese tablet, and this has 2 sdcard slots, so i have to use the path "sdcard2" you can do it:
File sdcard = Environment.getExternalStorageDirectory();
String path = "file://"+sdcard.getAbsolutePath();
Then you can use the variable
window.resolveLocalFileSystemURI(path, step2,fail); //resolve destinaio
Or, you can use this method to copy a file:
public void copy(File src, File dst) throws IOException {
try {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException io) {
Toast.makeText(this, "Error: " + io, Toast.LENGTH_LONG).show();
}
}
You can copy the file, next delete it, as a fast move.
Or as other alternative, you can use the property renameTo() of the file,
For example:
File sdcard = Environment.getExternalStorageDirectory();
File example= new File(sdcard.getAbsolutePath()+"/example.txt");
File newpath= new File(sdcard.getAbsolutePath()+"/examplefolder/example.txt");
example.renameTo(newpath);//this will move the file to the new path