Intent Service stopping before finishing the task? - android

I have a IntentService I am doing some task in another thread in
onHandleIntent(Intent intent)
Why is the IntentService stopping before performing the operation(task)?
Here is my code:
public class SampleIntentService extends IntentService {
public static final int DOWNLOAD_ERROR = 10;
public static final int DOWNLOAD_SUCCESS = 11;
public SampleIntentService() {
super(SampleIntentService.class.getName());
}
#Override
protected void onHandleIntent(Intent intent) {
final String url = intent.getStringExtra("url");
final ResultReceiver receiver = intent.getParcelableExtra("receiver");
final Bundle bundle = new Bundle();
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
return downloadFile(url, receiver);
}
#Override
protected void onPostExecute(String filePath) {
super.onPostExecute(filePath);
bundle.putString("filePath", filePath);
receiver.send(DOWNLOAD_SUCCESS, bundle);
}
};
}
private String downloadFile(String url, ResultReceiver receiver) {
File downloadFile = new File(Environment.getExternalStorageDirectory() + File.pathSeparator + "test.png");
if (downloadFile.exists())
downloadFile.delete();
try {
downloadFile.createNewFile();
URL downloadURL = new URL(url);
HttpURLConnection conn = (HttpURLConnection) downloadURL
.openConnection();
int responseCode = conn.getResponseCode();
if (responseCode != 200)
throw new Exception("Error in connection");
InputStream is = conn.getInputStream();
FileOutputStream os = new FileOutputStream(downloadFile);
byte buffer[] = new byte[1024];
int byteCount;
while ((byteCount = is.read(buffer)) != -1) {
os.write(buffer, 0, byteCount);
}
os.close();
is.close();
String filePath = downloadFile.getPath();
return filePath;
} catch (Exception e) {
receiver.send(DOWNLOAD_ERROR, Bundle.EMPTY);
e.printStackTrace();
}
return null;
}
}

As per the Docs:
abstract void onHandleIntent(Intent intent)
This method is invoked on the worker thread with a request to process.
Since this method is already invoked on worker thread you don't need to start another thread.
If you do that, the onHandleIntent(Intent intent) will return and the IntentService will think the task is done and it will stop itself.
Source: onHandleIntent
Here is the updated code :
public class SampleIntentService extends IntentService {
public static final int DOWNLOAD_ERROR = 10;
public static final int DOWNLOAD_SUCCESS = 11;
public SampleIntentService() {
super(SampleIntentService.class.getName());
}
#Override
protected void onHandleIntent(Intent intent) {
final String url = intent.getStringExtra("url");
final ResultReceiver receiver = intent.getParcelableExtra("receiver");
final Bundle bundle = new Bundle();
String filePath = downloadFile(url, receiver);
bundle.putString("filePath", filePath);
receiver.send(DOWNLOAD_SUCCESS, bundle);
}
private String downloadFile(String url, ResultReceiver receiver) {
File downloadFile = new File(Environment.getExternalStorageDirectory() + File.pathSeparator + "test.png");
if (downloadFile.exists())
downloadFile.delete();
try {
downloadFile.createNewFile();
URL downloadURL = new URL(url);
HttpURLConnection conn = (HttpURLConnection) downloadURL
.openConnection();
int responseCode = conn.getResponseCode();
if (responseCode != 200)
throw new Exception("Error in connection");
InputStream is = conn.getInputStream();
FileOutputStream os = new FileOutputStream(downloadFile);
byte buffer[] = new byte[1024];
int byteCount;
while ((byteCount = is.read(buffer)) != -1) {
os.write(buffer, 0, byteCount);
}
os.close();
is.close();
String filePath = downloadFile.getPath();
return filePath;
} catch (Exception e) {
receiver.send(DOWNLOAD_ERROR, Bundle.EMPTY);
e.printStackTrace();
}
return null;
}

Related

Android - Call Thread synchronized on UI thread

I try to create synchronized threads, but I always get the following error: android.os.NetworkOnMainThreadException.
I've read more posts, but they don't work for me.
Below I write the code blocks that do not work for me:
1.
final SyncApp syncJob = new SyncApp();
Thread t = new Thread (new Runnable () {
                         #Override
                         public void run () {
                             synchronized (syncJob) {
                                 String s = syncJob.insert (newJobs, GlobalVariables.URL_LOCALHOST + "jobs");
                                 txtState.setText (s);
                             }}});
                         }
                     });
                     t.Start ();
// t.run ();
2.
myClass.runOnUiThread(new Runnable() {
public void run() {...}
})
3.
Running code in main thread from another thread
SyncApp:
public class SyncApp {
synchronized public String insert(List<Jobs> job, String... params) {
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
String str = new Gson().toJson(job);
byte[] outputInBytes = str.getBytes();
OutputStream os = conn.getOutputStream();
os.write( outputInBytes );
os.flush();
int responseCode=conn.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line=br.readLine()) != null) {
response+=line;
}
}
else {
response=conn.getResponseMessage();
}
return response;
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return null;
}
}
I need to call a thread, wait for the answer and call another thread. Their answers I must use them in the activity
I need to call a thread, wait for the answer and call another thread.
Their answers I must use them in the activity
Example using async tasks to accomplish objective.
In this code, let A be your activity which needs to call a thread,
wait for the answer and call another thread. Customize as needed.
Since you never wait in UI threads, callbacks are used to accomplish synchronization.
Let A be your activity class:
public class A extends Activity {
// some method in activity where you launch a background thread (B)
// which then completes and invokes callback which then creates and launches
// a background thread (C) which then completes and invokes a callback.
//
// In callback C, you are on the UI thread.
protected void someMethod() {
new B(new B.CallbackB() {
public void result(Object o) {
new C(new C.CallbackC() {
public void result(Object o, Object answerFromB) {
// OK - C is now done and we are on UI thread!
// 'o' is answer from C
// 'answerFromB' also provided
}
}, o).execute(new Object());
}
).execute(new Object());
}
}
Define a class B:
public class B extends AsyncTask<Object, Void, Object> {
public static interface CallbackB {
void result(Object o);
}
private CallbackB cb;
public B (CallbackB cb) {
this.cb = cb;
}
protected Object doInBackground(Object... params) {
// do work and return an answer.
return new Object();
}
protected void onPostExecute(Object result) {
if (cb != null) {
cb.result(result);
}
}
}
Define a class C:
public class C extends AsyncTask<Object, Void, Object> {
public static interface CallbackC {
void result(Object o, Object answerFromB);
}
private CallbackC cb;
private Object answerFromB;
public C (CallbackC cb, Object answerFromB) {
this.cb = cb;
this.answerFromB = answerFromB;
}
protected Object doInBackground(Object... params) {
// do work and return an answer.
return new Object();
}
protected void onPostExecute(Object result) {
if (cb != null) {
cb.result(result, answerFromB);
}
}
}
For reference:
https://stackoverflow.com/a/9963705/2711811
My solution is:
public class Sync extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync_server);
dao = new DAO(this);
txtState = findViewById(R.id.txt_log);
btnSincro = findViewById(R.id.btn_sincro);
btnSincro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
countCall = 0;
callFlow();
}
});
btnHome = findViewById(R.id.btn_home);
btnHome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(SyncServerActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
private void callFlow() {
switch (countCall) {
case 0:
templates = toTemplate("url");
break;
case 1:
jobs = toJobs("url");
break;
case 2:
job = ... //select item
res = sendJobs(jobs, "url");
break;
default:
runOnUiThread(new Runnable() {
#Override
public void run() {
btnSincro.setEnabled(true);
txtState.append("\n\nEND");
}
});
}
}
private void nextStep() {
setText(txtState, "\nSync \n" + countCall + "/3");
countCall++;
callFlow();
}
private void setText(final TextView text, final String value) {
runOnUiThread(new Runnable() {
#Override
public void run() {
text.setText(value);
}
});
}
public List<Templates> toTemplate(final String... params) {
final List<Templates> list = new ArrayList<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
try {
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
int responseCode = connection.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("data");
for (int i = 0; i < parentArray.length(); i++) {
Templates item = new Gson().fromJson(parentArray.get(i).toString(), Templates.class);
list.add(item);
}
} else {
response = connection.getResponseMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
nextStep(); //call next Thread
}
}
});
t.start();
return list;
}
public List<Jobs> toJobs(final String... params) {
final List<Jobs> list = new ArrayList<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
try {
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
int responseCode = connection.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("data");
for (int i = 0; i < parentArray.length(); i++) {
Jobs item = new Gson().fromJson(parentArray.get(i).toString(), Jobs.class);
list.add(item);
}
} else {
response = connection.getResponseMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
nextStep();
}
}
});
t.start();
return list;
}
public Boolean sendJobs(final List<Jobs> job, final String... params) {
final Boolean[] result = {false};
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
String str = new Gson().toJson(job);
Log.d(TAG, str);
byte[] outputInBytes = str.getBytes();
OutputStream os = conn.getOutputStream();
os.write(outputInBytes);
os.flush();
int responseCode = conn.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
result[0] = true;
} else {
response = conn.getResponseMessage();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
nextStep();
}
}
});
t.start();
return result[0];
}
}
Whenever a thread ends, it calls the nextStep() method, which starts the next trhead.

How to download video from URL?

I am trying to download a video file from URL.
Below is my Code.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ProgressBack PB = new ProgressBack();
PB.execute("");
}
private class ProgressBack extends AsyncTask<String, String, String> {
ProgressDialog PD;
#Override
protected void onPreExecute() {
PD = ProgressDialog.show(MainActivity.this, null, "Please Wait ...", true);
PD.setCancelable(true);
}
#Override
protected String doInBackground(String... arg0) {
downloadFile("https://r8---sn-nhpax-ua8z.googlevideo.com/videoplayback?c=web&clen=17641691&cpn=Mf_hDzzzBYPH8N_J&cver=as3&dur=189.857&expire=1425270280&fexp=905657%2C907263%2C912333%2C926419%2C927622%2C931358%2C934947%2C936928%2C9406255%2C9406746%2C9406850%2C943917%2C945093%2C947225%2C947240%2C948124%2C951703%2C952302%2C952605%2C952612%2C952620%2C952901%2C955301%2C957201%2C959701&gcr=il&gir=yes&id=o-AM54E58Im9m8yqaerEsKkGXOx0IWge8YN4h6OhFkcDTe&initcwndbps=1488750&ip=84.228.53.86&ipbits=0&itag=135&keepalive=yes&key=yt5&lmt=1402678222642477&mime=video%2Fmp4&mm=31&ms=au&mt=1425248654&mv=m&pl=20&ratebypass=yes&requiressl=yes&signature=E8027BCB4C1EE76254FC008B0044655E58485D81.931863F3A7AD6C6B01262BCD723B37E5396D4317&source=youtube&sparams=clen%2Cdur%2Cgcr%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Ckeepalive%2Clmt%2Cmime%2Cmm%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cupn%2Cexpire&sver=3&upn=moGJHdfD4Z8", "Sample.mp4");
return null;
}
protected void onPostExecute(Boolean result) {
PD.dismiss();
}
}
private void downloadFile(String fileURL, String fileName) {
try {
String rootDir = Environment.getExternalStorageDirectory()
+ File.separator + "Video";
File rootFile = new File(rootDir);
rootFile.mkdir();
URL url = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(rootFile,
fileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (IOException e) {
Log.d("Error....", e.toString());
}
}
}
But it is not downloading. and it is showing java.io.FileNotFoundException.
Is there any other way to download video file or anything wrong in my code.
Can someone please help me?
//Check if External Storage permission js allowed
if (!storageAllowed()) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(getActivity(), Constant.PERMISSIONS_STORAGE, Constant.REQUEST_EXTERNAL_STORAGE);
progressDialog.dismiss();
showToast("Kindly grant the request and try again");
}else {
String mBaseFolderPath = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "FolderName" + File.separator;
if (!new File(mBaseFolderPath).exists()) {
new File(mBaseFolderPath).mkdir();
}
if (downloadUrl == null || TextUtils.isEmpty(downloadUrl)) {
showToast("Download url not found!");
return;
}
Uri downloadUri = Uri.parse(url.trim());
if (downloadUri == null) {
showToast("Download url not found!");
return;
}
String mFilePath = "file://" + mBaseFolderPath + "/" + fname ;
DownloadManager.Request req = new DownloadManager.Request(downloadUri);
req.setDestinationUri(Uri.parse(mFilePath));
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
DownloadManager dm = (DownloadManager) getActivity().getSystemService(getActivity().DOWNLOAD_SERVICE);
dm.enqueue(req);
progressDialog.dismiss();
loadInterstitialAd();
}
}
try out this:
private static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch(FileNotFoundException e) {
return; // swallow a 404
} catch (IOException e) {
return; // swallow a 404
}
}
You can use DownloadManger for downloading file in android from server.
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(videoUrl))
.setTitle(file.getName())
.setDescription("Downloading")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDestinationUri(Uri.fromFile(file))
.setAllowedOverMetered(true)
.setAllowedOverRoaming(true);
long downloadId = mDownloadManager.enqueue(request);

Download a file with no extension from a server

I'm try to download a mp3 file from following URL. I found lot of articles and examples regarding file download. Those examples are based on URLs that end with a file extension, e.g.:- yourdomain.com/filename.mp3 but I want to download a file from following url which typically does not end with file extension.
youtubeinmp3.com/download/get/?i=1gsE32jF0aVaY0smDVf%2BmwnIZPrMDnGmchHBu0Hovd3Hl4NYqjNdym4RqjDSAis7p1n5O%2BeXmdwFxK9ugErLWQ%3D%3D
**Please note that I use the above url as-is without using Stackoverflow url formatting method to easily understand the question.
** I have tried the #Arsal Imam's solution as follows still not working
btnShowProgress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// starting new Async Task
File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"Folder Name");
if(!cacheDir.exists())
cacheDir.mkdirs();
File f=new File(cacheDir,"ddedddddd.mp3");
saveDir=f.getPath();
new DownloadFileFromURL().execute(fileURL);
}
});
and the async task code is as follows
class DownloadFileFromURL extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
#Override
protected String doInBackground(String... f_url) {
try{
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveDir);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}catch(Exception e){
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(String... progress) {
pDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String file_url) {
dismissDialog(progress_bar_type);
}
}
Although Volley library is not recommended for large download or streaming operations, however, I'd like to share my following working sample code.
Let's assume we download only MP3 files so I hard-code the extension. And of course, we should check more carefully to avoid exceptions (NullPointer...) such as checking whether headers contain "Content-Disposition" key or not...
Hope this helps!
Volley Custom class:
public class BaseVolleyRequest extends Request<NetworkResponse> {
private final Response.Listener<NetworkResponse> mListener;
private final Response.ErrorListener mErrorListener;
public BaseVolleyRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(0, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
#Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
try {
return Response.success(
response,
HttpHeaderParser.parseCacheHeaders(response));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
#Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return super.parseNetworkError(volleyError);
}
#Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
}
Then in your Activity:
public class BinaryVolleyActivity extends AppCompatActivity {
private final Context mContext = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_binary_volley);
RequestQueue requestQueue = Volley.newRequestQueue(mContext);
String url = "http://www.youtubeinmp3.com/download/get/?i=3sI2yV5mJ0kQ8CnddqmANZqK8a%2BgVQJ%2Fmg3xwhHTUsJKuusOCZUzebuWW%2BJSFs0oz8VTs6ES3gjohKQMogixlQ%3D%3D";
BaseVolleyRequest volleyRequest = new BaseVolleyRequest(url, new Response.Listener<NetworkResponse>() {
#Override
public void onResponse(NetworkResponse response) {
Map<String, String> headers = response.headers;
String contentDisposition = headers.get("Content-Disposition");
// String contentType = headers.get("Content-Type");
String[] temp = contentDisposition.split("filename=");
String fileName = temp[1].replace("\"", "") + ".mp3";
InputStream inputStream = new ByteArrayInputStream(response.data);
createLocalFile(inputStream, fileName);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
}
});
volleyRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 10, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(volleyRequest);
}
private String createLocalFile(InputStream inputStream, String fileName) {
try {
String folderName = "MP3VOLLEY";
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, folderName);
folder.mkdir();
File file = new File(folder, fileName);
file.createNewFile();
FileOutputStream f = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
f.write(buffer, 0, length);
}
//f.flush();
f.close();
return file.getPath();
} catch (IOException e) {
return e.getMessage();
}
}
}
Here the result screenshot:
NOTE:
As I commented below, because the direct download Url changes regularly, you should check the new url with some tools such as Postman for Chrome, if it responses binary instead of a web page (expired url), then the Url is valid and my code works for that Url.
Refer to the two following screenshots:
Expired url:
Un-expired url:
UPDATE BASIC LOGIC FOR GETTING DIRECT DOWNLOAD LINK FROM THAT SITE'S DOCUMENTATION:
According to Create Your Own YouTube To MP3 Downloader For Free
You can take a look at
JSON Example
You can also receive the data in JSON by setting the "format"
parameter to "JSON".
http://YouTubeInMP3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=i62Zjga8JOM
Firstly, you create a JsonObjectRequest getting response from the above file link. Then, inside onResponse of this JsonObjectRequest you will get the direct download link, like this directUrl = response.getString("link"); and use BaseVolleyRequest volleyRequest
I have just told the logic for getting direct url, IMO, you should implement it yourself. Goodluck!
Use below code it works fine for encrypted URLs
public class HttpDownloadUtility {
private static final int BUFFER_SIZE = 4096;
/**
* Downloads a file from a URL
* #param fileURL HTTP URL of the file to be downloaded
* #param saveDir path of the directory to save the file
* #throws IOException
*/
public static void downloadFile(String fileURL, String saveDir)
throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}
}
The url returns a 302 redirect to the actual .mp3. The browser does the redirect in the background for you, but in your app you need to do it yourself. Here is an example on how to do that with HttpUrlConnection http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
If you know the type of file in advance then you can download your file from url which don't have extension.
DownloadService .java
public class DownloadService extends IntentService {
public static final int UPDATE_PROGRESS = 8344;
private Context context;
private PowerManager.WakeLock mWakeLock;
ProgressDialog mProgressDialog;
String filename;
File mypath;
String urlToDownload;
BroadcastReceiver broadcaster;
Intent intent1;
static final public String BROADCAST_ACTION = "com.example.app.activity.test.broadcast";
public DownloadService() {
super("DownloadService");
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
intent1 = new Intent(BROADCAST_ACTION);
}
#Override
protected void onHandleIntent(Intent intent) {
ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
try {
intent1 = new Intent(BROADCAST_ACTION);
urlToDownload = intent.getStringExtra("url");
filename= intent.getStringExtra("filename");
BufferedWriter out;
try {
File path=new File("/sdcard/","folder name");
path.mkdir();
mypath=new File(path,filename);
Log.e("mypath",""+mypath);
if (!mypath.exists()) {
out= new BufferedWriter(new FileWriter(mypath));
//ut = new OutputStreamWriter(context.openFileOutput( mypath.getAbsolutePath() ,Context.MODE_PRIVATE));
out.write("test");
out.close();
}
}catch(Exception e){
e.printStackTrace();
}
URL url = new URL(urlToDownload);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(connection.getInputStream());
OutputStream output = new FileOutputStream(mypath);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress" ,(int) (total * 100 / fileLength));
//Log.e("mypath",""+mypath);
resultData.putString("mypath", ""+mypath);
receiver.send(UPDATE_PROGRESS, resultData);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
Bundle resultData = new Bundle();
resultData.putInt("progress" ,100);
resultData.putString("mypath", ""+mypath);
receiver.send(UPDATE_PROGRESS, resultData);
intent1.putExtra("progressbar", 100);
sendBroadcast(intent1);
}
}
DownloadReceiver.java
public class DownloadReceiver extends ResultReceiver{
private Context context;
private PowerManager.WakeLock mWakeLock;
ProgressDialog mProgressDialog;
String filename;
String mypath;
public DownloadReceiver(Handler handler ,String filename ,Context context) {
super(handler);
this.context = context;
this.filename = filename;
mProgressDialog = new ProgressDialog(context);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == DownloadService.UPDATE_PROGRESS) {
int progress = resultData.getInt("progress");
mypath = resultData.getString("mypath");
mProgressDialog.setProgress(progress);
//Log.e("progress","progress");
mProgressDialog.setMessage("App name");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
if (progress == 100) {
mProgressDialog.dismiss();
Log.e("download","download");
}
}
}
}
Now start service in your mainactivity by below code :
Intent miIntent = new Intent(mContext, DownloadService.class);
miIntent.putExtra("url", url);
miIntent.putExtra("filename", id+".mp3");
miIntent.putExtra("receiver", new DownloadReceiver(new Handler() , id,mContext));
startService(miIntent);

Upload of some file fails using HttpClient

I am trying to upload images as well as videos to my external server from the app. I Googled and found out HttpClient procedure is a good one, so I downloaded the library and execute the following code which normally works well for every file however for some videos, it does not upload the video.
public void executeMultipartPost(String uri) throws Exception {
try {
File file = new File(uri);
Uri imageUri = Uri.fromFile(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = readBytes(imageUri);
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(
"http://example.com/ccs-business/upload.php");
ByteArrayBody bab = new ByteArrayBody(data, file.getName());
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("uploaded_video", bab);
reqEntity.addPart("number", new StringBody("123456"));
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
Log.v("ONMESSAGE", "Response: " + s);
dialog.dismiss();
} catch (Exception e) {
// handle exception here
Log.e(e.getClass().getName(), e.getMessage());
dialog.dismiss();
}
}
public byte[] readBytes(Uri uri) throws IOException {
InputStream inputStream = getContentResolver().openInputStream(uri);
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
My requirement is to upload up to 20mb file.
I Have tired Uploading files with below code attached and worked fine :
public class UploadService extends IntentService {
/**
* Utility method that creates the intent that starts the background
* file upload service.
*
* #param task object containing the upload request
* #throws IllegalArgumentException if one or more arguments passed are invalid
* #throws MalformedURLException if the server URL is not valid
*/
public static void startUpload(final UploadRequest task)
throws IllegalArgumentException, MalformedURLException {
if (task == null) {
throw new IllegalArgumentException("Can't pass an empty task!");
} else {
task.validate();
final Intent intent = new Intent(UploadService.class.getName());
intent.setAction(ACTION_UPLOAD);
intent.putExtra(PARAM_NOTIFICATION_CONFIG, task.getNotificationConfig());
intent.putExtra(PARAM_ID, task.getUploadId());
intent.putExtra(PARAM_URL, task.getServerUrl());
intent.putExtra(PARAM_METHOD, task.getMethod());
intent.putParcelableArrayListExtra(PARAM_FILES, task.getFilesToUpload());
intent.putParcelableArrayListExtra(PARAM_REQUEST_HEADERS, task.getHeaders());
intent.putParcelableArrayListExtra(PARAM_REQUEST_PARAMETERS, task.getParameters());
task.getContext().startService(intent);
}
}
public UploadService() {
super(SERVICE_NAME);
}
#Override
public void onCreate() {
super.onCreate();
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notification = new NotificationCompat.Builder(this);
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_UPLOAD.equals(action)) {
notificationConfig = intent.getParcelableExtra(PARAM_NOTIFICATION_CONFIG);
final String uploadId = intent.getStringExtra(PARAM_ID);
final String url = intent.getStringExtra(PARAM_URL);
final String method = intent.getStringExtra(PARAM_METHOD);
final ArrayList<FileToUpload> files = intent.getParcelableArrayListExtra(PARAM_FILES);
final ArrayList<NameValue> headers = intent.getParcelableArrayListExtra(PARAM_REQUEST_HEADERS);
final ArrayList<NameValue> parameters = intent.getParcelableArrayListExtra(PARAM_REQUEST_PARAMETERS);
lastPublishedProgress = 0;
wakeLock.acquire();
try {
createNotification();
handleFileUpload(uploadId, url, method, files, headers, parameters);
} catch (Exception exception) {
broadcastError(uploadId, exception);
} finally {
wakeLock.release();
}
}
}
}
private void handleFileUpload(final String uploadId,
final String url,
final String method,
final ArrayList<FileToUpload> filesToUpload,
final ArrayList<NameValue> requestHeaders,
final ArrayList<NameValue> requestParameters)
throws IOException {
final String boundary = getBoundary();
final byte[] boundaryBytes = getBoundaryBytes(boundary);
HttpURLConnection conn = null;
OutputStream requestStream = null;
try {
conn = getMultipartHttpURLConnection(url, method, boundary);
setRequestHeaders(conn, requestHeaders);
requestStream = conn.getOutputStream();
setRequestParameters(requestStream, requestParameters, boundaryBytes);
uploadFiles(uploadId, requestStream, filesToUpload, boundaryBytes);
final byte[] trailer = getTrailerBytes(boundary);
requestStream.write(trailer, 0, trailer.length);
final int serverResponseCode = conn.getResponseCode();
final String serverResponseMessage = conn.getResponseMessage();
broadcastCompleted(uploadId, serverResponseCode, serverResponseMessage);
} finally {
closeOutputStream(requestStream);
closeConnection(conn);
}
}
private String getBoundary() {
final StringBuilder builder = new StringBuilder();
builder.append("---------------------------")
.append(System.currentTimeMillis());
return builder.toString();
}
private byte[] getBoundaryBytes(final String boundary)
throws UnsupportedEncodingException {
final StringBuilder builder = new StringBuilder();
builder.append(NEW_LINE)
.append(TWO_HYPHENS)
.append(boundary)
.append(NEW_LINE);
return builder.toString().getBytes("US-ASCII");
}
private byte[] getTrailerBytes(final String boundary)
throws UnsupportedEncodingException {
final StringBuilder builder = new StringBuilder();
builder.append(NEW_LINE)
.append(TWO_HYPHENS)
.append(boundary)
.append(TWO_HYPHENS)
.append(NEW_LINE);
return builder.toString().getBytes("US-ASCII");
}
private HttpURLConnection getMultipartHttpURLConnection(final String url,
final String method,
final String boundary)
throws IOException {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setChunkedStreamingMode(0);
conn.setRequestMethod(method);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
return conn;
}
private void setRequestHeaders(final HttpURLConnection conn,
final ArrayList<NameValue> requestHeaders) {
if (!requestHeaders.isEmpty()) {
for (final NameValue param : requestHeaders) {
conn.setRequestProperty(param.getName(), param.getValue());
}
}
}
private void setRequestParameters(final OutputStream requestStream,
final ArrayList<NameValue> requestParameters,
final byte[] boundaryBytes)
throws IOException, UnsupportedEncodingException {
if (!requestParameters.isEmpty()) {
for (final NameValue parameter : requestParameters) {
requestStream.write(boundaryBytes, 0, boundaryBytes.length);
byte[] formItemBytes = parameter.getBytes();
requestStream.write(formItemBytes, 0, formItemBytes.length);
}
}
}
private void uploadFiles(final String uploadId,
final OutputStream requestStream,
final ArrayList<FileToUpload> filesToUpload,
final byte[] boundaryBytes)
throws UnsupportedEncodingException,
IOException,
FileNotFoundException {
final long totalBytes = getTotalBytes(filesToUpload);
long uploadedBytes = 0;
for (FileToUpload file : filesToUpload) {
requestStream.write(boundaryBytes, 0, boundaryBytes.length);
byte[] headerBytes = file.getMultipartHeader();
requestStream.write(headerBytes, 0, headerBytes.length);
final InputStream stream = file.getStream();
byte[] buffer = new byte[BUFFER_SIZE];
long bytesRead;
try {
while ((bytesRead = stream.read(buffer, 0, buffer.length)) > 0) {
requestStream.write(buffer, 0, buffer.length);
uploadedBytes += bytesRead;
broadcastProgress(uploadId, uploadedBytes, totalBytes);
}
} finally {
closeInputStream(stream);
}
}
}
private long getTotalBytes(final ArrayList<FileToUpload> filesToUpload) {
long total = 0;
for (FileToUpload file : filesToUpload) {
total += file.length();
}
return total;
}
private void closeInputStream(final InputStream stream) {
if (stream != null) {
try {
stream.close();
} catch (Exception exc) { }
}
}
private void closeOutputStream(final OutputStream stream) {
if (stream != null) {
try {
stream.flush();
stream.close();
} catch (Exception exc) { }
}
}
private void closeConnection(final HttpURLConnection connection) {
if (connection != null) {
try {
connection.disconnect();
} catch (Exception exc) { }
}
}
private void broadcastProgress(final String uploadId, final long uploadedBytes, final long totalBytes) {
final int progress = (int) (uploadedBytes * 100 / totalBytes);
if (progress <= lastPublishedProgress) return;
lastPublishedProgress = progress;
updateNotificationProgress(progress);
final Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_IN_PROGRESS);
intent.putExtra(PROGRESS, progress);
sendBroadcast(intent);
}
private void broadcastCompleted(final String uploadId, final int responseCode, final String responseMessage) {
final String filteredMessage;
if (responseMessage == null) {
filteredMessage = "";
} else {
filteredMessage = responseMessage;
}
if (responseCode >= 200 && responseCode <= 299)
updateNotificationCompleted();
else
updateNotificationError();
final Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_COMPLETED);
intent.putExtra(SERVER_RESPONSE_CODE, responseCode);
intent.putExtra(SERVER_RESPONSE_MESSAGE, filteredMessage);
sendBroadcast(intent);
}
private void broadcastError(final String uploadId, final Exception exception) {
updateNotificationError();
final Intent intent = new Intent(BROADCAST_ACTION);
intent.setAction(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_ERROR);
intent.putExtra(ERROR_EXCEPTION, exception);
sendBroadcast(intent);
}
private void createNotification() {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getMessage())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(100, 0, true)
.setOngoing(true);
startForeground(UPLOAD_NOTIFICATION_ID, notification.build());
}
private void updateNotificationProgress(final int progress) {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getMessage())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(100, progress, false)
.setOngoing(true);
startForeground(UPLOAD_NOTIFICATION_ID, notification.build());
}
private void updateNotificationCompleted() {
stopForeground(notificationConfig.isAutoClearOnSuccess());
if (!notificationConfig.isAutoClearOnSuccess()) {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getCompleted())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(0, 0, false)
.setOngoing(false);
notificationManager.notify(UPLOAD_NOTIFICATION_ID_DONE, notification.build());
}
}
private void updateNotificationError() {
stopForeground(false);
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getError())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(0, 0, false)
.setOngoing(false);
notificationManager.notify(UPLOAD_NOTIFICATION_ID_DONE, notification.build());
}
}
For compelete Source code refer this

Android Service not Instantiating

This my first attempt at working with a service. My service is intended to download an image file from a server based on a filename string that it gets dynamically.
I'm getting the following error. Does anyone see what I am doing wrong? Thank you!
08-19 16:40:18.102: E/AndroidRuntime(27702): java.lang.RuntimeException: Unable to instantiate service database.DownloadPicture: java.lang.InstantiationException: can't instantiate class database.DownloadPicture; no empty constructor
Here is how I am starting the service:
Intent intent = new Intent(context, DownloadPicture.class);
intent.putExtra(DownloadPicture.FILENAME, filename);
startService(intent);
System.err.println("service started");
This is my service:
public class DownloadPicture extends IntentService {
private int result = Activity.RESULT_CANCELED;
public static final String FILENAME = "filename";
public static final String FILEPATH = "filepath";
public static final String RESULT = "result";
public static final String NOTIFICATION = "com.mysite.myapp";
public DownloadPicture(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
String urlPath = this.getResources().getString(R.string.imagesURL);
String fileName = intent.getStringExtra(FILENAME);
File output = new File(Environment.getExternalStorageDirectory(), fileName);
if (output.exists()) {output.delete();}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(stream);
fos = new FileOutputStream(output.getPath());
int next = -1;
while ((next = reader.read()) != -1) {
fos.write(next);
}
// Successful finished
result = Activity.RESULT_OK;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
publishResults(output.getAbsolutePath(), result);
}
private void publishResults(String outputPath, int result) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(FILEPATH, outputPath);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
}
If you carefully read the error it says : no empty constructor . So try to have an empty default no-argument constructor for IntentService like:
public DownloadPicture() {
super("DownloadPicture");
}
See No empty constructor when create a service Hope it helps.
Have you added the service to your manifest?
<service android:name=".DownloadPicture" />

Categories

Resources