Pausing and resuming a download - android

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));
}

Related

Download Speed is slow in Android

I have a list of PDFs that I need to download all PDFs in one click. I have implemented a foreground service to do the task. In this service I am enqueuing the list of PDFs in the Android DownloadManager's request to handle the downloads.
For the enqueue of request, I am inserting 6 PDF's in request for the first time and further when any one download completed I am inserting next PDF in the request list.
In this implementation the whole process is taking around 1-2 mins for the 91 PDFs(roughly size of 40MB in total). Is there any way, so we can speed up the download process.
This is the function to start Download queue
private void startDownloadQueue()
{
for(int i=0;i<6;i++){
if(i<hashMap.size()) {
listIndex++;
initiateDownload(documentList.get(i), positionList.get(i), hashMap.size());
}
}
}
private void initiateDownload(DocumentJsonModel.Document doc, int pos, int listSize)
{
if (doc != null && isDownloading) {
String position = String.valueOf(pos);
String docId = doc.id;
String docFile = doc.file;
String docName = doc.name;
String docDescription = doc.description;
boolean isJustView = false;
isFromSearch = false;
long id = downloadFile(doc, docId, docFile, docName, docDescription, position, isJustView, listSize);
if (id != 0) {
setProgressUpdate(id, Integer.parseInt(position), Integer.parseInt(docId), isJustView, doc, listSize);
} else if (isJustView) {
Intent intent1 = new Intent(INTENT_FILTER_ACTION_OPEN_DOC);
intent1.putExtra("docID",docId);
intent1.putExtra("position",pos);
intent1.putExtra("fromDownloadAll", true);
intent1.putExtra("docId", docId);
sendBroadcast(intent1);
stopForeground(true);
stopSelf();
} else if (isFromSearch) {
Intent intent1 = new Intent(INTENT_FILTER_ACTION_OPEN_DOC_FROM_SEARCH);
intent1.putExtra("fromDownloadAll", true);
intent1.putExtra("position", pos);
intent1.putExtra("docId", docId);
sendBroadcast(intent1);
stopForeground(true);
stopSelf();
}
}
}
Method to enqueue PDFs in download manager request queue -
public long downloadFile(DocumentJsonModel.Document doc,String docId, String docFile, String docName, String description, String position, boolean isJustView, int listSize) {
long downloadReference = 0;
String root = "/twoway/saved_documents/";
String BASE_DIR = getExternalFilesDir(null).getPath();
File dir = new File(BASE_DIR + root);
File file = new File(dir, docId + "_" + docFile);
if(!isCancelledButtonPressed) {
if (!file.exists()) {
String fileUrl = DOCUMENT_URL + docFile;
fileUrl = fileUrl.replaceAll(" ", "%20");
Uri fileUri = Uri.parse(fileUrl);
//Create request for android download manager
DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(fileUri);
//set title for download
request.setTitle(docName);
request.setVisibleInDownloadsUi(false);
//request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION);
//Setting description of request
request.setDescription(description);
request.setDestinationInExternalFilesDir(this, null, "/twoway/saved_documents/"
+ docId + "_" + docFile);
//Enqueue download and save into referenceId
downloadReference = downloadManager.enqueue(request);
}
}}

java.lang.NullPointerException: DatabaseHelperClass.DatabaseHelper splonline.Activity.spl.getDatabaseHelper()' on a null object reference

public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = MyFirebaseMessagingService.class.getSimpleName();
Context context;
int Different_id_everytime = 0;
Bitmap bitmap;
//when application is foreground push the notification
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d("msg", "onMessageReceived: " + remoteMessage.getData().get("Body"));
String strtitle = remoteMessage.getNotification().getTitle();
String strmessage = remoteMessage.getNotification().getBody();
String strimg = remoteMessage.getData().get("image");
bitmap = getBitmapfromUrl(strimg);
// String imageUri = remoteMessage.getData().get("image");
Different_id_everytime = Different_id_everytime + 1;
Intent intent = new Intent(this, FCMNotificationListActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, Different_id_everytime, intent, PendingIntent.FLAG_ONE_SHOT);
String channelId = "Default";
Uri defaultSounfUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(strtitle)
.setContentText(strmessage)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(bitmap))/*Notification with Image*/
.setAutoCancel(true)
.setSound(defaultSounfUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, "Default channel", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify( Different_id_everytime, notificationBuilder.build());
NotificationCompat.InboxStyle inboxStyle =
new NotificationCompat.InboxStyle();
String[] events = new String[6];
// Sets a title for the Inbox in expanded layout
//inboxStyle.setBigContentTitle("Event tracker details:");
// Moves events into the expanded layout
for (int i = 0; i < events.length; i++) {
inboxStyle.addLine(events[i]);
}
// Moves the expanded layout object into the notification object.
notificationBuilder.setStyle(inboxStyle);
// Issue the notification here.
notificationManager.notify(0,notificationBuilder.build());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
String title = remoteMessage.getNotification().getTitle();
String message = remoteMessage.getNotification().getBody();
String imageUri = remoteMessage.getData().get("image");
String strTitle = SessionManager.setMessage(context,title);
String strMessage = SessionManager.setTitle(context,message);
bitmap = getBitmapfromUrl(imageUri);
String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");
// sendNotification(message, bitmap,);
// create one model class to save push notification and error for null reference
try {
NotificationModel notificationModel = new NotificationModel();
notificationModel.setTitle(strtitle);
notificationModel.setMessage(strmessage);
notificationModel.setImage(imageUri);
spl.getInstance().getDatabaseHelper().insertNotification(notificationModel);
}catch(Exception e){
e.printStackTrace();
}
sendNotification(message,title,bitmap,TrueOrFlase);
if (TextUtils.isEmpty(title)){
title = getString(R.string.app_name);
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
}
// when application is in background push the notification
private void sendNotification(String message, String title,Bitmap image, String TrueOrFalse) {
Intent intent = new Intent(this, FCMNotificationListActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("KEY_ISNOTIFICATION", true);
intent.putExtra("title",title);
intent.putExtra("message",message);
intent.putExtra("AnotherActivity", TrueOrFalse);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(image))/*Notification with Image*/
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Different_id_everytime, notificationBuilder.build());
// to show inbox style notification
NotificationCompat.InboxStyle inboxStyle =
new NotificationCompat.InboxStyle();
String[] events = new String[6];
// Sets a title for the Inbox in expanded layout
//inboxStyle.setBigContentTitle("Event tracker details:");
// Moves events into the expanded layout
for (int i = 0; i < events.length; i++) {
inboxStyle.addLine(events[i]);
}
// Moves the expanded layout object into the notification object.
//mBuilder.setStyle(inBoxStyle);
notificationBuilder.setStyle(inboxStyle);
// Issue the notification here.
//mNotificationManager.notify(mId, mBuilder.build());
notificationManager.notify(Different_id_everytime,notificationBuilder.build());
}
// to show image in notification
/*
*To get a Bitmap image from the URL received
* */
public Bitmap getBitmapfromUrl(String imageUrl) {
try {
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
return bitmap;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
//to save data in database
public class spl extends Application {
private SharedPreferences sharedPreferences;
private DatabaseHelper databaseHelper;
private static spl sInstance;
private static AppCompatActivity sActivity;
public static AppCompatActivity getsActivity() {
return sActivity;
}
public static void setsActivity(AppCompatActivity sActivity) {
spl.sActivity = sActivity;
}
#Override
public void onCreate() {
super.onCreate();
sharedPreferences = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
databaseHelper = new DatabaseHelper(getApplicationContext());
databaseHelper.openDataBase();
sInstance = this;
// if (Utils.isInternetAvail(getApplicationContext())) {
// Intent intent = new Intent(getApplicationContext(), StateService.class);
// startService(intent);
// }
}
public static spl getInstance() {
return sInstance;
}
public DatabaseHelper getDatabaseHelper() {
return databaseHelper;
}
public SharedPreferences getSharedPreferences() {
return sharedPreferences;
}
public void setSharedPreferences(SharedPreferences sharedPreferences) {
this.sharedPreferences = sharedPreferences;
}
}
//Databse helperclass
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = DatabaseHelper.class.getSimpleName();
private Context context;
private SQLiteDatabase database;
/**
* Constructor
* *
*/
public DatabaseHelper(Context context) {
super(context, DBUtils.DATABASE_NAME, null, DBUtils.DATABASE_VERSION);
this.context = context;
}
/**
* Create database tables if it does not exists.
* *
*/
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DBUtils.DB_CREATE_NOTIFICATION_TABLE);
this.database = db;
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
/**
* Open Databases
* *
*/
public void openDataBase() throws SQLException {
database = this.getWritableDatabase();
}
#Override
public synchronized void close() {
// if (database != null && database.isOpen())
// database.close();
// super.close();
}
/**
* Insert NotificationList
*
* #param
*/
public void insertNotification(NotificationModel notificationModel) {
if (!database.isOpen()) {
openDataBase();
}
try {
// database.beginTransaction();
ContentValues values = new ContentValues();
values.put(DBUtils.COLUMN_NOTIFICATION_MESSAGE, notificationModel.getMessage());
values.put(DBUtils.COLUMN_NOTIFICATION_TITLE, notificationModel.getTitle());
values.put(DBUtils.COLUMN_NOTIFICATION_IMAGE, notificationModel.getImage());
database.insert(DBUtils.NOTIFICATION_TABLE, null, values);
} catch (Exception e) {
e.printStackTrace();
} finally {
close();
SQLiteDatabase.releaseMemory();
}
}
/**
* Delete from Notificaton
*/
public void deleteNotification() {
if (!database.isOpen()) {
openDataBase();
}
try {
database.delete(DBUtils.NOTIFICATION_TABLE, null, null);
} catch (Exception e) {
e.printStackTrace();
} finally {
close();
}
}
/**
* Get NotificationList
*
* #return
*/
public ArrayList<NotificationModel> getNotificationList() {
final ArrayList<NotificationModel> notificationlist = new ArrayList<NotificationModel>();
if (!database.isOpen()) {
openDataBase();
}
Cursor cursor = null;
try {
cursor = database.query(DBUtils.NOTIFICATION_TABLE, new String[]{"*"}, null, null, null, null, DBUtils.COLUMN_NOTIFICATION_ID + " DESC");
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
NotificationModel notificationModel=new NotificationModel();
notificationModel.setTitle(cursor.getString(cursor.getColumnIndex(DBUtils.COLUMN_NOTIFICATION_TITLE)));
notificationModel.setMessage(cursor.getString(cursor.getColumnIndex(DBUtils.COLUMN_NOTIFICATION_MESSAGE)));
notificationModel.setImage(cursor.getString(cursor.getColumnIndex(DBUtils.COLUMN_NOTIFICATION_IMAGE)));
notificationlist.add(notificationModel);
cursor.moveToNext();
}
notificationlist.trimToSize();
}
} catch (Exception e) {
} finally {
close();
if (cursor != null) {
cursor.close();
SQLiteDatabase.releaseMemory();
}
}
return notificationlist;
}
}

How to perform multiple download operations from a single Intent Service with progress update of each operation

I have written code for downloading images through Intent Service
public class UIIntentService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
*/
public UIIntentService() {
super("UIIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
downLoadManager();
}
private void downLoadManager() {
// Starting download manager
final DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse("http://some_url/xyz.jpg"));
MainActivity.enqueue = manager.enqueue(request);
scheduleAlarm(MainActivity.enqueue);
}
public void scheduleAlarm(long id) {
Intent intent = new Intent(getBaseContext(), com.example.com.downloaddemo.DisplayInoker.class);
intent.putExtra("ID", ""+id);
final PendingIntent pIntent = PendingIntent.getBroadcast(getBaseContext(), com.example.com.downloaddemo.DisplayInoker.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis(); // alarm is set right away
AlarmManager alarm = (AlarmManager) getBaseContext().getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
3000, pIntent);
}
}
My BroadcastReceiver for AlarmManager
public class DisplayInoker extends BroadcastReceiver{
public static final int REQUEST_CODE = 12345;
public static final String ACTION = "DISPLAYRESULT";
private long enqueue;
// Triggered by the Alarm periodically
#Override
public void onReceive(Context context, Intent intent) {
EventBus bus = EventBus.getDefault();
if(intent.getExtras().getString("ID") != null) {
enqueue = Long.parseLong("" + intent.getExtras().getString("ID"));
Log.d("Innnnnnnnnnnnnnnnnnnnnn", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
final DownloadManager manager = (DownloadManager) context.getSystemService(context.DOWNLOAD_SERVICE);
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(enqueue);
Cursor cursor = manager.query(q);
cursor.moveToFirst();
double bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
double bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
double percentComplete = 0;
// checking whether file downloaded or not
boolean downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
== DownloadManager.STATUS_SUCCESSFUL ? true : false;
cursor.close();
boolean stopDisplaying = false;
if (!downloaded) {
try {
percentComplete = (bytes_downloaded / bytes_total) * 100;
bus.post("" + (int) percentComplete);
} catch (Exception e) {
percentComplete = 0;
e.printStackTrace();
}
} else {
Log.d("completed", "////////////////////// end ///////////////////////////" + bytes_total + " " + bytes_downloaded);
percentComplete = (bytes_downloaded / bytes_total) * 100;
bus.post("" + (int) percentComplete);
}
}
}
}
Calling my Intent service simply
Intent intentservice = new Intent(MainActivity.this, UIIntentService.class);
startService(intentservice);
This code is working fine and I am receiving progress updates of single download operation.
Now, I want to use this IntentService to perform multiple download operations with progress update of each operation. can you please check whether is it possible through this code or provide some other alternative solution.
Thanks in advance.
Using Handler you can achieve the result.
Please see here.

Download Manager failed the download

I am using DownloadManager to download the following url:
http://dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/November%202013/Yo%20Yo%20Honey%20Singh%20-%20Blue%20Eyes-[DJKANG.Com].mp3
But the downloading is failed. I even hit the url on browser and it works properly. Is it the problem of url parsing?
Code: DDownloadService.java
public class DDownloadService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
Context conte;
// NotificationManager notificationManager;
// NotificationCompat.Builder mBuilder;
boolean playing = false;
Runnable runnable;
SharedPreferences pre;
static int countOfCurrent = 0;
String downloadName, downloadUrl;
NotificationManager notificationManager;
NotificationCompat.Builder mBuilder;
// ..
static int downloadNumber = 0;
DownloadManager mgr[] = new DownloadManager[100];
long downloadIds[] = new long[100];
BroadcastReceiver cancelDownload;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
downloadNumber++;
downloadName = pre.getString("downloadname", "");
downloadName = viewSD(downloadName);
downloadUrl = pre.getString("downloadurl", "");
downloadName = downloadName.toLowerCase();
pre.edit()
.putString(
"songsInDownload",
pre.getString("songsInDownload", "") + "|"
+ downloadName).commit();
pre.edit().putInt(downloadName + "no", +downloadNumber).commit();
mgr[downloadNumber] = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
try {
countOfCurrent++;
downloadIds[downloadNumber] = mgr[downloadNumber]
.enqueue(new DownloadManager.Request(Uri
.parse(downloadUrl))
.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("Downloading")
.setDescription(downloadName)
.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_HIDDEN)
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_MUSIC,
downloadName)
.setVisibleInDownloadsUi(false));
pre.edit()
.putLong(downloadName + "id",
downloadIds[downloadNumber]).commit();
Timer myTimer = new Timer();
myTimer.schedule(new RegrowCornAnimate(downloadNumber,
downloadName), 0, 10);
} catch (IllegalStateException e) {
Toast.makeText(getBaseContext(), "No storage found!",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (Exception e) {
Toast.makeText(getBaseContext(), " Something wrong happened!",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
#Override
public void onCreate() {
conte = this;
pre = getSharedPreferences("download", 0);
downloadName = pre.getString("downloadname", "");
downloadUrl = pre.getString("downloadurl", "");
cancelDownload = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
try {
mgr[pre.getInt(arg1.getExtras().getString("name") + "no", 0)]
.remove(pre.getLong(
arg1.getExtras().getString("name") + "id",
0));
} catch (Exception e) {
e.printStackTrace();
}
}
};
registerReceiver(cancelDownload, new IntentFilter("cancelIt"));
notificationManager = (NotificationManager) conte
.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(conte)
.setSmallIcon(R.drawable.icon)
.setContentTitle("Downloading in progress").setContentText("");
startForeground(55, mBuilder.build());
notificationManager.cancel(55);
HandlerThread thread = new HandlerThread("ServiceStartArguments", 0);
// //..................
// notificationManager = (NotificationManager) conte
// .getSystemService(Context.NOTIFICATION_SERVICE);
// mBuilder = new NotificationCompat.Builder(conte);
// RemoteViews remoteViews = new RemoteViews(getPackageName(),
// R.layout.notification_layout);
// try {
// mBuilder.setSmallIcon(R.drawable.icon);
// mBuilder.setAutoCancel(false).setOngoing(true)
// .setContent(remoteViews);
// Uri uri = RingtoneManager
// .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// mBuilder.setSound(uri);
// notificationManager.notify(Mp3Constants.NOTIFICATION_NUMBER,
// mBuilder.build());
// } catch (Exception e) {
// e.printStackTrace();
// }
// //...................
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// online = intent.getExtras().getString("online");
// link = intent.getExtras().getString("link");
// name = intent.getExtras().getString("name");
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(cancelDownload);
}
class RegrowCornAnimate extends TimerTask {
private final int serial;
private final String name_of_da;
boolean startFlag = true, errorFlag = true;
RegrowCornAnimate(int serial, String name) {
this.serial = serial;
this.name_of_da = name;
}
public void run() {
// Do stuff
int dl_progress = 0;
try {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadIds[serial]);
Cursor c = mgr[serial].query(q);
c.moveToFirst();
long bytes_downloaded = c
.getInt(c
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
long bytes_total = c
.getInt(c
.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
dl_progress = (int) ((bytes_downloaded * 100) / bytes_total);
pre.edit().putInt(name_of_da, dl_progress).commit();
switch (c.getInt(c
.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
case DownloadManager.STATUS_FAILED:
// msg = "Download failed!";
// Toast.makeText(getBaseContext(), "Url Broken!",
// Toast.LENGTH_SHORT).show();
sendNotification(1, serial, name_of_da, dl_progress);
this.cancel();
countOfCurrent--;
if (countOfCurrent == 0)
stopSelf();
break;
case DownloadManager.STATUS_PAUSED:
// msg = "Download paused!";
if (errorFlag) {
errorFlag = false;
sendNotification(7, serial, name_of_da, dl_progress);
}
break;
case DownloadManager.STATUS_PENDING:
// msg = "Download pending!";
sendNotification(0, serial, name_of_da, dl_progress);
break;
case DownloadManager.STATUS_RUNNING:
// msg = "Download in progress!";
errorFlag = true;
if (startFlag) {
if (verifyFromSD(name_of_da)) {
startFlag = false;
sendBroadcast(new Intent("start"));
}
}
sendNotification(0, serial, name_of_da, dl_progress);
break;
case DownloadManager.STATUS_SUCCESSFUL:
// msg = "Download complete!";
pre.edit()
.putString(
"songsInDownload",
pre.getString("songsInDownload", "")
.replace("|" + name_of_da, ""))
.commit();
pre.edit().putInt(name_of_da, 100);
sendNotification(0, serial, name_of_da, dl_progress);
this.cancel();
countOfCurrent--;
if (countOfCurrent == 0)
stopSelf();
break;
default:
// msg = "Download is nowhere in sight";
sendNotification(10, serial, name_of_da, dl_progress);
this.cancel();
countOfCurrent--;
if (countOfCurrent == 0)
stopSelf();
break;
}
c.close();
} catch (Exception e) {
e.printStackTrace();
sendNotification(7, serial, name_of_da, dl_progress);
cancel();
countOfCurrent--;
if (countOfCurrent == 0)
stopSelf();
}
}
}
public void sendNotification(int tmout, int nin, String name, int progress) {
if (tmout == 0) {
// notificationManager.notify(nin, mBuilder.build());
if (progress >= 100) {
// notificationManager.cancel(nin);
mBuilder.setSmallIcon(R.drawable.icon)
.setContentTitle("Completed").setContentText(name)
.setAutoCancel(true).setOngoing(false)
.setProgress(100, 100, false);
Uri ttt = Uri.parse(Environment.getExternalStorageDirectory()
.toString() + "/Music/" + name);
pre.edit().putInt("retry", 1).commit();
Intent inten = new Intent(Intent.ACTION_VIEW, ttt);
String arr[] = name.split("\\.");
inten.setDataAndType(ttt, "audio/" + arr[arr.length - 1]);
PendingIntent i = PendingIntent.getActivity(getBaseContext(),
0, inten, 0);
mBuilder.setContentIntent(i);
notificationManager.notify(nin, mBuilder.build());
} else {
mBuilder.setContentTitle("Downloading: " + name)
.setContentText(progress + " %")
.setSmallIcon(R.drawable.icon).setAutoCancel(false)
.setOngoing(true);
mBuilder.setProgress(100, progress, false);
notificationManager.notify(nin, mBuilder.build());
}
} else {
if (tmout == 1) {
mBuilder.setSmallIcon(R.drawable.icon)
.setContentTitle("Failed: " + name)
.setContentText(progress + " %").setAutoCancel(true)
.setProgress(100, progress, false).setOngoing(false);
// Intent intnt = new Intent(Mp3Constants.NOTIFICATION);
// intnt.putExtra("resume", "1");
// intnt.putExtra("url", urlD);
// intnt.putExtra("name", name);
// intnt.putExtra("nin", nin);
// PendingIntent i = PendingIntent
// .getBroadcast(conte, 0, intnt, 0);
// mBuilder.setContentIntent(i);
} else if (tmout == 7) {
mBuilder.setSmallIcon(R.drawable.icon)
.setContentTitle("Cancelled: " + name)
.setAutoCancel(true).setProgress(100, progress, false)
.setOngoing(false);
// Intent intnt = new Intent(Mp3Constants.NOTIFICATION);
// intnt.putExtra("resume", "1");
// intnt.putExtra("url", urlD);
// intnt.putExtra("name", name);
// intnt.putExtra("nin", nin);
// PendingIntent i = PendingIntent
// .getBroadcast(conte, 0, intnt, 0);
// mBuilder.setContentIntent(i);
} else {
mBuilder.setSmallIcon(R.drawable.icon)
.setContentTitle("Interrupted: " + name)
.setContentText("No storage found").setAutoCancel(true)
.setOngoing(false);
}
notificationManager.notify(nin, mBuilder.build());
}
}
private String viewSD(String naame) {
File f = new File(Environment.getExternalStorageDirectory().toString()
+ "/Music");
File[] files = f.listFiles();
if (files == null) {
return naame;
}
while (true) {
String newName = naame;
naame = relooper(files, newName);
if (newName.equals(naame))
break;
}
return naame;
}
public String relooper(File[] files, String name) {
int send = files.length;
for (int i = 0; i < send; i++) {
File file = files[i];
String myfile = file
.getPath()
.substring(file.getPath().lastIndexOf("/") + 1,
file.getPath().length()).toLowerCase();
if (name.equalsIgnoreCase(myfile))
return "copy_of_" + name;
}
return name;
}
private boolean verifyFromSD(String naame) {
File f = new File(Environment.getExternalStorageDirectory().toString()
+ "/Music");
File[] files = f.listFiles();
if (files == null) {
return false;
}
int send = files.length;
for (int i = 0; i < send; i++) {
File file = files[i];
String myfile = file
.getPath()
.substring(file.getPath().lastIndexOf("/") + 1,
file.getPath().length()).toLowerCase();
if (naame.equalsIgnoreCase(myfile))
return true;
}
return false;
}
}
EDIT: I found the problem from logcat:
01-07 11:47:37.313: W/DownloadManager(18893): Exception for id 285: Illegal character in path at index 115: http://dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/November%202013/Yo%20Yo%20Honey%20Singh%20-%20Blue%20Eyes-[DJKANG.Com].mp3
01-07 11:47:37.313: W/DownloadManager(18893): java.lang.IllegalArgumentException: Illegal character in path at index 115: http://dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/November%202013/Yo%20Yo%20Honey%20Singh%20-%20Blue%20Eyes-[DJKANG.Com].mp3
01-07 11:47:37.313: W/DownloadManager(18893): at java.net.URI.create(URI.java:727)
01-07 11:47:37.313: W/DownloadManager(18893): at android.net.Proxy.getProxy(Proxy.java:113)
01-07 11:47:37.313: W/DownloadManager(18893): at android.net.Proxy.getPreferredHttpHost(Proxy.java:218)
01-07 11:47:37.313: W/DownloadManager(18893): at com.android.providers.downloads.DownloadThread.run(DownloadThread.java:174)
But I still need to know which format to use to parse url for DownloadManager.
The IllegalArgumentException occurs when the URL contains illegal characters such as [ ]. As mentioned in the comments, you need to encode such characters using URLEncoder.
I implemented it this way in my code -
private String checkUrl(String url) {
if(url.contains("[")) {
String[] a = url.split("\\[");
String b = "[" + a[1]; //contains text after [ e.g. [DJKANG.Com].mp3
url = a[0] + URLEncoder.encode(b, "UTF-8"); // encodes illegal characters
}
return url;
}

Android: detect when app is installed

I am trying to download an Android app from a server using the DownloadManager class, install it and then detect when the installation is completed. I am using two receivers: one to detect the download process and the other to detect the install process. The first receiver works properly, but the second doesn't. What I am doing wrong?
DownloadManager dm = (DownloadManager) DownloadApplicationActivity.this.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request req = new DownloadManager.Request(Uri.parse(MY_LINK));
req.setTitle(MY_TITLE)
.setDescription("Downloading ....")
// download the package to the /sdcard/downlaod path.
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
MY_PATH);
long enqueue = dm.enqueue(req);
BroadcastReceiver receiver= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
Query query = new Query();
query.setFilterById(enqueue);
Cursor c =dm.query(query);
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
// show a notification bar.
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon,"",System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_NO_CLEAR;
Intent i = new Intent(Intent.ACTION_VIEW);
// when the notification is clicked, install the app.
i.setDataAndType(Uri.fromFile(new File(Environment
.getExternalStorageDirectory() + APP_PATH)),"application/vnd.android.package-archive");
PendingIntent pendingIntent = PendingIntent.getActivity(
activity, 0, i, 0);
notification.setLatestEventInfo(activity, MY_TEXT, MY_TEXT,pendingIntent);
notification.number += 1;
notificationManager.notify( 0, notification);
//i want to detect the app's installation, I register a ne receiver
registerReceiver(installReceiver,new IntentFilter(Intent.ACTION_PACKAGE_ADDED));
}
}
};
BroadcastReceiver installReceiver= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
Uri data = intent.getData();
String packageName = data.getEncodedSchemeSpecificPart();
Log.i("The installed package is: ", "" + packageName);
}
}
};
I solved my problem, I added
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_INSTALL);
intentFilter.addDataScheme("package");
before the line :
registerReceiver(installReceiver, intentFilter);
You can try the code below. This way you can get all activities that can be called by an intent and if you know the activity name and it is present in list retrieved by queryIntentActivities()..you know it is installed.
public void callQrScan()
{
Intent intent1 = new Intent("com.google.zxing.client.android.SCAN");
if(isCallable(intent1)== true){
Context context = getApplicationContext();
CharSequence text = "Scan Niet Gelukt";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
else{
Context context = getApplicationContext();
CharSequence text = "Scan Niet Gelukt";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
Button tempbutton = (Button)findViewById(R.id.Button03);
tempbutton.setOnClickListener(new OnClickListener()
{
public void onClick(final View v)
{
callQrScan();
}
});
}
private boolean isCallable(Intent intent1) {
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent1,
PackageManager.MATCH_DEFAULT_ONLY);
if(list.size() > 0)
return true ;
else
return false;
}
Hope it helps :)

Categories

Resources