How to get status of downloading? - android

I use DownloadManager for getting status of downloading, but it still doesn't work, it never jumps to condition if(c.moveToFirst()) and I don't know why. Could anybody help me, please?
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_SCREEN_OFF.equals(action)) {
DownloadManager downloadMgr = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterByStatus(DownloadManager.STATUS_FAILED|DownloadManager.STATUS_PENDING|DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_SUCCESSFUL);
Cursor c = downloadMgr.query(query);
if(c==null) {
//
}
else {
if(c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = c.getInt(columnIndex);
if(status == DownloadManager.STATUS_RUNNING){
//do something
}
}
}
}
}
};

Here are few link refer it.
LINK1
LINK2
sample code is below::
DownloadManager.Query query = null;
Cursor c = null;
DownloadManager downloadManager = null;
downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
query = new DownloadManager.Query();
if(query!=null) {
query.setFilterByStatus(DownloadManager.STATUS_FAILED|DownloadManager.STATUS_PAUSED|DownloadManager.STATUS_SUCCESSFUL|
DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_PENDING);
} else {
return;
}
c = downloadManager.query(query);
if(c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch(status) {
case DownloadManager.STATUS_PAUSED:
break;
case DownloadManager.STATUS_PENDING:
break;
case DownloadManager.STATUS_RUNNING:
break;
case DownloadManager.STATUS_SUCCESSFUL:
break;
case DownloadManager.STATUS_FAILED:
break;
}
}

This is how I do it
//broadcastReceiver
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
//call notify off NotificationManager passing in the id & notification
notificationManager.apply {
notify(NOTIFICATION_ID, createNotification())
}
//DownloadManager.Query() is used to filter DownloadManager queries
val query = DownloadManager.Query()
query.setFilterById(id)
val cursor = downloadManager.query(query)
if (cursor.moveToFirst()){
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
when (status) {
DownloadManager.STATUS_SUCCESSFUL ->{
}
DownloadManager.STATUS_FAILED -> {
}
}
}
}
}

Related

Message not added to store after SmsManager SendTextMessage

G'day,
My question is fairly straight forward:
Should I expect SMSManager.Default.SendTextMessage() to automatically add the sent message to the message store, or do I need to add it myself? If I need to add it myself, should I do that in the BroadcastReceiver or in the dependency service after sending?
For context:
I'm trying to recreate an SMS app as practice for myself.
I've managed to create a dependency service that gets messages from the message store and have a BroadcastReceiver to notify when a message is received.
My issue arises when I try to use the below code to send a message.
public Task SendSMS(string message, string destination)
{
piSent = PendingIntent.GetBroadcast(context, destination.GetHashCode(), new Intent("SMS_SENT"), PendingIntentFlags.UpdateCurrent);
//var piDelivered = PendingIntent.GetBroadcast(context, 0, new Intent("SMS_DELIVERED"), 0);
try
{
manager.SendTextMessage(destination, null, message, piSent, null);
}
catch (Exception e)
{
Toast.Make(e.Message, ToastDuration.Long).Show();
}
return Task.CompletedTask;
}
So the BroadcastReceiver for SMS_SENT gets the intent and has a Result.Ok code, but the message itself isn't added to the message store. I also haven't live tested this to see if the message actually sends.
This is the code I use to get all messages from the store.
public async Task<ObservableCollection<Message>> GetMessages(string thread_id)
{
var inbox = App.Current.Resources["smsInbox"] as string;
var cols = new string[] { "address", "_id", "thread_id", "body", "date" };
var projection = "thread_id=?";
string[] selection = { thread_id };
var results = await ExecuteQuery(inbox, cols, projection, selection);
var messages = new ObservableCollection<Message>();
foreach(var result in results)
{
messages.Add(new Message
{
Address = result[0],
Id = result[1],
ThreadId = result[2],
Body = result[3],
Date = DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(result[4]))
});
}
return messages;
}
private async Task<List<List<string>>> ExecuteQuery(string uriString, string[] cols, string projection, string[] projectionValue = null)
{
await init();
var queryData = new List<List<string>>();
var uri = Android.Net.Uri.Parse(uriString);
var cursor = context.ContentResolver.Query(uri, cols, projection, projectionValue, null);
if (cursor.MoveToFirst())
{
do
{
var tuple = new List<string>(cursor.ColumnCount);
for (int i = 0; i < cursor.ColumnCount; i++)
{
tuple.Add(cursor.GetString(i));
}
queryData.Add(tuple);
} while (cursor.MoveToNext());
}
cursor.Close();
return queryData;
}
And the broadcastreceiver
[BroadcastReceiver(Exported = true)]
public class MessageSentReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
switch ((int)ResultCode)
{
case (int)Result.Ok:
Toast.Make("SMS Sent", ToastDuration.Short).Show();
break;
case (int)SmsResultError.GenericFailure:
Toast.Make("Generic Error", ToastDuration.Short).Show();
break;
case (int)SmsResultError.NoService:
Toast.Make("No Service", ToastDuration.Short).Show();
break;
case (int)SmsResultError.NullPdu:
Toast.Make("Null PDU", ToastDuration.Short).Show();
break;
case (int)SmsResultError.RadioOff:
Toast.Make("Radio Off", ToastDuration.Short).Show();
break;
default:
Toast.Make("Default Message", ToastDuration.Short).Show();
break;
}
}
}
Thanks in advance, and apologies if this isn't enough information to answer the question.
Well, after double-triple checking I wasn't making a fool of myself, turns out I was.
The messages are saved in the sent table, so weren't showing up when I pulled from the inbox.
Lesson learnt!
I guess I'll leave this here to save someone else that's having a brain fade.

Pausing and resuming a download

I know there are some libraries for this, but i want to implement my own pause/resume functionality for android.
i'm now using DownloadManager for downloading and this is the service i implemented for download:
public class DownloadService extends Service {
public static boolean isServiceRunning = false;
private static String downloadingPackageName;
private DownloadManager downloadManager;
long downloadRef;
RemoteViews contentView;
private boolean isDownloading = false;
Notification notification;
NotificationManager manager;
DownloadRequestListener downloadRequestListener;
NotificationManager notifManager;
private String dirPath;
private String packageName;
public static String PACKAGE_NAME;
#Override
public void onCreate() {
super.onCreate();
PACKAGE_NAME = getApplicationContext().getPackageName();
Log.e("OnCreate","OnCreateCommandClled...");
downloadRequestListener = new DownloadRequestListener();
IntentFilter filter = new IntentFilter("ir.amulay.downloadRequest");
registerReceiver(downloadRequestListener, filter);
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
isServiceRunning = true;
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.e("Service","Service Destroyed...");
unregisterReceiver(downloadRequestListener);
isServiceRunning = false;
super.onDestroy();
}
public Long downloadFile(String path, String packageName, String dirPath){
if(isDownloading) return null;
isDownloading =true;
this.dirPath = dirPath;
notifManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
contentView = new RemoteViews(getPackageName(), R.layout.download_notification_bar);
contentView.setImageViewResource(R.id.image, R.mipmap.ic_launcher);
contentView.setTextViewText(R.id.title, "Custom notification");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChanel = new NotificationChannel(
"downloadChanel",
"Example Service Chanel",
NotificationManager.IMPORTANCE_LOW
);
manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChanel);
}
notification = new NotificationCompat.Builder(this,"downloadChanel")
.setContentTitle("test")
.setContentText("test Againg")
.setContent(contentView)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setAutoCancel(false)
.build();
startForeground(1,notification);
//I Dont Want many files to be downloaded at same time, so here is a check...
downloadingPackageName = packageName;
Uri uri = Uri.parse(path);
//Uri dir = Uri.parse(dirPath + "/" + packageName + ".apk");
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
this.packageName = packageName;
request.setTitle("Download File");
request.setDestinationInExternalPublicDir(dirPath, packageName+".apk");
request.setDescription("download apk files using download manager");
request.setMimeType(getMimeType(uri.toString()));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
request.setVisibleInDownloadsUi(false);
// request.setDestinationUri(dir);
request.setAllowedOverMetered(true);
request.setAllowedOverRoaming(true);
downloadRef = downloadManager.enqueue(request);
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
boolean downloading = true;
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadRef); //filter by id which you have receieved when reqesting download from download manager
Cursor cursor = manager.query(q);
if(cursor.getCount() <= 0 ){
return;
}
cursor.moveToFirst();
//if its Running Send BroadCast... :)
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_RUNNING) {
int bytes_downloaded = cursor.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
final int dl_progress = (int) ((bytes_downloaded * 100L) / bytes_total);
Log.e("DownloadProgress", "progress= " + dl_progress);
contentView.setTextViewText(R.id.title,"Downloading " +dl_progress);
// contentView.setProgressBar(R.id.downloadProgress,200,dl_progress,true);
notification.contentView.setProgressBar(R.id.downloadProgress, 100, dl_progress, false);
notifManager.notify(1, notification );
Intent intent = new Intent();
intent.setAction("ir.amulay.downloadEvent");
intent.putExtra("eventType","downloadProgress");
intent.putExtra("progresspercent",""+dl_progress);
intent.putExtra("packagename",packageName);
intent.putExtra("refID",""+downloadRef);
sendBroadcast(intent);
}
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
}
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_FAILED) {
downloading = false;
}
cursor.close();
if(!downloading) {
Intent intent= new Intent();
intent.setAction("ir.amulay.downloadEvent");
intent.putExtra("eventType","downloadCompleted");
intent.putExtra("packagename",packageName);
intent.putExtra("refID",""+downloadRef);
sendBroadcast(intent);
//send a broadcast to tell its completed
return;
}
handler.postDelayed(this,300);
}
});
return downloadRef;
}
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Fetching the download id received with the broadcast
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
//Checking if the received broadcast is for our enqueued download by matching download id
if (downloadRef == id) {
long downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
openDownloadedAttachment(context, downloadId);
}
}
};
private String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
type = mime.getMimeTypeFromExtension(extension);
}
return type;
}
private void openDownloadedAttachment(final Context context, final long downloadId) {
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
int downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
String downloadLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
String downloadMimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));
if ((downloadStatus == DownloadManager.STATUS_SUCCESSFUL) && downloadLocalUri != null) {
openDownloadedAttachment(context, Uri.parse(downloadLocalUri), downloadMimeType);
}
}
cursor.close();
}
private void openDownloadedAttachment(final Context context, Uri attachmentUri, final String attachmentMimeType) {
if(attachmentUri!=null) {
// Get Content Uri.
if (ContentResolver.SCHEME_FILE.equals(attachmentUri.getScheme())) {
// FileUri - Convert it to contentUri.
File file = new File(attachmentUri.getPath());
attachmentUri = FileProvider.getUriForFile(this, "com.freshdesk.helpdesk.provider", file);
}
Intent openAttachmentIntent = new Intent(Intent.ACTION_VIEW);
openAttachmentIntent.setDataAndType(attachmentUri, attachmentMimeType);
openAttachmentIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
context.startActivity(openAttachmentIntent);
} catch (ActivityNotFoundException e) {
// Toast.makeText(context, context.getString("cant O"), Toast.LENGTH_LONG).show();
}
finally {
stopSelf();
}
}
}
private class DownloadRequestListener extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Received", Toast.LENGTH_SHORT).show();
String reqType = intent.getStringExtra("reqType");
String packageName =intent.getStringExtra("package");
if(reqType.equals("download")){
String url = intent.getStringExtra("url");
String dirPath = intent.getStringExtra("dirPath");
downloadFile(url,packageName,dirPath);
}
else if(reqType.equals("stop")){
if(downloadingPackageName.equals(packageName) && downloadManager!= null){
downloadManager.remove(downloadRef);
isDownloading =false;
unregisterReceiver(onDownloadComplete);
stopSelf();
}
}
}
}
}
how can i implement Pause/Resume for my downloads? WITHOUT a library?
is it possible trough Download manager itself or i should use some other methods?
You can send message to the DownloadService you created, and invoke the DownloadManager to do the pause and resume action.
When DownloadManager enqueue a download task, you will get a id (long)
DownloadManager keep the download info in the ContentProvider, just update the ContentProvider info with the given id (long), if the network or other conditions satisfied the action will execute.
You can extends DownloadManager and create a pair of methods like below.
Pause Download
/**
* pause download
*
* #param ids the IDs of the downloads to be paused
* #return the number of downloads actually paused
*/
public int pauseDownload(long... ids) {
if (ids == null || ids.length == 0) {
// called with nothing to remove!
throw new IllegalArgumentException("input param 'ids' can't be null");
}
ContentValues values = new ContentValues();
values.put(Downloads.Impl.COLUMN_CONTROL, Downloads.Impl.CONTROL_PAUSED);
values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PAUSED_BY_APP);
if (ids.length == 1) {
return mResolver.update(ContentUris.withAppendedId(mBaseUri, ids[0]), values,
null, null);
}
return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),
getWhereArgsForIds(ids));
}
Resume download
/**
* resume download
*
* #param ids the IDs of the downloads to be resumed
* #return the number of downloads actually resumed
*/
public int resumeDownload(long... ids) {
if (ids == null || ids.length == 0) {
// called with nothing to remove!
throw new IllegalArgumentException("input param 'ids' can't be null");
}
ContentValues values = new ContentValues();
values.put(Downloads.Impl.COLUMN_CONTROL, Downloads.Impl.CONTROL_RUN);
values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_RUNNING);
if (ids.length == 1) {
return mResolver.update(ContentUris.withAppendedId(mBaseUri, ids[0]), values,
null, null);
}
return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),
getWhereArgsForIds(ids));
}

Getting "DownloadManager.STATUS_SUCCESSFUL" even after download not successful (when insufficient space)

I am always getting COLUMN_STATUS as STATUS_SUCCESSFUL even it fails due to insufficient space:
#Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
Utils.log(TAG, "Intent is NULL");
return;
}
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
DownloadManager downloadManager = (DownloadManager)
context.getSystemService(Context.DOWNLOAD_SERVICE);
long referenceId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, -1L);
if (downloadManager != null) {
DownloadManager.Query dmQuery = new DownloadManager.Query();
dmQuery.setFilterById(referenceId);
try (Cursor cursor = downloadManager.query(dmQuery)) {
if (cursor != null && cursor.getCount() > 0) {
// The error is here
int columnIndex =cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (cursor.moveToFirst() && cursor.getInt(columnIndex) == DownloadManager.STATUS_SUCCESSFUL) {
} else {
Log.e(TAG, "fail");
}
}
} catch (Exception exception) {
Log.e(TAG, exception);
}
}
}
}
If your connection timeouts, you will get FAILED.
If it fails due to insufficient space, check the query columns COLUMN_TOTAL_SIZE_BYTES and COLUMN_BYTES_DOWNLOADED_SO_FAR to check if equal.
int bytes_total = cur.getInt(cur.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
int bytes_downloaded = cur.getInt(cur.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));

PlaceHolder reason for Download Failure using Download Manager in Android

I am using Download Manager to download files of types(.mov, .pdf, .png). When I call download manager, download fails giving reason as Place holder. What does place holder mean and how do I fix this issue? Please help!
My code is as follows:
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrlFile))
.setDestinationInExternalFilesDir(context,
(Environment.DIRECTORY_DOWNLOADS), downloadFileName).setNotificationVisibility(visibility);
mEnqueue = downloadManager.enqueue(request);
mDownloadReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "DOWNLOAD_STATUS"+intent.getAction());
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
Query query = new Query();
query.setFilterById(mEnqueue);
Cursor c = downloadManager.query(query);
if (c.moveToFirst()) {
int columnIndex = c .getColumnIndex(DownloadManager.COLUMN_STATUS);
Log.d("getColumnIndex()", "Reason: " + c
.getColumnIndex(DownloadManager.COLUMN_STATUS)+DownloadManager.STATUS_SUCCESSFUL);
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
Log.d(TAG, "DOWNLOAD_STATUS_SUCCESSFUL");
} else if (DownloadManager.STATUS_FAILED == c.getInt(columnIndex)) {
Log.d("handleData()", "Reason: " + c.getString(c.getColumnIndex(DownloadManager.COLUMN_REASON)));
Log.d(TAG, "DOWNLOAD_STATUS_FAILED");
}
}
}
}
};
The problem is that the column "COLUMN_REASON" is an int and not a String (despite some examples I have seen that imply it is a string).
Hence you should be using:
Log.d("handleData()", "Reason: " + c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON)));
The value can be found:
Here
and
here

Why is this cursor empty?

I have for example button and when user click on it I want to find out the download history by DownloadManager, but problem is that my cursor is empty, it never goes to condition if(c.moveToFirst()), it always skip this condition.
DownloadManager downloadMgr = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterByStatus(DownloadManager.STATUS_FAILED|DownloadManager.STATUS_PENDING|DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_SUCCESSFUL);
Cursor c = downloadMgr.query(query);
if(c==null) {
//
}
else {
if(c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = c.getInt(columnIndex);
if(status == DownloadManager.STATUS_RUNNING){
//do something
}
}
}
I also tried this code (by imran khan) but still same problem:
DownloadManager.Query query = null;
Cursor c = null;
DownloadManager downloadManager = null;
downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
query = new DownloadManager.Query();
query.setFilterByStatus(DownloadManager.STATUS_FAILED|DownloadManager.STATUS_PENDING|DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_SUCCESSFUL);
c = downloadManager.query(query);
if(c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch(status) {
case DownloadManager.STATUS_PAUSED:
break;
case DownloadManager.STATUS_PENDING:
break;
case DownloadManager.STATUS_RUNNING:
break;
case DownloadManager.STATUS_SUCCESSFUL:
break;
case DownloadManager.STATUS_FAILED:
break;
}
}

Categories

Resources