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" />
Related
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 found an anomaly during tests with this particular device, the details are below:
Hardware: samsung,SM-A326B (Smartphone Samsung A32)
OS: Android 12
ONE UI: 4.1
Google Play: 01/may/22
Patch level: 01/june/22
These are the specs of one device that works properly, the only differences that I see are related to different version of the patch level.
Hardware: samsung,SM-A515F (Smartphone Samsung A51)
OS: Android 12
ONE UI: 4.1
Google Play: 01/may/22
Patch level: 01/may/22
I have implemented a customization of camera2 in my application, this always works except with this device, the specific anomaly is that the images are saved completely white and are corrupted, the image can only be recovered by third party software.
These are the permissions I ask for in the manifest:
<uses-feature android:name="android.hardware.location.gps " />
<uses-feature android:name="android.hardware.location.network" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
This is the code that I use to save the images
public void saveCameraImage(Image mImage, File mFile, String mOrientation, Context context) {
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(mFile);
fileOutputStream.write(bytes);
} catch (IOException e) {
wil.WriteFile("saveImage - Exception: " + e.getMessage(), context);
} finally {
mImage.close();
if (null != fileOutputStream) {
try {
fileOutputStream.close();
} catch (IOException e) {
wil.WriteFile("saveImage - Exception: " + e.getMessage(), context);
} finally {
saveExifData(mFile.getPath(), context);
createThumbs(mOrientation, mFile, context);
}
}
}
}
This is the function that I named "saveExifData"
private void saveExifData(String filepath, Context context) {
try {
if (filepath.endsWith(IMAGE_FORMAT)) {
File file = new File(filepath);
if (file.exists()) {
DbGest dbGest = DbGest.getInstance(context);
String dateTime = dbGest.getTimestampFromFileToSend(filepath, "dateTime", context);
String dateTimeGps = dbGest.getTimestampFromFileToSend(filepath, "gps", context);
String dateTimeDesc = dbGest.getTimestampFromFileToSend(filepath, "dateTimeDesc", context);
ExifInterface exifInterface = new ExifInterface(filepath);
exifInterface.setAttribute(ExifInterface.TAG_COPYRIGHT, "xxxxx ");
exifInterface.setAttribute(ExifInterface.TAG_MODEL, Build.MANUFACTURER + "," + Build.MODEL);
exifInterface.setAttribute(ExifInterface.TAG_SOFTWARE, dbGest.getSetting("appName", context));
exifInterface.setAttribute(ExifInterface.TAG_DATETIME, dateTime);
exifInterface.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, dateTime);
exifInterface.setAttribute(ExifInterface.TAG_USER_COMMENT, "Immagine scattata tramite " + dbGest.getSetting("appName", context) + " il " + dateTimeDesc);
CoordinatesData position = DbGest.getInstance(context).getBetterPositionKnown(context);
exifInterface.setAttribute(ExifInterface.TAG_GPS_LATITUDE, String.valueOf(position.getLat()));
exifInterface.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, String.valueOf(position.getLng()));
exifInterface.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, dateTimeGps);
exifInterface.setAttribute(ExifInterface.TAG_GPS_SPEED, String.valueOf(position.getSpeed()));
exifInterface.setLatLong(position.getLat(), position.getLng());
exifInterface.saveAttributes();
}
}
} catch (Exception e) {
wil.WriteFile("saveExifData - Exception: " + e.getMessage(), context);
}
}
So I guess it's not a permission issue, also there are no exceptions, so I don't know how to fix this
After several test and debugging I find the cause of the bug.
The problem it is in the "saveExifData", for some reason this row of code
exifInterface.setAttribute(ExifInterface.TAG_COPYRIGHT, "xxxx");
it is the cause of the problem
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.
I'm trying to develop an app which provides many movies and you can play it or download the movie.
I'm using Download Manager to download the movie from server, but it didn't work...
this is my method
public void downloadFileFromUrl(String url, String fileName) {
String filePath=Environment.getExternalStorageDirectory() + File.separator + "BlueNet";
File folder = new File(filePath);
if (!folder.exists()) {
folder.mkdirs();
}
try {
Uri downloadUri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(downloadUri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
request.allowScanningByMediaScanner();
request.setDestinationInExternalPublicDir("BlueNet", fileName);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE | DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setVisibleInDownloadsUi(true);
DownloadManager downloadManager = (DownloadManager)getApplicationContext().getSystemService(DOWNLOAD_SERVICE);
long id= downloadManager.enqueue(request);
}
catch (Exception ex){
Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show();
}
}
this is attribute
url: (http://192.168.1.5:8080/BlueNet_NMC/video_shared/blue_elephant.mp4)
filename: (blue_elephant.mp4)
and I already give this permissions to manifests
<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.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
but when I test it in emulator or in my Galaxy S4 not working.
Please help me.
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