Update progress of notification from a background service - android

I'm trying to update the progress of a notification during ftp upload handled by a background service, I tried directly from the service and after using a ResultReceiver but when the upload starts, the notification menu is freezed until the upload is done.How can I do this?
FtpService
public class FtpService extends IntentService {
public static final int UPDATE_PROGRESS = 10;
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
private static final String ACTION_SEND = "SEND";
private static final String EXTRA_PATH = "PATH";
private static final String PREFERENCES = "virtualtv";
private SharedPreferences mPrefs;
private NotificationManager mNotifyManager;
private NotificationCompat.Builder mBuilder;
/********* work only for Dedicated IP ***********/
private String FTP_HOST= "";
/********* FTP USERNAME ***********/
private String FTP_USER;
/********* FTP PASSWORD ***********/
private String FTP_PASS;
private String FTP_PORT;
private String PATH;
private Context mContext;
public FTPClient ftpClient;
private ResultReceiver mUploadReceiver;
public FtpService() {
super("FtpService");
}
/**
* Starts this service to perform action Foo with the given parameters. If
* the service is already performing a task this action will be queued.
*
* #see IntentService
*/
// TODO: Customize helper method
public static void startActionSend(Context context, String param1) {
Intent intent = new Intent(context, FtpService.class);
intent.setAction(ACTION_SEND);
intent.putExtra(EXTRA_PATH, param1);
intent.putExtra("UPLOAD_RECEIVER", new UploadReceiver(new Handler(), context));
context.startService(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
mContext = this;
final String action = intent.getAction();
mUploadReceiver = intent.getParcelableExtra("UPLOAD_RECEIVER");
if (ACTION_SEND.equals(action)) {
final String filePath = intent.getStringExtra(EXTRA_PATH);
mPrefs = mContext.getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE);
JsonObject config = Account.getInstance(mContext).getConfig();
if(mPrefs != null && config != null){
FTP_HOST = config.get("ftp_host").getAsString();
FTP_USER = config.get("ftp_username").getAsString();
FTP_PASS = config.get("ftp_password").getAsString();
FTP_PORT = config.get("ftp_port").getAsString();
PATH = config.get("ftp_path").getAsString();
}
handleActionSend(filePath);
}
}
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionSend(String filePath) {
File f = new File(filePath);
uploadFile(f);
}
public boolean uploadFile(final File f){
try {
ftpClient = new FTPClient();
ftpClient.connect(FTP_HOST, Integer.valueOf(FTP_PORT));
boolean b = ftpClient.login(FTP_USER, FTP_PASS);
Log.d("Login", "" + b);
b = ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
Log.d("file_type", "" + b);
b = ftpClient.changeWorkingDirectory(PATH);
Log.d("directory", "" + b);
// ftpClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
//
int reply = ftpClient.getReplyCode();
Log.d("reply", "" + reply);
// if(!FTPReply.isPositiveCompletion(reply)) {
// ftpClient.logout();
// ftpClient.disconnect();
// Log.d("ftp", "FTP server refused connection.");
// return false;
// }
InputStream srcFileStream = new FileInputStream(f);
// BufferedInputStream buffIn = new BufferedInputStream(new FileInputStream(f));
ftpClient.setControlKeepAliveTimeout(10);
ftpClient.enterLocalPassiveMode();
final int fileSize = (int) (FileUtils.sizeOf(f) / 1024);
// dati trasferiti
ftpClient.setCopyStreamListener(new CopyStreamListener() {
#Override
public void bytesTransferred(CopyStreamEvent event) {
}
#Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
Log.d("ftp", "total:" + totalBytesTransferred / 1024 + " trasnferred: " + bytesTransferred + " size:" + fileSize);
Bundle data = new Bundle();
data.putInt("fileSize", fileSize);
data.putInt("kbyte_transferred", (int) totalBytesTransferred / 1024);
mUploadReceiver.send(UPDATE_PROGRESS, data);
}
});
// Log.d("buffer", "" + buffIn.available());
Log.d("ftp", "storing file...");
boolean result = ftpClient.storeFile(f.getName(), srcFileStream);
Log.d("ftp", "result:" + result);
Log.d("ftp", "reply code:" + ftpClient.getReplyCode());
// inputStream.close();
srcFileStream.close();
// buffIn.close();
ftpClient.logout();
ftpClient.disconnect();
return result;
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (CopyStreamException e) {
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
return false;
}
}
UploadReceiver
class UploadReceiver extends ResultReceiver{
private NotificationManager mNotifyManager;
private NotificationCompat.Builder mBuilder;
private int id = 1;
public UploadReceiver(Handler handler, Context context) {
super(handler);
final int id = 1;
//Gestione notifica
mNotifyManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_launcher);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == FtpService.UPDATE_PROGRESS) {
int fileSize = resultData.getInt("file_size");
int transferred = resultData.getInt("kbyte_transferred");
mBuilder.setProgress(fileSize,transferred, false);
mNotifyManager.notify(id, mBuilder.build());
}
}
}

I solved the issue adding a check with an interval of 1000 milliseconds, if these have gone the UploadReceiver can update the notify and in this way it seems to work fine without freeze.It works also with a lower interval as 500 milliseconds.

Guys is my case these many times progress is rendering but I want only 100 times of progress so this code solve my issue.
Put int oldProgress =1;
int progresss = (int) ((progress.currentBytes / (float) progress.totalBytes) * 100);
if(progresss>oldProgress)
{
oldProgress=progresss;
notificationBuilder.setProgress(100, progresss,false);
notification = notificationBuilder.build();
notificationManager.notify(notificationID,notification);
}

Related

Android: Unable to update custom notification when I kill my app

I am downloading multiple files one after the other in service. I want to update download progress in notification. But my notification doesn't update when I kill my app. Download works on different thread. Download works fine in when app is running. When I kill app from recent section, I am unable to update notification.
Here is my DownloadService class
public class DownloadService extends Service {
public static DownloadMap<String, Downloadables> map = new DownloadMap<String, Downloadables>();
private static Thread thread;
private DownloadCancelReceiver receiver;
public DownloadService() {
}
public class BackgroundThread extends Thread {
int serviceId;
private DownloadMap<String, Downloadables> map;
private SpeedRevisionDatabase helper;
private final int notificationId = 1;
private RemoteViews remoteViewsSmall, remoteViewsBig;
private NotificationManagerCompat notificationManager;
private NotificationCompat.Builder mBuilder, mBuilderComplete, downloadFailBuilder;
public BackgroundThread(int serviceId, DownloadMap<String, Downloadables> map) {
this.serviceId = serviceId;
this.map = new DownloadMap<>();
this.map.putAll(map);
}
#Override
public void run() {
remoteViewsSmall = new RemoteViews(getApplicationContext().getPackageName(), R.layout.download_notification_small);
remoteViewsBig = new RemoteViews(getApplicationContext().getPackageName(), R.layout.download_notification);
Intent cancelDownload = new Intent("CANCEL_DOWNLOAD");
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, cancelDownload, 0);
remoteViewsBig.setOnClickPendingIntent(R.id.tvCancel, pendingIntent);
notificationManager = NotificationManagerCompat.from(DownloadService.this);
mBuilder = new NotificationCompat.Builder(DownloadService.this, "default");
initChannels(DownloadService.this);
mBuilder.setContentTitle("Download is in progress")
.setContentText("Please wait...")
.setSmallIcon(R.mipmap.download)
.setOngoing(true)
.setCustomContentView(remoteViewsSmall)
.setCustomBigContentView(remoteViewsBig)
.setPriority(NotificationCompat.PRIORITY_HIGH);
notificationManager.notify(notificationId, mBuilder.build());
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
try {
String path = getApplicationContext().getApplicationInfo().dataDir + "/" + "UEP";
File uepFolder = new File(path);
if (!uepFolder.exists()) {
uepFolder.mkdir();
}
int i = 0;
while (map.entrySet().iterator().hasNext()) {
Log.e("WhileCheck", "Now i is " + i);
Map.Entry data = (Map.Entry) map.entrySet().iterator().next();
try {
Downloadables download = (Downloadables) data.getValue();
if (NetworkUtil.getConnectivityStatus(getApplicationContext()) == 0) {
throw new InternetDisconnectedException("Internet Disconnected");
}
HttpURLConnection urlConnection;
InputStream inputStream;
//finding file on internet
try {
URL url = new URL(download.URL);
if (url.toString().endsWith(".xps")) {
url = new URL(url.toString().replace(".xps", ".pdf"));
}
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
inputStream = urlConnection.getInputStream();
} catch (IOException e) {
Log.e("IOException", "" + e.getMessage());
i++;
map.remove(data.getKey());
notificationManager.notify(notificationId, mBuilder.build());
continue;
}
//Downloading file over internet
File file = new File(uepFolder + "/" + download.FileName + "" + download.Format + ".download");
try {
int fileSize = urlConnection.getContentLength();
FileOutputStream fileOutput = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bufferLength = 0;
int count = 0;
int previousProgress = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
if (this.isInterrupted()) {
throw new InterruptedException("Thread has been kill (Destroyed)");
}
fileOutput.write(buffer, 0, bufferLength);
count += bufferLength;
int progress = (int) (count * 100L / (float) fileSize);
if (previousProgress > 999) {
updateProgress(map.insertedCount, i, progress, download.Name);
notificationManager.notify(notificationId, mBuilder.build());
previousProgress = 0;
}
previousProgress++;
}
fileOutput.close();
} catch (IOException e) {
Log.e("IOException", "" + e.getMessage());
i++;
map.remove(data.getKey());
continue;
}
File actualFile = new File(uepFolder + "/" + download.FileName + "" + download.Format);
file.renameTo(actualFile);
Log.e("Downloaded",""+actualFile.getAbsoluteFile());
} catch (InterruptedException | InternetDisconnectedException e) {
throw e;
}
i++;
map.remove(data.getKey());
Log.e("Downloaded", "Remaining files are "+map.size());
}
Log.e("WhileCheck", "While End");
// Due to thread, sometime the sequence of code flow is not in correct flow, and "Download complete" Notifaction is getting shown
// Hence this check is required.
if (this.isInterrupted()) {
throw new InterruptedException("Thread has been kill (Destroyed)");
}
notificationManager.cancel(notificationId);
mBuilderComplete = new NotificationCompat.Builder(DownloadService.this, "default");
initChannels(DownloadService.this);
mBuilderComplete.setOngoing(false)
.setContentTitle("Download Complete")
.setColor(Color.WHITE)
.setSmallIcon(R.drawable.download);
notificationManager.notify(2, mBuilderComplete.build());
Log.e("DownloadingService", "File downloaded successfully");
stopSelf();
map.insertedCount = 0;
} catch (InterruptedException e) {
closeNotification();
Log.e("InterruptedException", "" + e.getMessage());
} catch (InternetDisconnectedException e) {
stopSelf();
closeNotification();
showNotification("Internet disconnected", "Download failed. Try again later.");
Log.e("InternetDisconnect", "" + e.getMessage());
}
}
private void updateProgress(int totalFiles, int currentFileCount, int currentProgress, String fileName) {
remoteViewsSmall.setTextViewText(R.id.tvOverAll, currentFileCount + "/" + totalFiles);
remoteViewsSmall.setProgressBar(R.id.overallProgress, totalFiles, currentFileCount, false);
remoteViewsBig.setTextViewText(R.id.tvOverAll, currentFileCount + "/" + totalFiles);
remoteViewsBig.setTextViewText(R.id.tvFileName, "Downloading " + fileName);
remoteViewsBig.setTextViewText(R.id.tvCurrentProgress, currentProgress + "%");
remoteViewsBig.setProgressBar(R.id.overallProgress, totalFiles, currentFileCount, false);
remoteViewsBig.setProgressBar(R.id.currentProgress, 100, currentProgress, false);
}
public void closeNotification() {
if (notificationManager != null)
notificationManager.cancel(notificationId);
}
public void showNotification(String title, String message) {
downloadFailBuilder = new NotificationCompat.Builder(DownloadService.this, "default");
initChannels(DownloadService.this);
downloadFailBuilder.setOngoing(false)
.setContentTitle(title)
.setContentText(message)
.setColor(Color.WHITE)
.setSmallIcon(android.R.drawable.stat_sys_warning);
notificationManager.notify(3, downloadFailBuilder.build());
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
ArrayList<Downloadables> list = (ArrayList<Downloadables>) intent.getSerializableExtra("downloadList");
for (Downloadables d : list) {
String key = d.Name + "" + d.FileName;
map.put(key, d);
}
if (thread == null || !thread.isAlive()) {
thread = new BackgroundThread(startId, map);
receiver = new DownloadCancelReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
intentFilter.addAction("CANCEL_DOWNLOAD");
registerReceiver(receiver, intentFilter);
thread.start();
}
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.e("Service", " Stop");
try {
thread.interrupt();
} catch (Exception e) {
Log.e("Exception", "" + e.getMessage());
}
map.clear();
unregisterReceiver(receiver);
//closeNotification();
}
public static class DownloadCancelReceiver extends BroadcastReceiver {
public DownloadCancelReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase("CANCEL_DOWNLOAD")) {
Intent intent1 = new Intent(context, DownloadService.class);
context.stopService(intent1);
}
}
}
public void initChannels(Context context) {
if (Build.VERSION.SDK_INT < 26) {
return;
}
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel("default", "Channel name", NotificationManager.IMPORTANCE_LOW);
channel.setDescription("Channel description");
channel.setImportance(NotificationManager.IMPORTANCE_LOW);
channel.setSound(null, null);
notificationManager.createNotificationChannel(channel);
}
private class InternetDisconnectedException extends Exception {
public InternetDisconnectedException(String message) {
super(message);
}
}
public static class DownloadMap<String, Downloadables> extends HashMap<String, Downloadables> {
public int insertedCount;
#Override
public Downloadables put(String key, Downloadables value) {
insertedCount++;
return super.put(key, value);
}
}
}
And From activity I start service like this.
ArrayList<Downloadables> list = helper.GetVideoFileList();
Intent intent1 = new Intent(SRDownloadActivity.this, DownloadService.class);
intent1.putExtra("downloadList", list);
startService(intent1);
I can even Add files to HashMap while downloading is in progress. It also worked fine.
I am unable to figure it out why it is not running in background since it is on different thread.
Here is my notification look like
Threads are killed by the Android OS even if the main app is still working and they dont have access to the UI thats why u should use AsyncTask class its a like a thread that works in background but it has access to the UI of the main. And the jobdispatcher class can help u assign jobs in the background
Here is a good tutorial https://youtu.be/das7FmQIGik

Adding Progress Bar or Progress Dialogue for sending and receiving file

I have implemented a file sharing project. I am able to Send and Receive File but want to add progress bar or progress dialogue but I have no clue where to add progress bar to it.
Receiver Activity
public class ReceiverActivity extends AppCompatActivity {
FileReceiver fileReceiver;
ImageButton ibt;
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
/* case FileReceiver.CODE :
tvCode.setText((int)msg.obj + "");
break;
*/
case FileReceiver.LISTENING :
Toast.makeText(ReceiverActivity.this,"Listening...",Toast.LENGTH_SHORT).show();
break;
case FileReceiver.CONNECTED:
Toast.makeText(ReceiverActivity.this,"Connected!",Toast.LENGTH_SHORT).show();
break;
case FileReceiver.RECEIVING_FILE :
Toast.makeText(ReceiverActivity.this,"Receiving File!",Toast.LENGTH_SHORT).show();
break;
case FileReceiver.FILE_RECEIVED :
File file = (File) msg.obj;
Toast.makeText(ReceiverActivity.this,file.getName() + " Received!",Toast.LENGTH_SHORT).show();
Toast.makeText(ReceiverActivity.this,"Stored in " + file.getAbsolutePath(),Toast.LENGTH_SHORT).show();
fileReceiver.close();
break;
case FileReceiver.RECEIVE_ERROR :
Toast.makeText(ReceiverActivity.this,"Error occured : " + (String)msg.obj,Toast.LENGTH_SHORT).show();
fileReceiver.close();
break;
}
}
};
public void getFile(View view) {
fileReceiver = new FileReceiver(this,mHandler);
fileReceiver.getFile();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receiver);
ibt= (ImageButton) findViewById(R.id.imgbtn);
ibt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(ReceiverActivity.this, Selection_Activity.class);
startActivity(i);
}
});
}
}
Receiver Thread
public class ReceiverThread extends Thread {
private int port;
private Messenger messenger;
private ServerSocket listenerSocket;
private Socket communicationSocket;
private int PKT_SIZE = 60*1024;
ProgressDialog dialog;
public ReceiverThread(int port,Messenger messenger){
//
this.port = port;
this.messenger = messenger;
File folder = new File(Environment.getExternalStorageDirectory() + "/FileSharer/");
folder.mkdirs();
}
#Override
public void run() {
Message message;
try {
listenerSocket = new ServerSocket(port);
message = Message.obtain();
message.what = FileReceiver.CODE;
message.obj = port;
messenger.send(message);
message = Message.obtain();
message.what = FileReceiver.LISTENING;
message.obj = "";
messenger.send(message);
communicationSocket = listenerSocket.accept();
message = Message.obtain();
message.what = FileReceiver.CONNECTED;
message.obj = "";
messenger.send(message);
DataInputStream in = new DataInputStream(communicationSocket.getInputStream());
message = Message.obtain();
message.what = FileReceiver.RECEIVING_FILE;
message.obj = "";
messenger.send(message);
// Read File Name and create Output Stream
String fileName = in.readUTF();
File receiveFile = new File(Environment.getExternalStorageDirectory() + "/FileSharer/" + fileName);
DataOutputStream dout = new DataOutputStream(new FileOutputStream(receiveFile,true));
// Read File Size
long fileSize = in.readLong();
int totalLength = 0;
int length = 0;
byte[] receiveData = new byte[PKT_SIZE];
long startTime = System.currentTimeMillis();
// Get the file data
while( fileSize>0 && ( ( length = in.read( receiveData,0,(int) Math.min(receiveData.length,fileSize) ))!= -1) )
{
dout.write(receiveData, 0, length);
totalLength += length;
fileSize -= length;
}
long stopTime = System.currentTimeMillis();
dout.close();
double time = (stopTime - startTime) / 1000.0;
double speed = (totalLength / time) / 1048576.0;
message = Message.obtain();
message.what = FileReceiver.FILE_RECEIVED;
message.obj = receiveFile;
messenger.send(message);
} catch (Exception e){
e.printStackTrace();
message = Message.obtain();
message.what = FileReceiver.RECEIVE_ERROR;
message.obj = e.toString();
try {
messenger.send(message);
} catch (RemoteException re) {
Log.e("ReceiverThread","Error in sending an error message! Error : " + re.toString());
re.printStackTrace();
}
} finally {
try {
if(communicationSocket!=null)
communicationSocket.close();
if(listenerSocket!=null)
listenerSocket.close();
} catch (IOException ioe) {
Log.e("ReceiverThread","Error in closing sockets. Error : " + ioe.toString());
ioe.printStackTrace();
}
}
}
}
Receiver Service
public class ReceiverService extends Service {
private final String PORT = "PORT";
private final String MESSENGER = "MESSENGER";
private int port;
private Messenger messenger;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle b = intent.getExtras();
port = (int) b.get(PORT);
messenger = (Messenger) b.get(MESSENGER);
ReceiverThread receiverThread = new ReceiverThread(port,messenger);
receiverThread.start();
return START_REDELIVER_INTENT;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
File Receiver
public class FileReceiver {
private final boolean mDebug = true;
// private final int MIN_PORT_NUMBER = 1024;
// private final int MAX_PORT_NUMBER = 65536;
private final String PORT = "PORT";
private final String MESSENGER = "MESSENGER";
// Constants start from 2001
public static final int CODE = 2001;
public static final int LISTENING = 2002;
public static final int CONNECTED = 2003;
public static final int RECEIVING_FILE = 2004;
public static final int FILE_RECEIVED = 2005;
public static final int RECEIVE_ERROR = 2006;
private Context context;
private Handler mHandler;
private Intent i;
public FileReceiver(Context context, Handler mHandler) {
this.context = context;
this.mHandler = mHandler;
}
/* private boolean isPortAvailable(int port) {
boolean available;
if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
throw new IllegalArgumentException("Invalid port: " + port);
}
ServerSocket ss = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
available = true;
} catch (IOException e) {
available = false;
} finally {
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
}
}
}
return available;
}
*/
private int getRandomPort() {
//int port = 1001;
int port = 40500;
//do{
// port = (int) (MIN_PORT_NUMBER + 1 + Math.floor(Math.random()*(MAX_PORT_NUMBER - MIN_PORT_NUMBER-1)));
if(mDebug)
Log.i("FileReceiver","Trying port : " + port);
// }while(!isPortAvailable(port));
return port;
// return port;
}
public void getFile(){
int port = getRandomPort();
if(mDebug)
Log.i("FileReceiver","Port : " + port);
i = new Intent(context,ReceiverService.class);
i.putExtra(PORT,port);
i.putExtra(MESSENGER,new Messenger(mHandler));
context.startService(i);
}
public void close() {
context.stopService(i);
}
}
You can add a simple ProgressDialog box from your activity.
Something like :
// global variable
ProgressDialog mProgressDialog;
...
...
// inside onCreate
mProgressDialog = new ProgressDialog(ReceiveActivity.this);
mProgressDialog.setCancelable(true);
mProgressDialog.setMessage("Downloading file ..");
...
...
// before file downloads
mProgressDialog.show();
...
...
// when file is downloaded
mProgressDialog.dismiss();
Edit :
In case of the given questions, this can be done as :
// assuming mProgressDialog is already initialised and configured.
case FileReceiver.CONNECTED:
Toast.makeText(ReceiverActivity.this,"Connected!",Toast.LENGTH_SHORT).show();
/******** Show the dialog box *********/
mProgressDialog.show(); // make sure that the file receiving starts immediately
// after the receiver is connected and that it do not
// require any action (like button click) after is connected
break;
case FileReceiver.RECEIVING_FILE :
Toast.makeText(ReceiverActivity.this,"Receiving File!",Toast.LENGTH_SHORT).show();
/******** Dismiss the dialog box *********/
mProgressDialog.dismiss();
break;
case FileReceiver.FILE_RECEIVED :
File file = (File) msg.obj;
Toast.makeText(ReceiverActivity.this,file.getName() + " Received!",Toast.LENGTH_SHORT).show();
Toast.makeText(ReceiverActivity.this,"Stored in " + file.getAbsolutePath(),Toast.LENGTH_SHORT).show();
fileReceiver.close();
/******** Dismiss the dialog box *********/
mProgressDialog.dismiss();
break;
You can also have a dialog box with progress percentage. Have a look into the ProgressDialog documentation.
There are methods like setProgressStyle(int style) with values like STYLE_HORIZONTAL. And then there are incrementProgressBy(int diff) that can be used to get a horizontal bar there.

Is it possible to show progress bar when download file via Retrofit 2, Android

I'am currently using Retrofit 2 and i want to download some file from my server.
Can i call back some event to catch percent complete download file to show in notification like this picture
I reference that link, but it is upload, can i do it with same problem?
Link
Is it possible to show progress when using retrofit 2 library?
You can use ResponseBody and set it to OkHttp client and to update progress in UI you can use interface.check this link
As an alternative, you could use an Intent service as described here.
I will show you how I used the above... The only difference is the portion where the file is written to disk.
Define the service:
public class BackgroundNotificationService extends IntentService {
public BackgroundNotificationService() {
super("Service");
}
private NotificationCompat.Builder notificationBuilder;
private NotificationManager notificationManager;
private String mAgentsID;
private String mReportsID;
private String mJobID;
private String mFileName;
#Override
protected void onHandleIntent(Intent intent) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel("id", "an", NotificationManager.IMPORTANCE_LOW);
notificationChannel.setDescription("no sound");
notificationChannel.setSound(null, null);
notificationChannel.enableLights(false);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.enableVibration(false);
notificationManager.createNotificationChannel(notificationChannel);
}
notificationBuilder = new NotificationCompat.Builder(this, "id")
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle("Download")
.setContentText("Downloading Image")
.setDefaults(0)
.setAutoCancel(true);
notificationManager.notify(0, notificationBuilder.build());
mAgentsID = intent.getStringExtra("AgentsID");
mReportsID = intent.getStringExtra("ReportsID");
mJobID = intent.getStringExtra("JobID");
mFileName = intent.getStringExtra("FileName");
initRetrofit();
}
private void initRetrofit(){
Call<ResponseBody> downloadCall = ApiManager.getJasperReportsService().DownloadAgentReportData(mAgentsID, mReportsID, mJobID, mFileName);
try {
writeResponseBodyToDisk(downloadCall.execute().body(), mFileName);
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean writeResponseBodyToDisk(ResponseBody body, String FileName) {
try {
File SDCardRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File DownloadedFile = new File(SDCardRoot + File.separator + FileName);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
long total = 0;
boolean downloadComplete = false;
inputStream = body.byteStream();
outputStream = new FileOutputStream(DownloadedFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
downloadComplete = true;
break;
}
total += read;
int progress = (int) ((double) (total * 100) / (double) fileSize);
updateNotification(progress);
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Log.d("DOWNLOAD FILE", "file download: " + fileSizeDownloaded + " of " + fileSize);
}
onDownloadComplete(downloadComplete);
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
private void updateNotification(int currentProgress) {
notificationBuilder.setProgress(100, currentProgress, false);
notificationBuilder.setContentText("Downloaded: " + currentProgress + "%");
notificationManager.notify(0, notificationBuilder.build());
}
private void sendProgressUpdate(boolean downloadComplete) {
Intent intent = new Intent("progress_update");
intent.putExtra("downloadComplete", downloadComplete);
LocalBroadcastManager.getInstance(BackgroundNotificationService.this).sendBroadcast(intent);
}
private void onDownloadComplete(boolean downloadComplete) {
sendProgressUpdate(downloadComplete);
notificationManager.cancel(0);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder.setContentText("Download Complete");
notificationManager.notify(0, notificationBuilder.build());
}
#Override
public void onTaskRemoved(Intent rootIntent) {
notificationManager.cancel(0);
}
}
And then use the intent service:
private void registerReceiver() {
LocalBroadcastManager bManager = LocalBroadcastManager.getInstance(itemView.getContext());
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("progress_update");
bManager.registerReceiver(mBroadcastReceiver, intentFilter);
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("progress_update")) {
boolean downloadComplete = intent.getBooleanExtra("downloadComplete", false);
//Log.d("API123", download.getProgress() + " current progress");
if (downloadComplete) {
Toast.makeText(itemView.getContext(), "File download completed", Toast.LENGTH_SHORT).show();
}
}
}
};
private void startDownload(String jobID, String FileName) {
Intent intent = new Intent(itemView.getContext(), BackgroundNotificationService.class);
// TODO customze to suit your own needs.
intent.putExtra("AgentsID", mAgentsID);
intent.putExtra("ReportsID", mReportsID);
intent.putExtra("JobID", jobID);
intent.putExtra("FileName", FileName);
itemView.getContext().startService(intent);
}
so you use registerReceiver() on start of your activity and then if you have a button to initiate the download, you in the onClick method run startDownload(). As an extra note, you can customize the intent variables(if you need any), to your needs.

Upload videos to youtube android

I have tried to upload videos using the following code.But whenever i click upload it is going into INITIATION_STARTED and INITIATION_COMPLETE of ResumableUpload class.But it is not getting uploaded to youtube.I couldnt find any exception and also i couldnt understand why it is not going into MEDIA_IN_PROGRESS.
Can you help me out..
Code for getting access token and calls uploadservice from MainActivity
MainActivity.java:
private void tryAuthenticate() {
if (isFinishing()) {
return;
}
mToken = null;
setProgressBarIndeterminateVisibility(true);
AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
try {
// Retrieve a token for the given account and scope. It will
// always return either
// a non-empty String or throw an exception.
mToken =
GoogleAuthUtil.getToken(MainActivity.this, mChosenAccountName, "oauth2:"
+ Scopes.PROFILE + " " + YouTubeScopes.YOUTUBE + " "
+ YouTubeScopes.YOUTUBE_UPLOAD);
} catch (GooglePlayServicesAvailabilityException playEx) {
GooglePlayServicesUtil.getErrorDialog(playEx.getConnectionStatusCode(),
MainActivity.this, REQUEST_GMS_ERROR_DIALOG).show();
} catch (UserRecoverableAuthException userAuthEx) {
// Start the user recoverable action using the intent
// returned by
// getIntent()
startActivityForResult(userAuthEx.getIntent(), REQUEST_AUTHENTICATE);
return false;
} catch (IOException transientEx) {
// TODO: backoff
Log.e(this.getClass().getSimpleName(), transientEx.getMessage());
} catch (GoogleAuthException authEx) {
Log.e(this.getClass().getSimpleName(), authEx.getMessage());
}
return true;
}
#Override
protected void onPostExecute(Boolean hideProgressBar) {
invalidateOptionsMenu();
if (hideProgressBar) {
setProgressBarIndeterminateVisibility(false);
}
if (mToken != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
saveAccount();
}
});
}
loadData();
}
};
task.execute((Void) null);
}
public void uploadVideo(View view) {
if (mToken == null) {
return;
}
// if an upload video is selected.
if (mVideoData != null) {
mDirectFragment.directLite(mVideoData, mToken);
mButton.setEnabled(false);
return;
}
// if a video is picked or recorded.
if (mFileURI != null) {
Intent uploadIntent = new Intent(this, UploadService.class);
uploadIntent.setData(mFileURI);
uploadIntent.putExtra(ACCOUNT_KEY, mChosenAccountName);
uploadIntent.putExtra(TOKEN_KEY, mToken);
startService(uploadIntent);
mButton.setEnabled(false);
}
}
UploadService.java
public class UploadService extends IntentService {
public UploadService() {
super("YTUploadService");
}
private Uri mFileUri;
private String mToken;
private long mFileSize;
#Override
protected void onHandleIntent(Intent intent) {
mFileUri = intent.getData();
Log.d("upload service"," "+mFileUri);
mToken = intent.getStringExtra("token");
mFileSize = intent.getLongExtra("length", 0);
GoogleCredential credential = new GoogleCredential();
credential.setAccessToken(mToken);
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
YouTube youtube =
new YouTube.Builder(httpTransport, jsonFactory, credential).setApplicationName(
Constants.APP_NAME).build();
InputStream fileInputStream = null;
try {
mFileSize = getContentResolver().openFileDescriptor(mFileUri, "r").getStatSize();
fileInputStream = getContentResolver().openInputStream(mFileUri);
} catch (FileNotFoundException e) {
Log.e(getApplicationContext().toString(), e.getMessage());
}
ResumableUpload.upload(youtube, fileInputStream, mFileSize, getApplicationContext());
}
}
ResumableUpload.java:
public class ResumableUpload {
private static int NOTIFICATION_ID = 1001;
private static String VIDEO_FILE_FORMAT = "video/*";
public static String upload(YouTube youtube, final InputStream fileInputStream,
final long fileSize, Context context) {
final NotificationManager mNotifyManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle(context.getString(R.string.youtube_upload))
.setContentText(context.getString(R.string.youtube_direct_lite_upload_started))
.setSmallIcon(R.drawable.icon);
String videoId = null;
try {
// Add extra information to the video before uploading.
Video videoObjectDefiningMetadata = new Video();
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
// We set a majority of the metadata with the VideoSnippet object.
VideoSnippet snippet = new VideoSnippet();
Calendar cal = Calendar.getInstance();
snippet.setTitle("Test Upload via Java on " + cal.getTime());
snippet.setDescription("Video uploaded via YouTube Data API V3 using the Java library "
+ "on " + cal.getTime());
List<String> tags = new ArrayList<String>();
tags.add(Constants.DEFAULT_KEYWORD);
tags.add(Upload.generateKeywordFromPlaylistId(Constants.UPLOAD_PLAYLIST));
snippet.setTags(tags);
videoObjectDefiningMetadata.setSnippet(snippet);
InputStreamContent mediaContent =
new InputStreamContent(VIDEO_FILE_FORMAT, new BufferedInputStream(fileInputStream));
mediaContent.setLength(fileSize);
YouTube.Videos.Insert videoInsert =
youtube.videos().insert("snippet,statistics,status", videoObjectDefiningMetadata,
mediaContent);
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader) throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
mBuilder.setContentText("Initiation Started").setProgress((int) fileSize,
(int) uploader.getNumBytesUploaded(), false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
break;
case INITIATION_COMPLETE:
mBuilder.setContentText("Initiation Completed").setProgress((int) fileSize,
(int) uploader.getNumBytesUploaded(), false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
break;
case MEDIA_IN_PROGRESS:
mBuilder
.setContentTitle("YouTube Upload " + (int) (uploader.getProgress() * 100) + "%")
.setContentText("Direct Lite upload in progress")
.setProgress((int) fileSize, (int) uploader.getNumBytesUploaded(), false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
break;
case MEDIA_COMPLETE:
mBuilder.setContentTitle("YouTube Upload Completed")
.setContentText("Upload complete")
// Removes the progress bar
.setProgress(0, 0, false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
case NOT_STARTED:
Log.d(this.getClass().getSimpleName(), "Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
// Execute upload.
Video returnedVideo = videoInsert.execute();
videoId = returnedVideo.getId();
} catch (final GoogleJsonResponseException e) {
if (401 == e.getDetails().getCode()) {
Log.e(ResumableUpload.class.getSimpleName(), e.getMessage());
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(context);
manager.sendBroadcast(new Intent(MainActivity.INVALIDATE_TOKEN_INTENT));
}
} catch (IOException e) {
Log.e("IOException", e.getMessage());
} catch (Throwable t) {
Log.e("Throwable", t.getMessage());
}
return videoId;
}
}

Activity with ProgressBar -> Service -> AsyncTask for downloading - but how to update the progress?

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

Categories

Resources