I know many questions been asked on this topic but none could answer my specific question or maybe I failed to recognize the right reply anyway!!
Just like Android Market during the download of a file with progressbar in the activity and progressbar in the notification bar, clicking the notification progressbar return back to the original activity with the progressbar updated with the download progress.
I am using AsyncTask for the download and creating & updating the notification bar all works fine, but when I click the notification it return me to same activity but without any data or progressbar (blank activity) in other word it start new activity and loose the extras and all fields data including the activity progressbar status.
I tried playing with flags and intent but failed to get my original activity loaded when clicking the notification bar specially when going back to another activity and then going to home screen then press the notification bar.
I run the download by:
df = new AsyncDownloadTask();
df.execute(m_item.getiid(),m_item.getipackage());
and the snippet (I changed the notification bar just to display progress text):
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView (R.layout.activity_app_display);
//get extras
Bundle extras = getIntent().getExtras();
if (extras == null) {
return;
}
itemId = extras.getString("id");
itemStatus = extras.getString("IorU");
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressbar);
progressBar.setVisibility(0);
showUI();
}
private void showUI() {
if(m_item != null) {
TextView actvTitle = (TextView) findViewById(R.id.title_text);
actvTitle.setText(m_item.geticategory());
appinstall = (Button) findViewById(R.id.app_install_btn);
appudinstall = (Button) findViewById(R.id.app_udinstall_btn);
permlist = (LinearLayout) findViewById(R.id.app_perm); //
info = (LinearLayout) findViewById(R.id.info);
mList = (HeightListView) findViewById(R.id.app_perm_list);
mList.setTextFilterEnabled(true);
instTxt = (TextView) findViewById(R.id.app_install);
TextView titleTxt = (TextView) findViewById(R.id.app_titlebig);
TextView companyTxt = (TextView) findViewById(R.id.app_descbig);
TextView descTxt = (TextView) findViewById(R.id.long_desc);
TextView verTxt = (TextView) findViewById(R.id.version);
//fill info
titleTxt.setText(m_item.getititle());
companyTxt.setText(m_item.geticompany());
descTxt.setText(m_item.getidescription());
verTxt.setText(" Version:" + m_item.getiversion());
}
}
#Override
protected void onResume(){
super.onResume();
}
#Override
public Object onRetainNonConfigurationInstance() {
Toast.makeText (getApplicationContext(), "onRetainNonConfigurationInstance", Toast.LENGTH_SHORT).show();
return null;
}
#Override
protected void onDestroy() {
super.onDestroy();
/*
if(df != null)
{
if(!df.isCancelled())
df.cancel(true);
}
CN=true;
*/
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onStart() {
super.onStart();
}
private class AsyncDownloadTask extends AsyncTask<String, Integer, Void>
{
private int successCount;
private int numTotalFiles;
private File outputFile;
private String pack;
private int downloadErr = 0;
#Override
protected void onPreExecute()
{
super.onPreExecute();
successCount = 0;
notificationManager = (NotificationManager) getApplicationContext().getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
CN=false;
}
#Override
protected Void doInBackground(String... params)
{
String remoteFilepath;
String id = params[0];
pack = params[1];
remoteFilepath = "http://www.myserver/download/1.zip";
String PATH = Environment.getExternalStorageDirectory()+ "/download/";
File file = new File(PATH);
file.mkdirs();
try
{
if(isCancelled())
return null;
URL url = new URL(remoteFilepath);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setConnectTimeout(getConnectTimeout());
c.setReadTimeout(getReadTimeout());
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
int filesize = c.getContentLength();
if(filesize > 0)
{
outputFile = new File(file, "1.zip");
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
int bytesRead, totalBytesRead = 0;
byte[] bytes = new byte[BYTES_BUFFER_SIZE];
String progress, kbytes;
while(!isCancelled() && (bytesRead = is.read(bytes)) != -1)
{
totalBytesRead += bytesRead;
fos.write(bytes, 0, bytesRead);
if(!isCancelled() ) //&& loopCount++ % 20 == 0)
{
RemoteViews progressView = getProgressView(successCount + 1, numTotalFiles, totalBytesRead, filesize);
if(progressView == null)
{
progress = "Download "+pack;
kbytes = String.format("%s / %s", getStringByteSize(totalBytesRead), getStringByteSize(filesize));
if(!isCancelled() && !CN){
showNotification("Downloading File(s)", progress , kbytes);
publishProgress(totalBytesRead,filesize);
} else { return null; }
}
else
{
if(!isCancelled() && !CN){
showNotification(progressView, "Downloading File(s)");
} else { return null; }
}
}
}
fos.close();
is.close();
if(isCancelled())
return null;
successCount ++;
}
else
{
}
}
catch(Exception e)
{
e.printStackTrace();
showNotification("Download Failed", "Download Progress", "Failed: " + (new File(remoteFilepath)).getName());
//updateCancelInstall();
publishProgress(100,100);
notificationManager.cancel(42);
downloadErr = 1;
CN = true;
}
return null;
}
#Override
protected void onCancelled()
{
super.onCancelled();
showNotification("Download Cancelled", "Download Progress", "Cancelled");
CN = true;
publishProgress(100,100);
notificationManager.cancel(42);
}
protected void onProgressUpdate(Integer... prog) {
if(prog[0]<prog[1]){
updateProgress(prog[0],prog[1],false);
} else {
updateProgress(100,100,true);
notificationManager.cancel(42);
}
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
if(!CN){
if(downloadErr==0) {
showNotification("Installing", "Installing "+pack, "Completed");
updateDLcount udl = new updateDLcount();
udl.execute("hello");
//updateCancelInstall();
notificationManager.cancel(42);
} else {
showNotification("Download Error", "Failed to download "+pack, "Error");
//updateCancelInstall();
notificationManager.cancel(42);
}
}
}
}
protected RemoteViews getProgressView(int currentNumFile, int totalNumFiles, int currentReceivedBytes, int totalNumBytes)
{
return null;
}
protected Class<?> getIntentForLatestInfo()
{
return DisplayApp.class;
}
protected void showNotification(String ticker, String title, String content)
{
Notification notification = new Notification(R.drawable.download_icon, ticker, System.currentTimeMillis());
Intent i=new Intent(this, DisplayApp.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
i.putExtra("id", itemId);
i.putExtra("IorU", "itemStatus");
i.putExtra("progrss", content);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, i, 0);
notification.setLatestEventInfo(getApplicationContext(), title, content, contentIntent);
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(42, notification);
if(content.equalsIgnoreCase("Cancelled")||content.equalsIgnoreCase("Completed")||CN)notificationManager.cancel(42);
}
protected void updateProgress(int downsize, int totalsize, boolean cancel){
//Log.i("YYYY","cancel="+cancel);
if(!cancel || (downsize<totalsize)){
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressbar);
TextView pb_t = (TextView) findViewById(R.id.progressbar_text);
progressBar.setVisibility(0);
pb_t.setVisibility(0);
progressBar.setProgress((int)downsize*100/totalsize);
pb_t.setText(String.format("%s / %s", getStringByteSize(downsize), getStringByteSize(totalsize)));
} else {
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressbar);
TextView pb_t = (TextView) findViewById(R.id.progressbar_text);
progressBar.setProgress(100);
progressBar.setVisibility(4);
pb_t.setVisibility(4);
updateCancelInstall();
}
}
protected void showNotification(RemoteViews remoteView, String ticker)
{
Notification notification = new Notification(R.drawable.download_icon, ticker, System.currentTimeMillis());
notification.contentView = remoteView;
Intent i=new Intent(this, DisplayApp.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
notification.contentIntent = PendingIntent.getActivity(this, 0, i, 0);
//Log.d("YYYY","2:"+notification.contentIntent.toString());
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(42, notification);
}
Appreciate if you can help me by code, url or any documentations that mimics the market way of doing this.
Thanks
I have used singleInstance in the launchMode of my activity, the activity comes to front with the progress bar progressing along with the download.
I figured out that it get confused only if I moved back and then home then click notification bar, this obvious since clicking back will destroy my activity and I loose history so my work around was to disable the back key in my activity and let the application user navigate through my UI menu and button.
I know there should be away to store my activity instance and retrieve it later no matter what happened to the history/stack but so far the above is enough for me!!
Thanks,
In your AndroidManifest.xml file try adding under the activity you wish to return to the line android:launchMode="singleTop". For example:
<activity android:name=".MainLayout"
android:label="#string/app_name"
android:launchMode="singleTop">
This will prevent a new instance of your activity being created and will route the intent to any current instances of your activity. For more info see here.
Related
I read all of the solutions about this problem.Also I know it can be considered as duplicated but it is not.
I see Error: Try Again toast message and I see Update Error log message.
I think at android v26 changed somethings about intent.setDataAndType or I dont know why this is not working.
Also I get the permissions something like this code
ActivityCompat.requestPermissions(Update.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
Problem can not be solved. I just want to do download and install apk file.
AndroidManifest.xml (I added write permission)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Update.java
package com.my.testapp;
public class Update extends AppCompatActivity {
ProgressDialog bar;
private static String TAG = "Update";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadNewVersion().execute();
}
class DownloadNewVersion extends AsyncTask<String,Integer,Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
bar = new ProgressDialog(Update.this);
bar.setCancelable(false);
bar.setMessage("Downloading...");
bar.setIndeterminate(true);
bar.setCanceledOnTouchOutside(false);
bar.show();
}
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
bar.setIndeterminate(false);
bar.setMax(100);
bar.setProgress(progress[0]);
String msg = "";
if(progress[0]>99){
msg="Finishing... ";
}else {
msg="Downloading... "+progress[0]+"%";
}
bar.setMessage(msg);
}
#Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
bar.dismiss();
if(result){
Toast.makeText(getApplicationContext(),"Update Done",
Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),"Error: Try Again",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected Boolean doInBackground(String... arg0) {
Boolean flag = false;
try {
URL url = new URL("http://mydownloadurl.com/_download/update.apk");
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory()+"/Download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file,"app-debug.apk");
if(outputFile.exists()){
outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
int total_size = 277962;//size of apk
byte[] buffer = new byte[1024];
int len1 = 0;
int per = 0;
int downloaded=0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
downloaded +=len1;
per = (int) (downloaded * 100 / total_size);
publishProgress(per);
}
fos.close();
is.close();
OpenNewVersion(PATH);
flag = true;
} catch (Exception e) {
Log.e(TAG, "Update Error: " + e.getMessage());
flag = false;
}
return flag;
}
}
void OpenNewVersion(String location) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(location + "app-debug.apk")),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
Commonsware thanks a lot, I waste my 2-3 hours to do different ways.
Actually I added this code before but the problem was not solved.
I tried again and it worked, it might be lazy solution but it is working.
This url have more info about the problem ,other solutions can be applied,
but it is enough for me.
if(Build.VERSION.SDK_INT>=24){
try{
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
}catch(Exception e){
e.printStackTrace();
}
}
It is totally fixed thank you very much again.
Application also need this storage permission.
ActivityCompat.requestPermissions(Update.this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE
I have good concept of starting and using the basic service. I mean not to complicated. In My app I want a service which should not be killed in any situation and should download some files from the server then it should call stopSelf. I have made my service in the following way. But before sharing its whole code just let me tell you what I am doing
In Service I am passing the series of url (string array) which has to download all files from the server.
I am using the async task to download from the server.
Under this whole process I am getting a 1st response that is in xml then I parse it , and get the JSON string (sorry about that my web service designer is a numb like me). so after these two conversion I store the data in the database and then starts downloading files and saving them to device and store their path in the database. (this all works fine)
I am calculating and updating progress in the notification bar. (showing user how much the files has been downloaded)
what I really want
I want that my service should not be killed when user removes it from the recent app list , so that it should continue to download and continue to update the status in notification bar. I am using Notification manager to update the progress.
What is really happening
When I close my app from recent app tray, I think my service gets killed and the downloading process stops, and It also stops updating the progress of notification in notification bar, Where As I want it to continue to run until the download process is finished.
Here is my code it is simplified as some methods are really not worthy
to be discussed here Such as Parsing the xml or JSON
Here is the Code
public class MyDemoService extends Service {
private static final String TAG = "MyDemoService";
private static final int NOTIFICATION_ID = 1;
private LocalBinder m_binder = new LocalBinder();
private NotificationManager mNotifyManager;
private NotificationCompat.Builder mBuilder;
myAsyncTask myWebFetch;
// Timer to update the ongoing notification
private final long mFrequency = 100; // milliseconds
private final int TICK_WHAT = 2;
public class LocalBinder extends Binder {
MyDemoService getService() {
return MyDemoService.this;
}
}
private Handler mHandler = new Handler() {
public void handleMessage(Message m) {
updateNotification();
sendMessageDelayed(Message.obtain(this, TICK_WHAT), mFrequency);
}
};
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "bound");
return m_binder;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "created");
mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.d(TAG, "Removed");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "Destroyed");
}
public void updateNotification() {
// Log.d(TAG, "updating notification");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
}
public void hideNotification() {
Log.d(TAG, "removing notification");
mNotifyManager.cancel(NOTIFICATION_ID);
mHandler.removeMessages(TICK_WHAT);
}
public void start() {
Log.d(TAG, "start");
mBuilder =
new NotificationCompat.Builder(MyDemoService.this)
.setSmallIcon(R.drawable.download)
.setContentTitle("SMU")
.setContentText("Downloading Images");
Intent targetIntent = new Intent(MyDemoService.this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(MyDemoService.this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(contentIntent);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
myWebFetch = new myAsyncTask();
myWebFetch.execute();
}
class myAsyncTask extends AsyncTask<String, Integer, Void> {
MyDB myDB;
myAsyncTask() {
myDB = new MyDB(MyDemoService.this);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mBuilder.setContentText("Download complete");
// Removes the progress bar
mBuilder.setProgress(0, 0, false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mBuilder.setProgress(100, values[0], false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
}
#Override
protected Void doInBackground(String... params) {
//set the download URL, a url that points to a file on the internet
getJSON("http://*****", 1000000);
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mBuilder.setProgress(100, 0, false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
}
public void getJSON(String url, int timeout) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(timeout);
c.setReadTimeout(timeout);
c.setInstanceFollowRedirects(false);
c.connect();
int status = c.getResponseCode();
if (status == 200) {
String readStream = readStream(c.getInputStream());
if (readStream != null) {
JsonParser mJsonParser = new JsonParser(MyDemoService.this);
mJsonParser.parseJaSon(readStream);
ArrayList<SuitDetails> mImageList = new ArrayList<>(myDB.GetAllData());
if (mImageList != null) {
//NOW HERE DOWNLOADING IMAGES FROM URL WE GOT SAVED IN DB AFTER PARSING
downloadImages(mImageList);
}
}
}
} catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
}
#TargetApi(Build.VERSION_CODES.KITKAT)
private String readStream(InputStream in) {
//parsing my input stream and sending back string
return jsonString.toString();
}
void downloadImages(ArrayList<SuitDetails> arrayList) {
try {
ArrayList<SuitDetails> imageUrl = arrayList;
URL url;
float progressImages = 0;
HttpURLConnection urlConnection = null;
for (int i = 0; i < imageUrl.size(); i++) {
progressImages += 100 / imageUrl.size();
publishProgress((int) progressImages);
url = new URL(imageUrl.get(i).getPath().toString());
//create the new connection
urlConnection = (HttpURLConnection) url.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(false);
urlConnection.setUseCaches(false);
urlConnection.setAllowUserInteraction(false);
urlConnection.setConnectTimeout(60000);
urlConnection.setReadTimeout(60000);
urlConnection.setInstanceFollowRedirects(false);
//and connect!
urlConnection.connect();
File storagePath = new File(MyDemoService.this.getExternalFilesDir("TEST") + "/Mytest");
storagePath.mkdirs();
String finalName = imageUrl.get(i).getImageName();
File myImage = new File(storagePath, finalName + ".png");
FileOutputStream fileOutput = new FileOutputStream(myImage);
InputStream inputStream = urlConnection.getInputStream();
int totalSize = urlConnection.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
}
//close the output stream when done
ContentValues contentValues = new ContentValues();
contentValues.put("Status", "1");
contentValues.put("Path", myImage.getPath().toString());
myDB.UpdateDownloadStatus(contentValues, imageUrl.get(i).getSImageID());
fileOutput.close();
}
myDB.closeDb();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I Know this is length code but sharing if You want to analyse it deeply.
I will provide how I am using and calling this service in MainActivity if you demand it
why are you not using an IntentService if you want to do network stuff?
you should consider adding setIntentRedelivery(true); in your constructor
from the documentation
Sets intent redelivery preferences. Usually called from the
constructor with your preferred semantics.
If enabled is true, onStartCommand(Intent, int, int) will return
START_REDELIVER_INTENT, so if this process dies before
onHandleIntent(Intent) returns, the process will be restarted and the
intent redelivered. If multiple Intents have been sent, only the most
recent one is guaranteed to be redelivered.
If enabled is false (the default), onStartCommand(Intent, int, int)
will return START_NOT_STICKY, and if the process dies, the Intent dies
along with it.
I just wonder that is it possible to make progressbar in notification and open an activity when click it.
Let's make a sample:
I have Activity A, B and C which C is file upload Activity with progressbar and notification.
So, when i click HOME button and then click notification icon i want to back to Activity C, Clicking back button go to Activity B and clicking again go to Activity A.
Here is my Fileupload and notification class
Activity C
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_c);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.x = -20;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
params.height = 750;
params.width = 550;
}
else
{
params.height = 550;
params.width = 750;
}
params.y = -10;
this.getWindow().setAttributes(params);
pg = (ProgressBar) findViewById(R.id.progressBar1);
pg.setProgress(0);
new RunProgress().execute();
}
public class RunProgress extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute()
{
if(extraFlag == 0)
{
// Call Notification method
// backup is executed
displayNotification();
}
super.onPreExecute();
}
#Override
protected String doInBackground(String... params)
{
for (int i = 0; i < fileName.size(); i++)
{
name = fileName.get(i);
WebDav writer = new WebDav(getApplicationContext(),
name);
try
{
x += percentage;
publishProgress("" + x);
writer.uploadFile(name);
if (isCancel)
break;
File file = new File(new FilePathClass().returnSimple()
+ name);
file.delete();
}
catch (Exception e)
{
system.out.println(e.toString());
}
}
return null;
}
#Override
protected void onProgressUpdate(String... progress)
{
pg.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String result)
{
// This makes Notification icon CLEAR
myNotificationManager.cancelAll();
}
}
and notification method
private void displayNotification()
{
n = new Notification.Builder(getApplicationContext());
n.setContentTitle(getResources().getString(R.string.msg_action_bar_title));
n.setTicker("Uploading...");
n.setContentText("Upload progress started");
n.setSmallIcon(R.drawable.ic_launcher);
// This makes return to Same Activity
// when clicking notification icon
Intent i = new Intent(getApplicationContext(), ActivityC.class);
// i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("extraFlag", 1);
i.putStringArrayListExtra("fileName", fileName);
i.putExtra("numberOfContacts", fileName.size());
TaskStackBuilder stackBuilder = TaskStackBuilder.create(ActivityC.this);
stackBuilder.addParentStack(ActivityC.class);
stackBuilder.addNextIntent(i);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_ONE_SHOT);
n.setContentIntent(pendingIntent);
myNotificationManager = (NotificationManager) getSystemService(ActivityC.NOTIFICATION_SERVICE);
if (currentApiVersion < 16)
myNotificationManager.notify(0, n.getNotification());
else
myNotificationManager.notify(0, n.build());
}
Call setLatestEventInfo() on the Notification object, supplying a PendingIntent that will start your activity when they tap on your entry in the notification drawer.
Check out this sample.
I'm trying to make my app download an expansion file. Here's my code so far.
public class main extends Activity implements IDownloaderClient {
TextView tv1;
Button mcButt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//////////
tv1 = (TextView)findViewById(R.id.textView1);
// Check whether the file have been downloaded.
String mainFileName = Helpers.getExpansionAPKFileName(this, true, 1);
boolean fileExists = Helpers.doesFileExist(this, mainFileName, 32921796L, false);
if (!fileExists) {
Intent launcher = getIntent();
Intent fromNotification = new Intent(this, getClass());
fromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
fromNotification.setAction(launcher.getAction());
if (launcher.getCategories() != null) {
for (String cat : launcher.getCategories())
{ fromNotification.addCategory(cat); }
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, fromNotification, PendingIntent.FLAG_UPDATE_CURRENT);
try {
int result = DownloaderClientMarshaller.startDownloadServiceIfRequired( this, pendingIntent, ExpansionFileDownloaderService.class);
if (DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED != result) {
// implement Downloading UI.
tv1.setText("Need to download.");
return;
}
} catch (Exception e) {
Log.e("apk-expansion-files", "NameNotFoundException occurred. " + e.getMessage(), e);
}
}
tv1.setText("Downloaded!");
}
///////////////////////////////////////////////////
#Override
public void onServiceConnected(Messenger m) {
tv1.setText("onServiceConnected: " + m.toString() );
}
///////////
#Override
public void onDownloadStateChanged(int newState) {
tv1.setText("onDownloadStateChanged: " + String.valueOf(newState) );
}
////////////
#Override
public void onDownloadProgress(DownloadProgressInfo progress) {
ProgressBar mPB = (ProgressBar)findViewById(R.id.progressBar1);
progress.mOverallTotal = progress.mOverallTotal;
mPB.setMax((int) (progress.mOverallTotal >> 8));
mPB.setProgress((int) (progress.mOverallProgress >> 8));
tv1.setText(Long.toString(progress.mOverallProgress * 100 / progress.mOverallTotal) + "%");
tv1.setText(Helpers.getDownloadProgressString(progress.mOverallProgress,progress.mOverallTotal));
}
}
The file does download fine, but it does not trigger onDownloadProgress or onDownloadStateChanged during or after download.
What comes to mind, is that DownloaderClientMarshaller need to be somehow connected with IDownloaderClient which is implemented into the activity...
Any ideas? Thanks!
You should create and stub and connect it to the context. Then, the events will be sent to your IDownloaderClient.
if (DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED != result) {
downloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
YourDownloaderServiceClass.class);
downloaderClientStub.connect(this);
}
in my app i have 4 buttons and when the user clicks any of the button it starts downloading a file and the progress bar gets shown in the notification area. The downloading and progress bar is working fine, but i have the following two problems
When the download completes the progress bar is not getting closed, it remains in the notification area
As i said above i have 4 buttons and when the first button is clicked download gets started and when the other three buttons are clicked immediately download is not taking place. I thought it may start after first download completes. But nothing happens. How to show all the progress bar when all buttons clicked
Following is my code(here i have added only 2 buttons) pls help me
b1 = (Button)findViewById(R.id.button1);
b1.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
i =1;
Intent intent = new Intent(NotificationProgressTestActivity.this, UploadService.class);
startService(intent);
}
});
b2 = (Button)findViewById(R.id.button2);
b2.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
i = 2;
Intent intent = new Intent(NotificationProgressTestActivity.this, UploadService.class);
startService(intent);
}
});
Next following is my Uplaod Service.class
public class UploadService extends IntentService
{
private NotificationManager notificationManager;
private Notification notification;
private int progress = 10;
private static String fileName = "folder/";
private static URL url;
public UploadService(String name)
{
super(name);
}
public UploadService()
{
super("UploadService");
}
#Override
protected void onHandleIntent(Intent intent)
{
notificationManager = (NotificationManager) getApplicationContext().getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
notification = new Notification(R.drawable.icon,"Uploading file", System.currentTimeMillis());
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.upload_progress_bar);
notification.contentIntent = contentIntent;
notification.contentView.setProgressBar(R.id.progressBar1, 100, progress, false);
notificationManager.notify(42, notification);
notificationManager.notify(42, notification);
Thread download = new Thread()
{
#Override
public void run()
{
Log.e("download", "start");
try
{
for (int i = 1; i < 100; i++)
{
progress++;
notification.contentView.setProgressBar(R.id.progressBar1, 100, progress, false);
if(i==1)
{
if(NotificationProgressTestActivity.i ==1 )
{
url = new URL("http://xxxxxxxxxxxxxxxx.mp4");
}
else if(NotificationProgressTestActivity.i == 2)
{
url = new URL("http://xxxxxxxxxxxxxxxx.mp4");
}
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory()+ "/";
Log.e("PATH:", PATH);
File file = new File(PATH);
if (!file.exists())
{
file.mkdir();
Log.e("destination", "created");
}
else
{
Log.e("destination", "exist");
}
File outputFile = new File(file, fileName);
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[10171188];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1)
{
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
// -----------------------
if (!outputFile.exists())
{
Log.e(outputFile.toString(), "not created");
}
else
{
Log.e(outputFile.toString(), "created");
Log.e(outputFile.toString(), "" + outputFile.length());
}
Log.e("download", "end");
}
notificationManager.notify(42, notification);
try
{
Thread.sleep(1017);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
catch (IOException e)
{
Log.e("log_tag", "Error: " + e);
}
Log.e("log_tag", "Check: ");
// remove the notification (we're done)
notificationManager.cancel(42);
}
};
download.run();
}
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
1- in this above line, the 2nd parameter in getActivity() is requestCode, it should be a unique number for each button. currently it is 0 for both buttons.
notificationManager.notify(42, notification);
2- in the above line, the notification index you are passing as 42, it should be unique for both buttons. currently no matter how many buttons you create it will never show you a new notification because you are passing 42 for each. it will keep updating the current one.
also you might need to look again the code you are doing in onHandleIntent(). there are better ways to do this.
What you need is an AsyncTask and a ListView.
Your downloadmagic happens in AsyncTask.
Make for example an Array that indicates which download is running and the progress of each running download.
Now in your AsyncTask there is a publishProgress-Method which calls onProgressUpdate.
In onProgressUpdate you have to update the respective progress-variable and call notifyDataSetChanged on your ListView Adapter.
This will cause the ListView to reload all Data.
Finally in your ListView-Adapter you got a Method getView, where you have to create the View for each row of your ListView.
There you can decide to show the ProgressBar (download running) or not.
More Information about AsyncTask can be found here: http://labs.makemachine.net/2010/05/android-asynctask-example/
And more about the ListView here: Android : BaseAdapter how to?