I do understand the basics of try and catch in as much as you try some code and look for errors that occur and catch them and then do something based on the error. I have code that when run looks for a complete video file exists on the SD card it plays the video if it is not complete it downloads it to the SD card then I want it to play.
here is my code block
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Window;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;
public class VideoActivity extends Activity {
private static final String TAG = "MyActivity";
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
public static final Context ACTION_VIEW = null;
private ProgressDialog mProgressDialog;
public String url = "";
public String fName = "";
public String vidName = "";
public String path="";
//final VideoView videoView = (VideoView) findViewById(R.id.videoView1);
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
final String[] myAPP_FILES = getResources().getStringArray(R.array.APP_FILES);
final String[] myAPP_FILENAMES = getResources().getStringArray(R.array.APP_FILENAMES);
final String[] myAPP_NAMES = getResources().getStringArray(R.array.APP_NAMES);
final int[] myAPP_SIZES = getResources().getIntArray(R.array.APP_SIZES);
setContentView(R.layout.video);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
final VideoView videoView = (VideoView) findViewById(R.id.videoView1);
final MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
Bundle extras = getIntent().getExtras();
url = myAPP_FILES[extras.getInt("key") ];
fName = myAPP_FILENAMES[extras.getInt("key") ];
vidName = myAPP_NAMES[extras.getInt("key") ];
int fsize = (myAPP_SIZES[extras.getInt("key") ] -1 )*1000;
File file1 = new File(Environment.getExternalStorageDirectory(), fName );
if (file1.exists()) {
if(file1.length() < fsize) {
file1.delete();
}
}
loadMedia();
Toast.makeText(
getApplicationContext(),
"" + file1.length()+ " " + fsize,
Toast.LENGTH_LONG).show();
String pathfile = Environment.getExternalStorageDirectory() + "/" +fName;
try {
Uri video = Uri.parse(pathfile);
videoView.setMediaController(mediaController);
videoView.setVideoURI(video);
videoView.start();
} catch (Exception w) {}
}
private void loadMedia() {
//Check for media file download if not on sdcard
File file = new File(Environment.getExternalStorageDirectory(), fName );
if (!file.exists()) {
new DownloadFileAsync().execute(url);
}
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading to SD: " + vidName + "\n...Please allow download to finish completely...");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lengthOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Length of file: " + lengthOfFile);
InputStream input = new BufferedInputStream(url.openStream(), 1024);
OutputStream output = new FileOutputStream("/sdcard/" + fName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lengthOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
}
In operation a spinner is displayed and the user can select a video. It then checks to see if the file exists on the SD card if it is not it starts the download and a progress bar is displayed. Here is the problem At that time a message pops up that says:
CANNOT PLAY VIDEO
Sorry, this video cannot be played.
the download is progressing in the background and I can see the progress bar but it is darkened down
I do not want this message to appear.
I want to catch this and do nothing so the message will not appear
In the code I process the loadmedia function and then I set the video to play. I need to try and catch this step looking for this error message but I do not know what to look for
in my logcat I see this
02-02 09:35:29.257: W/MediaPlayer(13311): info/warning (1, 26)
02-02 09:35:29.257: E/MediaPlayer(13311): error (1, -4)
02-02 09:35:29.277: I/MediaPlayer(13311): Info (1,26)
02-02 09:35:29.277: E/MediaPlayer(13311): Error (1,-4)
02-02 09:35:29.277: D/VideoView(13311): Error: 1,-4
I think it is included here but I don't know how to translate this into a valid try and catch routine
Hopefully someone can help
To catch an exception an exception must be thrown. Looks like you're already catching the base level Exception which would catch any uncaught exception from the media player layer. Therefore, they're not throwing any that they aren't catching themselves.
So this isn't about catching exceptions at this point but registering to receive notification of errors that the framework provides. Looking here shows a way to register a listener for errors. Whether that means that the error won't show up as you've described is unknown. I suspect it'll still show. But you may have no control over that.
Related
On Android, I want to play TextToSpeech output through only one sound channel (think Shoulder Angel). To do this, I am currently using tts.synthesizeToFile(), and then playing back the dynamically-created file using the MediaPlayer. I use mediaPlayer.setVolume(0.0f, 1.0f) to play the audio through only one channel.
My working code is below.
My question is: is there a more direct way of playing TTS output through a single channel?
Using TextToSpeech to synthesize the file is time-consuming, and using MediaPlayer to play it back uses more resources than strictly necessary. I want this to be responsive and to work on low-end devices, so being kind to the CPU is important.
MainActivity.java
package com.example.pantts;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.speech.tts.TextToSpeech;
import android.os.Bundle;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Locale;
public class MainActivity extends Activity implements TextToSpeech.OnInitListener {
private TextToSpeech tts;
private String toSpeak = "Hello, right ear!";
private static final String FILE_ID = "file";
private HashMap<String, String> hashMap = new HashMap<String, String>();
private String filename;
private TextToSpeech tts;
private MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
filename = getFilesDir() + "/" + "tts.wav";
Log.d("LOG", "file: " + filename);
// /data/data/com.example.pantts/files/tts.wav
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
tts = new TextToSpeech(this, this);
tts.setOnUtteranceProgressListener(mProgressListener);
}
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.UK);
hashMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, FILE_ID);
// Using deprecated call for API 20 and earlier
tts.synthesizeToFile(toSpeak, hashMap, filename);
Log.d("LOG", "synthesizeToFile queued");
}
}
private UtteranceProgressListener mProgressListener =
new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
Log.d("LOG", "synthesizeToFile onStart " + utteranceId);
}
#Override
public void onError(String utteranceId) {
Log.d("LOG", "synthesizeToFile onError " + utteranceId);
}
#Override
public void onDone(String utteranceId) {
if (utteranceId.equals(FILE_ID)) { // Thanks to Hoan Nguyen for correcting this
Log.d("LOG", "synthesizeToFile onDone " + utteranceId);
try {
File ttsFile = new File(filename);
FileInputStream inputStream = new FileInputStream(ttsFile);
FileDescriptor fileDescriptor = inputStream.getFD();
mediaPlayer.reset();
mediaPlayer.setDataSource(fileDescriptor);
inputStream.close();
mediaPlayer.prepare();
mediaPlayer.setVolume(0.0f, 1.0f); // right channel only
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
}
There is nothing wrong with the synthesize, it is the comparison that is wrong. It should be
if (utteranceId.equals(FILE_ID))
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
i am trying to download this file from url in android and also save file in SD card ....
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private ProgressBar bar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bar=(ProgressBar)findViewById(R.id.progressBar1);
new DownloadFileFromURL().execute("http://hrdevcontentapi.spanunit.com/000132/538/HCDocument/the_hatha_yoga_pradipika.docx");
}
/**
* 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 {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream("/sdcard/downloadedfile.docx");
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;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
bar.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task
* Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
File targetFile = new File("/sdcard/downloadedfile.docx");
Uri targetUri = Uri.fromFile(targetFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(targetUri, "application/*");
startActivityForResult(intent, 100);
}
}
}
This is the activity.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.test.MainActivity" >
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
And this is the activity_main.xml
Don't forget to add the following permissions:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
For further details check this link:http://www.androidhive.info/2012/04/android-downloading-file-by-showing-progress-bar/
Try using DownloadManager, it's very easy to use and good at long running download tasks.
import java.io.FileInputStream;
import android.app.Activity;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.ImageView;
public class Test extends Activity
{
private static final String DL_ID = "downloadId";
private SharedPreferences prefs;
private DownloadManager dm;
private ImageView imageView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageView = new ImageView(this);
setContentView(imageView);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
dm = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
}
#Override
public void onResume() {
super.onResume();
if(!prefs.contains(DL_ID)) {
Uri resource = Uri.parse("http://asdf.com/big.jpg");
DownloadManager.Request request = new DownloadManager.Request(resource);
request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);
request.setAllowedOverRoaming(false);
request.setTitle("Download Sample");
long id = dm.enqueue(request);
prefs.edit().putLong(DL_ID, id).commit();
} else {
queryDownloadStatus();
}
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
queryDownloadStatus();
}
};
private void queryDownloadStatus() {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(prefs.getLong(DL_ID, 0));
Cursor c = dm.query(query);
if(c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
Log.d("DM Sample","Status Check: "+status);
switch(status) {
case DownloadManager.STATUS_PAUSED:
case DownloadManager.STATUS_PENDING:
case DownloadManager.STATUS_RUNNING:
break;
case DownloadManager.STATUS_SUCCESSFUL:
try {
ParcelFileDescriptor file = dm.openDownloadedFile(prefs.getLong(DL_ID, 0));
FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(file);
imageView.setImageBitmap(BitmapFactory.decodeStream(fis));
} catch (Exception e) {
e.printStackTrace();
}
break;
case DownloadManager.STATUS_FAILED:
dm.remove(prefs.getLong(DL_ID, 0));
prefs.edit().clear().commit();
break;
}
}
}
}
Ckeck Out This Link
hello i used code below and i run the project in android 3.0 tablet emulator in android application nad i get path /mnt/sdcard/ but not get fullpath.how solve it ?please help me!!And my code below
![package com.hope.project;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.content.Context;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
WebView myWebView;
TextView mDisplay;
AsyncTask<Void, Void, Void> mRegisterTask;
String name;
String Message;
String deviceId;
String regId;
IntentFilter gcmFilter;
SharedPreferences sharedPref;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myWebView = (WebView) findViewById(R.id.webView1);
final JavaScriptInterface myJavaScriptInterface = new JavaScriptInterface(
this);
myWebView.addJavascriptInterface(myJavaScriptInterface,
"AndroidFunction");
WebSettings settings = myWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
settings.setBuiltInZoomControls(true);
settings.setUseWideViewPort(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setLoadWithOverviewMode(true);
myWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
myWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// handle stuff here
// e.g. view.loadUrl(url);
Log.v("log", " on ovverRide " + url);
return true;
}
public void onPageFinished(WebView view, String url) {
// dismiss the indeterminate progress dialog
Log.v("log", "onPageFinished: " + url);
myWebView.setEnabled(false);
}
});
myWebView.loadUrl("file:///android_asset/www/index.html");
/* File urlName= Environment.getExternalStorageDirectory().getAbsoluteFile();
Log.v("log_tag", "urlNameDownload "+urlName);*/
/* File file\[\] = Environment.getExternalStorageDirectory().listFiles();
for (File f : file)
{
if (f.isDirectory()) {
String uri=f.getPath().substring(f.getPath().lastIndexOf("/") + 1);
Log.v("Name", uri);
Log.v("Name", f.getPath()+ "");
Log.v("Name", f.getAbsolutePath()+ "");
}
}*/
File dir = new File("mnt/sdcard/");
File\[\] files = (new File("mnt/sdcard/")).listFiles();
// This filter only returns directories
FileFilter dirFilter = new FileFilter() {
public boolean accept(File dir) {
return dir.isDirectory();
}
};
files = dir.listFiles(dirFilter);
for (int i=0; i<files.length; i++) {
if(files\[i\].getAbsolutePath().contains("Download"))
Log.v("log_tag","directory path : " + files\[i\].getAbsolutePath().substring(files\[i\].getAbsolutePath().lastIndexOf("/") +1));
}
}
protected void onDestroy() {
super.onDestroy();
}
public class JavaScriptInterface {
Context mContext;
JavaScriptInterface(Context c) {
mContext = c;
}
public void DownloadUrl(String url) {
Log.v("log", "login main url " + url);
String file_url = url;
new DownloadFileFromURL().execute(file_url);
/*
* String url_new = "http://"+url; Intent i = new
* Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url_new));
* startActivity(i);
*/
}
}
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
// showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
int count;
Log.v("log", "login main url\[0\] " + f_url\[0\]);
try {
URL url = new URL(f_url\[0\]);
name = f_url\[0\].substring(f_url\[0\].lastIndexOf("/") + 1);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream to write file
// OutputStream output = new
// FileOutputStream("/sdcard/downloadedfile.jpg");
OutputStream output = new FileOutputStream(
Environment.getExternalStorageDirectory() + "/Download/" + name);
// OutputStream output = new
// FileOutputStream("/sdcard/downloadedUrl.mp4");
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;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
// pDialog.setProgress(Integer.parseInt(progress\[0\]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
// dismissDialog(progress_bar_type);
// Displaying downloaded image into image view
// Reading image path from sdcard
/*
* Log.v("log","login main url\[0\] " +
* Environment.getExternalStorageDirectory().toString()); String
* videoPath = Environment.getExternalStorageDirectory() +"/"+name;
* Intent i = new Intent(MainActivity.this,
* VideoPlayActivity.class); i.putExtra("videoPath", videoPath);
* startActivity(i);
*/
Toast.makeText(MainActivity.this, "DownLoad Is Completed",
Toast.LENGTH_LONG).show();
}
}
}
Instead of hardcoding mnt/sdcard/ you should use the Environment object.
Specifically:
File dir = Environment.getExternalStorageDirectory();
Will give you a file object that is automatically pointing in the proper place for the External Storage of the device that it is running on.
Also, you've posted your entire Activity. The vast majority of it is unrelated to the problem you are having. In the future it is more likely that you'll get good help on StackOverflow if you take out a smaller section of your code that specifically relates to the problem you are having. It makes it easier for people who are answering to figure out your situation.
I've read almost every similar topic but I couldn't find a solution. So I decided to ask my own.
I want to download a file and show a progress dialog during the operation. The file gets downloaded successfully.
The first problem is that the progress bar doesn't update during the download operation. It just stays %0 and when the download is finished, the dialog disappears as expected.
The second problem is - I noticed this by accident - when my activity gets updated (for example, when screen orientation is changed) the dialog disappears but the download continues.
I hope someone can help.
Here's my code:
package com.mehmetakiftutuncu.downloadunzipshow;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener
{
final String LOG_TAG = "DownloadUnzipShow";
final String RELATIVE_PATH = "mehmetakiftutuncu";
final String FILE_NAME = "...";
final String FILE_URL = "...";
final String FULL_PATH = Environment.getExternalStorageDirectory().getPath() + "/" + RELATIVE_PATH + "/";;
Button buttonDownload, buttonUnzip, buttonShow;
ProgressDialog progressDialog;
public class MyFileDownloader extends AsyncTask<String, String, String>
{
boolean isSuccessful = true;
InputStream inputStream;
OutputStream outputStream;
#Override
protected void onPreExecute()
{
super.onPreExecute();
prepareProgressDialog();
Log.d(LOG_TAG, "Downloading: " + FILE_URL + " to " + FULL_PATH + FILE_NAME);
}
#Override
protected String doInBackground(String... params)
{
int count;
try
{
URL url = new URL(params[0]);
URLConnection connection = url.openConnection();
connection.connect();
int lengthOfFile = connection.getContentLength();
File path = new File(FULL_PATH);
if(!path.exists())
{
path.mkdir();
}
inputStream = new BufferedInputStream(url.openStream());
outputStream = new FileOutputStream(FULL_PATH + FILE_NAME);
byte[] data = new byte[1024];
long total = 0;
int percentage = 0;
while((count = inputStream.read(data)) != -1)
{
total += count;
percentage = (int) ((total / lengthOfFile) * 100);
publishProgress(String.valueOf(percentage));
outputStream.write(data, 0, count);
}
outputStream.flush();
outputStream.close();
inputStream.close();
}
catch(Exception e)
{
isSuccessful = false;
Log.e(LOG_TAG, "An error occured while downloading. Details: " + e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(String... values)
{
super.onProgressUpdate(values);
progressDialog.setProgress(Integer.parseInt(values[0]));
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
if(isSuccessful)
{
Log.d(LOG_TAG, "File is successfully downloaded to: " + FULL_PATH + FILE_NAME);
}
progressDialog.dismiss();
}
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonDownload = (Button) findViewById(R.id.button_download);
buttonDownload.setOnClickListener(this);
}
private void prepareProgressDialog()
{
progressDialog = new ProgressDialog(this);
progressDialog.setTitle(getString(R.string.dialog_title));
progressDialog.setMessage(getString(R.string.dialog_message) + FILE_URL);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(100);
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.button_download:
new MyFileDownloader().execute(FILE_URL);
break;
}
}
}
The first problem is that the progress bar doesn't update during the
download operation. It just stays %0 and when the download is
finished, the dialog disappears as expected.
That is happening because the line:
percentage = (int) ((total / lengthOfFile) * 100);
always return 0 as you're doing an integer java division where total is smaller than lengthOfFile. Make total a double value. Also don't cast the percentage as a String, modify the second generic argument of the AsyncTask to be an Integer.
The second problem is - I noticed this by accident - when my activity
gets updated (for example, when screen orientation is changed) the
dialog disappears but the download continues.
On a configuration change(a rotation for example) the Activity will be recreated killing your dialog in the process. If you want to re-show the dialog you'll need to keep the AsyncTask across the configuration change by passing it to the onRetainNonConfigurationInstance() method of the Activity(or you could use fragments). In the onCreate method use getLastNonConfigurationInstance to see if you have a task retained and still running and reshow the dialog. Also you really shouldn't make the AsyncTask a inner class in the Activity because you'll tie it to the activity.
THe dialog disappearing- are you capturing orientation config changes, or are you letting Android do it? If you're letting Android do it, it will kill your activity and recreate it, which will destroy your dialog. The async task wouldn't get killed because the async task is owned by the system. To fix that, add android:configChange="orientation" to your manifest for the activity. General rule of thumb is if you want to have dialogs persist through rotation you need to do that.
I am trying to unzip a file located on SDCARD of Android device.
If the ZIP file only contains files NOT FOLDERS everything is fine. However the production file that I want the app to unzip contains multiple directories and sub-directories. This is where I run into issues.
The code isnt creating the folder structure required. If I manually create the folders prior to running the class it unzips as planned, but in the future I wont know the directory structure and need the code to create the proper folder structure.
Here is the code I'm working with
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
public class HomeActivity extends Activity
{
private TextView tv;
private static final String ROOT_FOLDER = Environment.getExternalStorageDirectory()
+ File.separator + "FacebookPhotos";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.tv);
tv.append("Reading zip file from assets folder...");
// Start the unzipping process
thread.start();
}
private Thread thread = new Thread()
{
#Override
public void run()
{
sendMessage("-----------------------------------------------");
// Create a directory in the SDCard to store the files
File file = new File(ROOT_FOLDER);
if (!file.exists())
{
file.mkdirs();
}
else
{
file.delete();
}
try
{
// Open the ZipInputStream
ZipInputStream inputStream = new ZipInputStream(new FileInputStream("/sdcard/Photos/photos.zip"));
// Loop through all the files and folders
for (ZipEntry entry = inputStream.getNextEntry(); entry != null; entry = inputStream
.getNextEntry())
{
sendMessage("Extracting: " + entry.getName() + "...");
String innerFileName = ROOT_FOLDER + File.separator + entry.getName();
File innerFile = new File(innerFileName);
if (innerFile.exists())
{
innerFile.delete();
}
// Check if it is a folder
if (entry.isDirectory())
{
// Its a folder, create that folder
innerFile.mkdirs();
}
else
{
// Create a file output stream
FileOutputStream outputStream = new FileOutputStream(innerFileName);
final int BUFFER = 2048;
// Buffer the output to the file
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream,
BUFFER);
// Write the contents
int count = 0;
byte[] data = new byte[BUFFER];
while ((count = inputStream.read(data, 0, BUFFER)) != -1)
{
bufferedOutputStream.write(data, 0, count);
}
// Flush and close the buffers
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
sendMessage("DONE");
// Close the current entry
inputStream.closeEntry();
}
inputStream.close();
sendMessage("-----------------------------------------------");
sendMessage("Unzipping complete");
}
catch (IOException e)
{
sendMessage("Exception occured: " + e.getMessage());
e.printStackTrace();
}
}
};
private Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
tv.append("\n" + msg.getData().getString("data"));
super.handleMessage(msg);
}
};
private void sendMessage(String text)
{
Message message = new Message();
Bundle data = new Bundle();
data.putString("data", text);
message.setData(data);
handler.sendMessage(message);
}
}
Check out this answer
Android - Unzip a folder?
I think sometimes in ZIP files, the directory entries may be added after their files. In this case, you won't get the directory before the file. The linked example calls file.getParentFile().exists() for regular files and creates that directory if it doesn't eixst.