I have a activity with recycler-view, and each list item has a download button.inside button click event i manage make call for download-service.so how can i manage queue when user click more than one download button with custom notification update.
I have googled and tried some solutions are:
1.How to Manage Queue of Runnable Tasks in Android
2.how to handle a queue in android?? java
3.Best way to update Activity from a Queue
but doesn't find the correct way to implement queue with notification update.
Here is my DownloadService Code:
public class DownloadApkService extends Service {
private NotificationCompat.Builder notificationBuilder;
private NotificationManager notificationManager;
String downloadLocation;
String appId = null;
String appLink = null;
String appName = null;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Queue", "queue");
appId = intent.getStringExtra(Constants.COM_APP_ID);
appLink = intent.getStringExtra(Constants.COM_APP_LINK);
appName = intent.getStringExtra(Constants.COM_APP_NAME);
Thread thread=new Thread(new MyThread(startId));
thread.start();
return START_STICKY;
}
final class MyThread implements Runnable {
int service_id;
MyThread(int service_id) {
this.service_id = service_id;
}
#Override
public void run() {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(DownloadApkService.this)
.setSmallIcon(R.drawable.ic_list_app_icon)
.setContentTitle(appName).setProgress(0, 0, true)
.setContentText("Downloading APK")
.setOngoing(true)
.setAutoCancel(true);
notificationManager.notify(0, notificationBuilder.build());
downloadApk();
}
}
private void downloadApk() {
downloadLocation = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = appName + ".apk";
downloadLocation += fileName;
File sourceFile = new File(downloadLocation);
if (sourceFile.exists()) {
sourceFile.delete();
}
Intent intentResponse = new Intent();
intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
intentResponse.putExtra(Constants.COM_APP_ID, appId);
intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, "0");
sendBroadcast(intentResponse);
new DownloadFileFromURL().execute(appLink);
}
public void installApk(Uri uri) {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.setDataAndType(uri,
"application/vnd.android.package-archive");
DownloadApkService.this.startActivity(install);
}
/**
* Background Async Task to download file
*/
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* Downloading file in background thread
*/
#Override
protected String doInBackground(String... f_url) {
int count;
try {
Log.e("ULR", f_url[0]);
URL url = new URL(f_url[0].trim());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = connection.getContentLength();
Log.e("Length", lenghtOfFile + "");
// download the file
InputStream input = connection.getInputStream();
downloadLocation = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = appName + ".apk";
downloadLocation += fileName;
// Output stream
FileOutputStream output = new FileOutputStream(downloadLocation);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getStackTrace().toString());
}
return null;
}
/**
* Updating progress bar
*/
protected void onProgressUpdate(String... progress) {
// setting progress percentage
Intent intentResponse = new Intent();
intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
intentResponse.putExtra(Constants.COM_APP_ID, appId);
intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, progress[0]);
sendBroadcast(intentResponse);
}
/**
* After completing background task Dismiss the progress dialog
**/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
notificationManager.cancel(0);
installApk(Uri.fromFile(new File(downloadLocation)));
}
}
}
any help would be appriciated...
Finally got answer for my own question.
I managed it with Queue class that is in java.util package.
The code i have been used is below:
public class DownloadApkService extends Service {
private NotificationManager notificationManager = null;
String downloadLocation;
String appId = null;
String appLink = null;
String appName = null;
String isApkFromServer = null;
public boolean isDownloading = false;
public static Queue<QueueData> downloadQueue = new LinkedList<>();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (isDownloading) {
QueueData queueData = new QueueData();
queueData.setAppId(intent.getStringExtra(Constants.COM_APP_ID));
queueData.setAppLink(intent.getStringExtra(Constants.COM_APP_LINK));
queueData.setIsApkFromServer(intent.getStringExtra(Constants.COM_APK_FROM_SERVER));
queueData.setAppName(intent.getStringExtra(Constants.COM_APP_NAME));
downloadQueue.add(queueData);
Intent intentQueueingApk = new Intent();
intentQueueingApk.setAction(Constants.ACTION_QUEUEING_APK);
sendBroadcast(intentQueueingApk);
return START_NOT_STICKY;
} else {
appId = intent.getStringExtra(Constants.COM_APP_ID);
appLink = intent.getStringExtra(Constants.COM_APP_LINK);
appName = intent.getStringExtra(Constants.COM_APP_NAME);
isApkFromServer = intent.getStringExtra(Constants.COM_APK_FROM_SERVER);
}
Thread thread = new Thread(new MyThread());
thread.start();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (notificationManager != null) {
notificationManager.cancel(0);
}
}
class MyThread implements Runnable {
MyThread() {
}
#Override
public void run() {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(DownloadApkService.this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(appName).setProgress(0, 0, true)
.setContentText(getResources().getText(R.string.downloading_notification))
.setOngoing(true)
.setAutoCancel(true);
notificationManager.notify(0, notificationBuilder.build());
new DownloadFileFromURL().execute(appLink);
}
}
public void installApk(Uri uri) {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.setDataAndType(uri,
"application/vnd.android.package-archive");
DownloadApkService.this.startActivity(install);
}
/**
* Background Async Task to download file
*/
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
isDownloading = true;
Intent intentResponse = new Intent();
intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
intentResponse.putExtra(Constants.COM_APP_ID, appId);
intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, "0");
sendBroadcast(intentResponse);
}
/**
* Downloading file in background thread
*/
#Override
protected String doInBackground(String... f_url) {
int count;
HttpURLConnection connection=null;
try {
String link=f_url[0].replace(" ","%20");
URL url = new URL(link);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Encoding", "identity");
int lenghtOfFile = connection.getContentLength();
connection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
// download the file
InputStream input = new BufferedInputStream(connection.getInputStream());
downloadLocation = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = appName + ".apk";
downloadLocation += fileName;
File sourceFile = new File(downloadLocation);
if (sourceFile.exists()) {
sourceFile.delete();
}
// Output stream
FileOutputStream output = new FileOutputStream(downloadLocation);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
return "fail";
}finally {
if(connection != null)
connection.disconnect();
}
return "success";
}
/**
* Updating progress bar
*/
protected void onProgressUpdate(String... progress) {
// setting progress percentage
Intent intentResponse = new Intent();
intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK);
intentResponse.putExtra(Constants.COM_APP_ID, appId);
intentResponse.putExtra(Constants.COM_APK_DOWNLOAD_PERCENTAGE, progress[0]);
sendBroadcast(intentResponse);
Intent intentQueueingApk = new Intent();
intentQueueingApk.setAction(Constants.ACTION_QUEUEING_APK);
sendBroadcast(intentQueueingApk);
}
/**
* After completing background task Dismiss the progress dialog
**/
#Override
protected void onPostExecute(String file_url) {
notificationManager.cancel(0);
if (file_url.equals("success")) {
Intent intentResponse = new Intent();
intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK_COMPLETE);
intentResponse.putExtra(Constants.COM_APP_ID, appId);
sendBroadcast(intentResponse);
isDownloading = false;
if (isApkFromServer!=null && isApkFromServer.equals("0")) {
Intent intent = new Intent(DownloadApkService.this, UploadApkService.class);
intent.putExtra(Constants.COM_APP_ID, mAppDetails.getId());
intent.putExtra(Constants.COM_APK_FILE_PATH, downloadLocation);
startService(intent);
}
installApk(Uri.fromFile(new File(downloadLocation)));
} else if (file_url.equals("fail")) {
isDownloading = false;
Intent intentResponse = new Intent();
intentResponse.setAction(Constants.ACTION_DOWNLOADING_APK_FAILED);
intentResponse.putExtra(Constants.COM_APP_ID, appId);
sendBroadcast(intentResponse);
}
if (/*isDownloading &&*/ !downloadQueue.isEmpty()) {
QueueData queueData = downloadQueue.poll();
appId = queueData.getAppId();
appLink = queueData.getAppLink();
appName = queueData.getAppName();
isApkFromServer = queueData.getIsApkFromServer();
Thread thread = new Thread(new MyThread());
thread.start();
}
}
}
#Override
public void onTaskRemoved(Intent rootIntent) {
if (notificationManager != null)
notificationManager.cancel(0);
}
}
I hope it's going to be helpful for someone.
Related
I am using service to download a file , but if I clear the app from recent app list then download stopped . I tried running the service as foreground but no luck . How can I achieve it ? Download multiple files in queue , even after remove the app from recent task .
public class ApkDownloadService extends Service {
public static final String EXTRA_APP_DETAILS = ApkDownloadService.class.getName().concat("_app_details");
int NOTIFICATION_ID = ((Number) System.currentTimeMillis()).intValue();
private String TAG = "ApkDownloadService";
String appId;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
NotificationManagerCompat notificationManager;
NotificationCompat.Builder mBuilder;
// Issue the initial notification with zero progress
int PROGRESS_MAX = 100;
int PROGRESS_CURRENT = 0;
int fileLength;
#Override
public void onCreate() {
super.onCreate();
notificationManager = NotificationManagerCompat.from(this);
Log.d(TAG,"onCreate");
}
#Override
public void onDestroy() {
notificationManager.cancel(NOTIFICATION_ID);
Log.d(TAG,"onDestroy");
super.onDestroy();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
notificationManager.cancel(NOTIFICATION_ID);
Log.d(TAG,"onTaskRemoved");
super.onTaskRemoved(rootIntent);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG,"onBind");
return null;
}
#Override
public boolean onUnbind(Intent intent) {
Log.d(TAG,"onUnbind");
return super.onUnbind(intent);
}
#SuppressLint("StaticFieldLeak")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
assert intent != null;
Result result = intent.getParcelableExtra(EXTRA_APP_DETAILS);
Log.d(TAG,"onStartCommand");
appId = result.getApplicationId();
mBuilder = new NotificationCompat.Builder(this, appId);
mBuilder.setContentTitle(result.getName())
.setContentText("Download in progress")
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(NotificationCompat.PRIORITY_LOW);
mBuilder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
startForeground((int) result.getId(), mBuilder.build());
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
URL url;
try {
url = new URL(result.getPackage().getApk());
URLConnection conection = url.openConnection();
conection.connect();
fileLength = conection.getContentLength();
long total = 0;
int count, tmpPercentage = 0;
InputStream input = url.openStream();
byte[] chunk = new byte[4096];
while ((count = input.read(chunk)) != -1) {
total += count;
outputStream.write(chunk, 0, count);
PROGRESS_CURRENT = (int) ((total * 100) / fileLength);
if (PROGRESS_CURRENT > tmpPercentage) {
EventBus.getDefault().post(String.valueOf(PROGRESS_CURRENT)); // Posting download percentage
mBuilder.setContentText(PROGRESS_CURRENT + "%");
mBuilder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManager.notify(NOTIFICATION_ID, mBuilder.build());
tmpPercentage = PROGRESS_CURRENT;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
#Override
protected void onCancelled() {
super.onCancelled();
Log.d(TAG,"onCancelled");
}
}.execute();
return START_REDELIVER_INTENT;
}
}
I am not sure what is wrong with my foreground service . If I clear the app from recent task , download stops .
This is my code. When i click download button, it download twice. How to stop second time downloading? Please help me to prevent second time downloading.
this my button click listener:
downloadPackage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
downloadPackage.setEnabled(false);
SharedPreferences.Editor editor = getSharedPreferences("SETID", MODE_PRIVATE).edit();
editor.putInt("setId", setId);
editor.commit();
Intent intent = new Intent(ReadingListeningTestActivity.this, DownloadService.class);
startService(intent);
}
});
this is my
Download Service:
public class DownloadService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private NotificationManager notificationManager;
private NotificationCompat.Builder notificationBuilder;
private int totalFileSize;
SharedPreferences prefs;
private boolean isDownloading = false;
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
prefs = getSharedPreferences("SETID", MODE_PRIVATE);
int setId = prefs.getInt("setId", 0);
Log.d("SEtID", setId + "");
if (isDownloading) {
return;
} else {
Log.d("Download", "isDownloading: " + isDownloading);
isDownloading = true;
initDownload(setId);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
private void initDownload(int setId) {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(data.getTitle())
.setContentText("Downloading File")
.setAutoCancel(true);
notificationManager.notify(0, notificationBuilder.build());
downloadFileTest("test.zip");
return null;
}
}.execute();
}
private void downloadFileTest(String uri) {
int count;
InputStream stream = null;
OutputStream output = null;
HttpURLConnection connection = null;
String fileName = packageName(uri);
try {
URL url = new URL(Application.BASE_URL + uri);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return;
}
byte data[] = new byte[4096];
long fileSize = connection.getContentLength();
stream = new BufferedInputStream(connection.getInputStream());
File outputFile = getCacheDir(fileName + ".part");
output = new FileOutputStream(outputFile);
try {
long total = 0;
long startTime = System.currentTimeMillis();
int timeCount = 1;
while ((count = stream.read(data)) != -1) {
total += count;
totalFileSize = (int) (fileSize / (Math.pow(1024, 2)));
double current = Math.round(total / (Math.pow(1021, 2)));
int progress = (int) ((total * 100) / fileSize);
long currentTime = System.currentTimeMillis() - startTime;
Download download = new Download();
download.setTotalFileSize(totalFileSize);
if (currentTime > 1000 * timeCount) {
download.setCurrentFileSize((int) current);
download.setProgress(progress);
sendNotification(download);
timeCount++;
}
output.write(data, 0, count);
}
} catch (IOException e) {
isDownloading = false;
prefs.edit().clear().commit();
outputFile.delete();
onErrorDownload("Internet Connection Problem Retry Download");
} finally {
isDownloading = false;
prefs.edit().clear().commit();
File originalName = getCacheDir(fileName);
if (originalName.exists()) {
outputFile.delete();
throw new IOException("file exists");
}
boolean success = outputFile.renameTo(originalName);
if (success) {
if (connection != null)
connection.disconnect();
onDownloadComplete();
output.flush();
output.close();
stream.close();
}
}
} catch (IOException e) {
isDownloading = false;
prefs.edit().clear().commit();
Log.d("Test", "Main");
if (e.getMessage().equals("file exists"))
onErrorDownload("Package Already Exists");
else
onErrorDownload("Internet Connection Problem Retry Download");
}
}
private void onDownloadComplete() {
Download download = new Download();
download.setProgress(100);
sendIntent(download);
notificationManager.cancel(0);
notificationBuilder.setOngoing(false);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder.setContentText("File Downloaded");
notificationManager.notify(0, notificationBuilder.build());
}
private void onErrorDownload(String message) {
Download download = new Download();
download.setProgress(download.getProgress());
sendIntent(download);
notificationManager.cancel(0);
notificationBuilder.setOngoing(false);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder.setContentText(message);
notificationManager.notify(0, notificationBuilder.build());
}
private void sendNotification(Download download) {
sendIntent(download);
notificationBuilder.setProgress(100, download.getProgress(), false);
notificationBuilder.setOngoing(true);
notificationBuilder.setContentText("Downloading Progress " + download.getProgress() + "%" + " /100%");
notificationManager.notify(0, notificationBuilder.build());
}
private void sendIntent(Download download) {
Intent intent = new Intent(ReadingListeningTestActivity.MESSAGE_PROGRESS);
intent.putExtra("download", download);
LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
}
private String packageName(String uri) {
String[] parts = uri.split("/");
return parts[parts.length - 1];
}
public File getCacheDir(String packageName) {
File cache = null;
File external = getApplication().getExternalCacheDir();
if (external != null && external.exists()) {
cache = external;
} else {
cache = getApplication().getCacheDir();
}
File file = new File(cache, packageName);
return file;
}
}
From my App, I am downloading some music files and saving them in a folder. In notification panel download progress is shown. When download completes, if notification is clicked, my android device should directly browse to destination folder, similar to "go to folder" on PCs after any download finishes.
I tried it from below code, but it is not working. It is just opening the app.
public class Temp extends Activity {
String[] link;
String[] items;
String song_link;
String song_name;
int song_index;
int link_index;
String url_link;
Exception error;
private ProgressBar mProgress;
long total = 0;
boolean downloadStatus = false;
ProgressDialog progressBar;
private Handler progressBarHandler = new Handler();
int progressBarStatus = 0;
Uri selectedUri;
Intent intent;
PendingIntent resultPendingIntent;
NotificationCompat.Builder mBuilder=
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("My notification")
.setContentText("Downloading");
NotificationManager mNotificationManager;
int id=1;
private class DownloadFilesTask extends AsyncTask<String, Integer, Long> {
protected Long doInBackground(String... urls) {
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mProgress = (ProgressBar) findViewById(R.id.progress_bar);
url_link = urls[0];
try {
/* runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),"link: "+url_link,Toast.LENGTH_SHORT).show();
}
});*/
int count;
URL url = new URL(url_link);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a typical 0-100% progress bar
final int lenghtOfFile = conexion.getContentLength();
// Download the file
InputStream input = new BufferedInputStream(url.openStream());
// String name = "first.mp3";
File folder = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MUSIC), "Vaishnav Songs");
if (!folder.mkdirs()) {
Log.e(DOWNLOAD_SERVICE, "Directory not created");
}
File filename = new File(folder,song_name);
OutputStream output = null;
output = new BufferedOutputStream(new FileOutputStream(filename));
byte data[] = new byte[1024];
mBuilder.setContentTitle(song_name);
int percentage;
id = song_index*10 + link_index;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// publishProgress((int)(total*100/lenghtOfFile) );
percentage = (int)(total*100/lenghtOfFile) ;
if(percentage%5 ==0){
new Thread(new Runnable() {
public void run() {
mBuilder.setProgress(100, (int)total*100/lenghtOfFile, false);
// Displays the progress bar for the first time.
mNotificationManager.notify(id, mBuilder.build());
}
}).start();
}
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
mBuilder.setContentIntent(resultPendingIntent);
new Thread(new Runnable() {
public void run() {
mBuilder.setContentText("Download complete")
// Removes the progress bar
.setProgress(100,100,false);
mNotificationManager.notify(id, mBuilder.build());
}
}).start();
}
catch (Exception e) {
error = e;
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),"Error: "+error,Toast.LENGTH_SHORT).show();
}
});
}
// Escape early if cancel() is called
// if (isCancelled()) break;
return total;
}
protected void onProgressUpdate(Integer... progress) {
progressBarStatus = progress[0];
}
protected void onPostExecute(Long result) {
/* Toast.makeText(getApplicationContext(),"Downloaded "+result+" bytes",Toast.LENGTH_SHORT).show();*/
Intent intent = getIntent();
finish();
//startActivity(intent);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectedUri = Uri.parse(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MUSIC) + "/"+"Vaishnav Songs"+"/");
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(selectedUri, "resource/folder");
resultPendingIntent =
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
song_name = (String) getIntent().getExtras().getString("songName");
song_link = (String) getIntent().getExtras().getString("songLink");
song_index = getIntent().getIntExtra("songIndex",0);
link_index = getIntent().getIntExtra("position",0);
Toast.makeText(getApplicationContext(),"Download started. Check progress in notification panel",Toast.LENGTH_SHORT).show();
//new DownloadFilesTask().execute(song_link);
DownloadFilesTask task = new DownloadFilesTask();
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,song_link);
finish();
}
}
Discover this https://developer.android.com/reference/android/app/Notification.Builder.html
You can try add setContentIntent(PendingIntent intent) to your notification with action for File manager opening.
I'm creating a local broadcast receiver for notifying an activity when a download has started and finished. I have two classes, one is the DownloadFileFromURL class that i call to download certain file, and in it I've defined this:
Intent intent = new Intent("completeDownloadItem");
// You can also include some extra data.
intent.putExtra("completedItem", suraName);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
that in my opinion should send a broadcast to my DownloadManager class that has this code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.download_manager);
LocalBroadcastManager.getInstance(this).registerReceiver(itemReceiver,
new IntentFilter("addDownloadItem"));
LocalBroadcastManager.getInstance(this).registerReceiver(
completeReceiever, new IntentFilter("completeDownloadItem"));
}
private BroadcastReceiver itemReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
Songs s = (Songs) intent.getSerializableExtra("newItems");
Log.d("receiver", "Got song: " + s.getTitle());
}
};
private BroadcastReceiver completeReceiever = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("completedItem");
Log.d("receiver", "Downloaded: " + message);
}
};
Can any one tell me what am I missing, should I define local broadcast receiver in the manifest or something?
here is the DownloadFileFromURL class:
public class DownloadFileFromURL extends AsyncTask<String, String, String> {
private Context context;
private ProgressDialog dialog;
private String reciterName, suraName;
private String file_url, filePath;
private MediaScannerConnection msc;
private DatabaseHelper db;
private int songNumber;
public DownloadFileFromURL(Context context, String reciterName,
String suraName, String fileURL, int songNumber) {
this.context = context;
this.songNumber = songNumber;
this.reciterName = reciterName;
this.suraName = suraName;
this.file_url = fileURL;
db = new DatabaseHelper(context);
}
protected void createDialog() {
// switch (id) {
// case progress_bar_type: // we set this to 0
dialog = new ProgressDialog(context);
// dialog.setMessage(context.getString(R.string.downloading) + " "
// + songName);
/*
* dialog.setIndeterminate(false); dialog.setMax(100);
*/
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCanceledOnTouchOutside(true);
dialog.setCancelable(false);
dialog.show();
// default:
// return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// createDialog();
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(file_url);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream
File appDir = new File(Environment.getExternalStorageDirectory()
.getPath() + "/" + context.getString(R.string.app_name));
appDir.mkdirs();
File albumDir = new File(appDir.getPath().toString() + "/"
+ reciterName);
albumDir.mkdirs();
OutputStream output = new FileOutputStream(appDir + "/"
+ reciterName + "/" + suraName + ".mp3");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
protected void onProgressUpdate(String... progress) {
// setting progress percentage
// dialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String file_url) {
msc = new MediaScannerConnection(context,
new MediaScannerConnection.MediaScannerConnectionClient() {
#Override
public void onScanCompleted(String path, Uri uri) {
msc.disconnect();
}
#Override
public void onMediaScannerConnected() {
msc.scanFile(filePath, null);
}
});
if (!msc.isConnected()) {
}
// dialog.dismiss();
db.openDB();
db.addDownloaded(songNumber, reciterName);
db.closeDB();
Intent intent = new Intent("completeDownloadItem");
// You can also include some extra data.
intent.putExtra("completedItem", suraName);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Toast.makeText(context, "Sucessfully downloaded " + suraName,
Toast.LENGTH_SHORT).show();
}
}
No, local broadcast receivers don't need to be configured in the AndroidManifest.xml. I have to say that I am as well a bit puzzled why the notification does not work; have you debugged into the code and checked if the broadcast is actually send out and whether the receiver is registered properly?
If you cannot get it working (for whatever reason), consider using a library like EventBus for your inter-component communication needs. Personally I haven't used the LocalBroadcastManager in ages...
this is the current state/situation: I have an Activity which binds a Service which creates AsyncTasks which downloads various web resources. That works well, but of course the ProgressBar shows nothing.
Previously i had an Activity which created an AsyncTask which downloaded some stuff. The AsyncTask got the View which holds the ProgressBar. So i could update the progress using onProgressUpdate and publishProgress. Obviously this doesn't work any longer because I have no reference to the ProgressBar.
So, do you have any idea on how to update the progress?
Thanks in advance.
Very nice explained indeed just missing the example :)
I went throw it and here it is.
public class Detail extends Activity {
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(DownloadService.CUSTOM_INTENT)) {
mProgressDialog.setProgress(intent.getFlags());
}
}
};
// Flag if receiver is registered
private boolean mReceiversRegistered = false;
// Define a handler and a broadcast receiver
private final Handler mHandler = new Handler();
#Override
protected void onResume() {
super.onResume();
// Register Sync Recievers
IntentFilter intentToReceiveFilter = new IntentFilter();
intentToReceiveFilter.addAction(DownloadService.CUSTOM_INTENT);
this.registerReceiver(mIntentReceiver, intentToReceiveFilter, null, mHandler);
mReceiversRegistered = true;
}
#Override
public void onPause() {
super.onPause();
// Make sure you unregister your receivers when you pause your activity
if(mReceiversRegistered) {
unregisterReceiver(mIntentReceiver);
mReceiversRegistered = false;
}
}
}
public class DownloadService extends Service {
private static final String CLASS_NAME = DownloadService.class.getSimpleName();
private List<Download> downloads = new ArrayList<Download>();
private int currentPosition;
public static final String sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";
private Context ctx;
#Override
public IBinder onBind(Intent arg0) {
ctx = getApplicationContext();
return mBinder;
}
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... _url) {
Log.d(Constants.LOG_TAG, CLASS_NAME + " Start the background GetNewsTask \nURL :" + _url[0]);
int count;
File finalFile = new File(sdcardPath + Constants.APK_LOCAL_PATH + "/" + splitName(_url[0]));
try {
if (!finalFile.exists()) {
Log.i(Constants.LOG_TAG, CLASS_NAME + " Donwloading apk from the Web");
URL url = new URL(_url[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(url.openStream());
File dir = new File(sdcardPath + Constants.APK_LOCAL_PATH);
if (!dir.exists())
dir.mkdirs();
OutputStream output = new FileOutputStream(sdcardPath + Constants.APK_LOCAL_PATH + "/" + splitName(_url[0]));
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int) (total * 100 / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} else {
Log.i(Constants.LOG_TAG, CLASS_NAME + " Apk in SDcard");
publishProgress(100);
}
} catch (Exception e) {
}
return null;
}
#Override
protected void onProgressUpdate(Integer... progress) {
Intent i = new Intent();
i.setAction(CUSTOM_INTENT);
i.setFlags(progress[0]);
ctx.sendBroadcast(i);
}
}
private String splitName(String url) {
String[] output = url.split("/");
return output[output.length - 1];
}
public static final String CUSTOM_INTENT = "es.tempos21.sync.client.ProgressReceiver";
private final IDownloadService.Stub mBinder = new IDownloadService.Stub() {
public void downloadAsynFile(String url) throws DeadObjectException {
try {
DownloadFile d = new DownloadFile();
d.execute(url);
} catch (Exception e) {
Log.e(Constants.LOG_TAG, CLASS_NAME + " " +e.getMessage()); }
}
}
};
interface IDownloadService {
void downloadAsynFile(String url);
}
Have the Service notify the then-running Activity about the progress from onProgressUpdate(). That could be via a broadcast Intent, or via a callback object registered by the Activity (and unregistered when the Activity is destroyed, such as on a screen rotation).
You can show progress just as easily via a Toast, which obviates all of the UI concerns:
public class foo extends Service {
private Toast toast;
#SuppressLint("ShowToast")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
ctxt = getApplicationContext();
toast = Toast.makeText(ctxt, "", Toast.LENGTH_SHORT);
...
}
public void functionCalledByYourAsyncWithUpdates(String progress){
toast.setText (progress);
toast.show;
}
}