Android programming (Trying to download a file to system directory) - java

Dear stackOverflow members i have recently started a new project called "RootBox" and it is an app that needs "su" perms and i have successfully allowed the app "su" or "root" access and im trying to download and replace a system file in "/system/media and i have setup my downloader but the download progress dialog pops up and closes which im guessing is the result of the file not being able to written to the system directory and i have Re-mounted the system as r-w before starting the download an i have searched all over the internet and was unable to find help thats why i have come here.
This is the activity executing the download
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private Button startBtn;
private ProgressDialog mProgressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bootmation);
startBtn = (Button)findViewById(R.id.startBtn);
startBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
startDownload();
RootTools.remount("/system/", "rw");
}
});
}
private void startDownload() {
String url = "http://www.filehosting.org/file/details/430746/bootanimation.zip";
new DownloadFileAsync().execute(url);
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask {
#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 lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/system/media/bootanimation.zip");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
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);
}
}
}

for this u have to allow in manifest for permission for writing as
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

URL u = new URL(fUrls[i]);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();

Related

Download and Share in Whatsapp

Video gets shared before the complete video gets downloaded.I am using the following code to download a video from the server and share in whatsapp:
AlertDialog.Builder alert1 = new AlertDialog.Builder(this);
alert1.setTitle("Share the file to Whatsapp");
alert1.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
DownloadFile1 downloadFile1 = new DownloadFile1();
downloadFile1.videoToDownload = video_url;
String value = "test.mp4";
downloadFile1.fileName = value;
downloadFile1.execute();
try {
shareVideoWhatsApp(value);
} catch (IOException e) {
e.printStackTrace();
}
}
});
alert1.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert1.show();
The Download part is implemented in async task.The problem is sharing to the whatsapp takes place before the complete video file gets downloaded.
Download code:
class DownloadFile1 extends AsyncTask<String, Integer, String> {
ProgressDialog bar;
public String videoToDownload;
public String fileName;
/**
* Before starting background thread
* Show Progress Bar Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
#Override
protected String doInBackground(String... params) {
int count;
try {
mp4load(videoToDownload);
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
public void mp4load(String urling) {
try {
System.out.println("Downloading");
URL url = new URL(urling);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
//c.setDoOutput(true);
con.connect();
// String downloadsPath = Environment.getExternalStoragePublicDirectory();
File SDCardRoot = Environment.getExternalStorageDirectory();
File outputFile = new File(SDCardRoot, fileName);
if (!outputFile.exists()) {
outputFile.createNewFile();
}
FileOutputStream fos = new FileOutputStream(outputFile);
int status = con.getResponseCode();
InputStream is = con.getInputStream();
int fileLength = con.getContentLength();
long total = 0;
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
total += len1;
pDialog.setProgress((int) (total * 100 / fileLength));
}
fos.close();
is.close();
System.out.println("Downloaded");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 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);
}
}
How to solve this problem?
Call shareVideoWhatsApp(value); inside onPostExecute()

Async only works when stepping through debugger

I've been getting very strange behavior from my code.
Basically, my code is using an Input/Output stream to download a .pdf file from the internet, saving it to internal storage (using an AsyncTask) and then outputting it using an outside "showPdf" library.
The strangest thing is that it only works on two conditions:
I run the code twice (run or debug without any break points). The first run logs File is empty when showPdf() is called, but the second run through runs perfectly fine when showPdf() is called on its own.
I debug the code and step through the program
As a preface, I'm new to java and android studio, so my guess may not be right at all, but I'm guessing since the InputStream is being done "asynchronously", showPdf() may be called before the byte[] array is written into memory. If this is the case, what could I do to delay Async long enough to work?
public class pdfView extends AppCompatActivity {
PDFView pdfView; //pdfView object
String URL;
String fileName;
File directory; //path of created File
// Container for all parameters of DownloadAsync
private static class AsyncParameters {
String URL;
File directory;
AsyncParameters(String URL, File directory) {
this.URL = URL;
this.directory = directory;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_view);
//Grab the extras from the intent call
Intent intent = getIntent(); //whatever calls this activity, gather the intent
URL = intent.getStringExtra("File URL"); // in this case, get the file name of the "extra" passed through
fileName = intent.getStringExtra("File Name");
//Grab the internal storage directory and create a folder if it doesn't exist
File intDirectory = getFilesDir();
File folder = new File(intDirectory, "pdf");
boolean isDirectoryCreated = folder.exists();
//See if the file exists
if (!isDirectoryCreated) {
isDirectoryCreated= folder.mkdir();
}
if(isDirectoryCreated) {
directory = new File(folder, fileName);
try {
directory.createNewFile();
if (directory.canWrite())
Log.d("hngggggggggggggg", "onCreate: ");
} catch (IOException e1) {
e1.printStackTrace();
}
//See if file already exists
boolean empty = directory.length() == 0;
if (empty){
/**Call class to create parameter container**/
AsyncParameters param = new AsyncParameters(URL, directory);
DownloadAsync Downloader = new DownloadAsync();
Downloader.execute(param);
showPdf();
}
else
showPdf();
}
}
public void showPdf()
{
pdfView = (PDFView) findViewById(R.id.pdfView);
pdfView.fromFile(directory).load();
}
/**Class for asynchronous tasks**/
public class DownloadAsync extends AsyncTask<AsyncParameters, Void, Void> {
// Container for all parameters of DownloadAsync
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(pdfView.this);
pDialog.setMessage("Downloading Database...");
String message= "Downloading Files";
SpannableString ss2 = new SpannableString(message);
ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);
ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0);
pDialog.setMessage(ss2);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(AsyncParameters... params) {
Log.d("WE ARE IN DOBACKGROUND", "doInBackground: ");
String fileURL = params[0].URL;
File directory = params[0].directory;
try {
FileOutputStream f = new FileOutputStream(directory);
java.net.URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[8192];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
e.printStackTrace();
}
onPostExecute();
return null;
}
protected void onPostExecute() {
pDialog.dismiss();
}
}
}
You already have answered your own question. Since the download is asyncTask running on a different thread, there is no wait for the asyncTask to complete before showPdf() is called. You can call showPdf() from onPostExecute() which is called after the background task completes. Your code should look like:
#Override
protected void onCreate(Bundle savedInstanceState) {
........
........
AsyncParameters param = new AsyncParameters(URL, directory);
DownloadAsync Downloader = new DownloadAsync();
Downloader.execute(param);
.......
.......
}
public class DownloadAsync extends AsyncTask<AsyncParameters, Void, Void> {
.......
#Override
protected void onPostExecute() {
pDialog.dismiss();
showPdf();
}
}

Async Task not getting canceled

I am trying to download file using AsyncTask and also wanted to implement cancel button in progress dialog to cancel the download.
i think the problem is in "doInBackground" method. here is my asynctask:
public class Download_result extends AsyncTask<String,Integer,Void>{
ProgressDialog progressDialog;
Context context;
String pdfFile;
Download_result(Context context, String pdfFile){
this.context=context;
this.pdfFile=pdfFile;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Downloading...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(200);
progressDialog.setCancelable(false);
progressDialog.setProgress(0);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Download_result.this.cancel(true); //cancel asynctask here
dialog.dismiss();
}
});
progressDialog.show();
}
#Override
protected Void doInBackground(String... params) {
//given below
}
#Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result) {
progressDialog.cancel();
}
}
"doInBackground" method:
#Override
protected Void doInBackground(String... params) {
String url_1=params[0];
int file_length=0;
try {
URL url = new URL(url_1);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
file_length=urlConnection.getContentLength();
filesize=file_length;
File sdCard = Environment.getExternalStorageDirectory();
File new_folder = new File (sdCard.getAbsolutePath() + "/xxx");
File input_file = new File(new_folder,pdfFile);
InputStream inputStream = new BufferedInputStream(url.openStream(),8192);
byte[] data=new byte[1024];
int total=0,count=0;
OutputStream outputStream = new FileOutputStream(input_file);
while ((count=inputStream.read(data))!=-1){
total+=count;
outputStream.write(data,0,count);
int progress= (total*200)/file_length;
downloadedsize=total;
publishProgress(progress);
if(isCancelled()){
break; or return null; // same result
}
}
inputStream.close();
outputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
try this:
boolean downloadstatus = true;
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Downloading...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(200);
progressDialog.setCancelable(false);
progressDialog.setProgress(0);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
download.cancel(true);
downloadstatus=false; //add boolean check
dialog.dismiss();
}
});
progressDialog.show();
}
Now in your doInbackGround()
while ((count=inputStream.read(data))!=-1){
if(!your_AsyncTask.isCancelled() || downloadstatus !=false){
total+=count;
outputStream.write(data,0,count);
int progress= (total*200)/file_length;
downloadedsize=total;
publishProgress(progress);
}else{
break;
}
}
This is a reply to my own post(may be in future someone need this):
Actualy my asynctask get cancel, but i didn't know because i thought that when we cancel the asynctask the file should not be there. But actualy when we cancel async task the file is stored but with the smaller size.
eg. Suppose the file is 1mb and i have cancel asynctask while progress dialog shows 50% then only 500kb file is stored, and i thought this is the actual file. sorry for my mistake.
So the logic is when someone press cancel you need to delete the half downloaded file too.
and sorry for my English, it's terrible i know.

How to Update My Android app From My Server?

Please help me to add update code to my app to be update from my server thank you
nothing worked from net , i need complete guide
You can't install your app without users permission and root access but you can download your applications new version from server then ask users for install. Here is an example:
{
PackageManager manager = context.getPackageManager();
try {
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
version = info.versionName;
if (newversion.replace(".", "") < version.replace(".", "")) {
new DownloadFileFromURL().execute("http://exampl.com/Content/files/example.apk");
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
private class DownloadFileFromURL extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = onCreateDialog();
}
#Override
protected String doInBackground(String... f_url) {
int count;
try {
File file = new File(Environment.getExternalStorageDirectory() + "/example.apk");
if (file.exists()) {
file.delete();
}
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
pDialog.setMax(lenghtOfFile / 1024);
InputStream input = new BufferedInputStream(url.openStream(), 8192);
OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory() + "/example.apk");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(total / 1024 + "");
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception ignored) {
}
return null;
}
protected void onProgressUpdate(String... progress) {
pDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String file_url) {
dialog.dismiss();
File file = new File(Environment.getExternalStorageDirectory() + "/example.apk");
if (file.exists()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
//finish() or whatever you want
}
}
}

How can I resume my download by onResume() in android?

My application has a "start download" and a "pause" button. Once I start the download through "Start Download" button my download starts and stop upon clicking "pause" now when I press back or home button the onPause() function works as intended it pauses my download and when I open the app again and click start it resumes from that progress,
what I want is that upon switching back(not the first time load of app) to the application once I have pressed back or home I want the download to resume automatically by onResume without clicking start button again. Right now in below code my download automatically starts without doing anything which is due to my onResume(), is it possible that I can resume with onResume but not start the download automatically upon first time loading of the app thorugh it? I know the below code is not as efficient as it could have been. Apologies for that.
Again, I want my onResume to only resume my previously downloaded file not start the download unless download was once initiated through the button.
public class MainActivity extends Activity implements OnClickListener{
String url = "http://upload.wikimedia.org/wikipedia/commons/1/11/HUP_10MB_1946_obverse.jpg";
boolean mStopped=false;
private ProgressBar progressBar2;
private String filepath = "MyFileStorage";
private File directory;
private TextView finished;
#Override
protected void onPause() {
super.onPause();
mStopped=true;
}
#Override
protected void onResume() {
super.onResume();
mStopped=false;
grabURL(url);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContextWrapper contextWrapper = new ContextWrapper(getApplicationContext());
directory = contextWrapper.getDir(filepath, Context.MODE_PRIVATE);
progressBar2 = (ProgressBar) findViewById(R.id.progressBar2);
progressBar2.setVisibility(View.GONE);
finished = (TextView) findViewById(R.id.textView1);
finished.setVisibility(View.GONE);
Button stop = (Button) findViewById(R.id.stop);
stop.setOnClickListener(this);
Button download = (Button) findViewById(R.id.download);
download.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.stop:
mStopped=true;
break;
case R.id.download:
mStopped=false;
grabURL(url);
break;
}
}
public void grabURL(String url) {
new GrabURL().execute(url);
}
private class GrabURL extends AsyncTask<String, Integer, String> {
protected void onPreExecute() {
progressBar2.setVisibility(View.VISIBLE);
progressBar2.setProgress(0);
finished.setVisibility(View.GONE);
}
protected String doInBackground(String... urls) {
String filename = "MySampleFile.png";
File myFile = new File(directory , filename);
try {
URL url = new URL(urls[0]);
URLConnection connection = url.openConnection();
if (myFile.exists())
{
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Range", "bytes=" + myFile.length() + "-");
}
connection.connect();
int fileLength = connection.getContentLength();
fileLength += myFile.length();
InputStream is = new BufferedInputStream(connection.getInputStream());
RandomAccessFile os = new RandomAccessFile(myFile, "rw");
os.seek(myFile.length());
byte data[] = new byte[1024];
int count;
int __progress = 0;
while ((count = is.read(data)) != -1 && __progress != 100) {
if (mStopped) {
throw new IOException();
}
else{
__progress = (int) ((myFile.length() * 100) / fileLength);
publishProgress((int) (myFile.length() * 100 / fileLength));
os.write(data, 0, count);}
}
os.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return filename;
}
protected void onProgressUpdate(Integer... progress) {
finished.setVisibility(View.VISIBLE);
finished.setText(String.valueOf(progress[0]) + "%");
progressBar2.setProgress(progress[0]);
}
protected void onCancelled() {
Toast toast = Toast.makeText(getBaseContext(),
"Error connecting to Server", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
protected void onPostExecute(String filename) {
progressBar2.setProgress(100);
finished.setVisibility(View.VISIBLE);
finished.setText("Download in progress..");
File myFile = new File(directory , filename);
ImageView myImage = (ImageView) findViewById(R.id.imageView1);
myImage.setImageBitmap(BitmapFactory.decodeFile(myFile.getAbsolutePath()));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
You seem to already have most of the code in place for the functionality. In onResume you can call your ASyncTask and it should start download if the file exists (paused download in onPause(), file exists). I have written similar code, you can find it here: https://github.com/hiemanshu/ContentDownloader/blob/master/src/com/example/contentdownloader/MainActivity.java
In my code you can find that instead of using onPause and onResume, I just have a wakelock for that period of time.

Categories