Starting new Activity after finish of several Async-Tasks - java

I tried to Download and Unzip files if there is an update on a server and all works perfect. But I want to open the next Activity only after all files have been downloaded and unzipped, not when it started downloading.
This is my Activity:
package com.example;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class Update extends AppCompatActivity {
private ProgressDialog ringProgressDialog;
private static Boolean finished = false;
private String read(String fileName) {
StringBuilder retString = new StringBuilder();
String zeilenumbruch = "\n";
BufferedReader reader = null;
try {
File file = new File(fileName);
FileInputStream in = new FileInputStream(Environment.getExternalStorageDirectory().toString() + "/.example/Anleitungen/.data/Versions/" + fileName);
reader = new BufferedReader(new InputStreamReader(in));
String zeile;
while ((zeile = reader.readLine()) != null) {
retString.append(zeile);
}
reader.close();
} catch (IOException ex) {
Log.e(getPackageName(), ex.getMessage());
}
return retString.toString();
}
public static String getTextOfUrl(String uri) throws Exception {
StringBuilder result = new StringBuilder();
URL url = new URL(uri);
String line = null;
BufferedReader reader = null;
finished = false;
try {
reader = new BufferedReader(new InputStreamReader(url.openStream()));
while ((line = reader.readLine()) != null) {
result.append(line);
}
return result.toString();
} finally {
if (reader != null) {
reader.close();
}
finished = true;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "Updating");
wl.acquire();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute();
}
private void downloadAndUnzipContent(String path, String urlPath) {
String url = urlPath;
DownloadFileAsync download = new DownloadFileAsync(path, this, new DownloadFileAsync.PostDownload() {
#Override
public void downloadDone(File file) {
Log.i(getPackageName(), "file download completed");
// check unzip file now
Decompress unzip = new Decompress(Update.this, file, true);
unzip.unzip();
Log.i(getPackageName(), "File unzip completed");
}
});
download.execute(url);
}
private void downloadContent(String path, String urlPath) {
DownloadFileAsync download = new DownloadFileAsync(path, this, new DownloadFileAsync.PostDownload() {
#Override
public void downloadDone(File file) {
Log.i(getPackageName(), "file download completed");
}
});
download.execute(urlPath);
}
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
private String resp;
#Override
protected String doInBackground(String... params) {
try {
List<String> files = new ArrayList<String>();
files.add("Archiv");
files.add("Funkempfaenger");
files.add("Funkhandsender");
files.add("Funksender");
files.add("Funksensoren");
files.add("Hausautomatisierung");
files.add("Jalousieantriebe");
files.add("Rohrantriebe");
files.add("SensorenKabelgebunden");
files.add("Sonderantriebe");
files.add("Torantriebe");
files.add("Torsteuerungen");
files.add("WandgeraeteKabelgebunden");
for (int uI = 0; uI < files.size(); uI++) {
try {
String newVersion = getTextOfUrl("http://www.example.com/zip/Versions/" + files.get(uI) + ".txt");
int nV = Integer.parseInt(newVersion);
String readString = files.get(uI) + ".txt";
String oldVersion = read(readString);
int iV = Integer.parseInt(oldVersion);
if (iV < nV) {
while (!finished) {
Log.i(getPackageName(), "Finished = False");
}
String dlPath = Environment.getExternalStorageDirectory() + "/.example/Anleitungen/.data/" + files.get(uI) + ".zip";
String dlPath2 = Environment.getExternalStorageDirectory() + "/.example/Anleitungen/.data/Versions/" + files.get(uI) + ".txt";
downloadAndUnzipContent(dlPath, "http://www.example.com/zip/Versions/" + files.get(uI) + ".zip");
downloadContent(dlPath2, "http://www.example.com/zip/Versions/" + files.get(uI) + ".txt");
}
} catch (Exception e) {
e.printStackTrace();
publishProgress(e.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "HI!";
}
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
Toast.makeText(Update.this, getString(R.string.UpdateFinished), Toast.LENGTH_LONG).show();
Intent intent = new Intent(Update.this, Home.class);
startActivity(intent);
finish();
}
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
}
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
#Override
protected void onProgressUpdate(String... text) {
Toast.makeText(Update.this, text[0], Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBackPressed() {
Log.i(getPackageName(), "Back pressed");
}
}
This is my Decompress.class:
package com.example;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Decompress {
private File _zipFile;
private InputStream _zipFileStream;
private Context context;
private static String ROOT_LOCATION = "/sdcard";
private static final String TAG = "UNZIPUTIL";
private Boolean pathNew;
public Decompress(Context context, File zipFile, Boolean path) {
_zipFile = zipFile;
this.context = context;
pathNew = path;
if (pathNew) {
ROOT_LOCATION = "/sdcard/.example/Anleitungen";
}
_dirChecker("");
}
public Decompress(Context context, InputStream zipFile) {
_zipFileStream = zipFile;
this.context = context;
_dirChecker("");
}
public void unzip() {
try {
Log.i(TAG, "Starting to unzip");
InputStream fin = _zipFileStream;
if(fin == null) {
fin = new FileInputStream(_zipFile);
}
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v(TAG, "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(ROOT_LOCATION + "/" + ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(new File(ROOT_LOCATION, ze.getName()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
// reading and writing
while((count = zin.read(buffer)) != -1)
{
baos.write(buffer, 0, count);
byte[] bytes = baos.toByteArray();
fout.write(bytes);
baos.reset();
}
fout.close();
zin.closeEntry();
}
}
zin.close();
Log.i(TAG, "Finished unzip");
} catch(Exception e) {
Log.e(TAG, "Unzip Error", e);
Toast.makeText(context, "Error while unzipping: " + e.toString(), Toast.LENGTH_LONG).show();
}
}
private void _dirChecker(String dir) {
File f = new File(dir);
Log.i(TAG, "creating dir " + dir);
if(dir.length() >= 0 && !f.isDirectory() ) {
f.mkdirs();
}
}
}
This is my DownloadFileAsnyc.class:
package com.example;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class DownloadFileAsync extends AsyncTask<String, String, String> {
private static final String TAG ="DOWNLOADFILE";
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private PostDownload callback;
private Context context;
private FileDescriptor fd;
private File file;
private String downloadLocation;
public DownloadFileAsync(String downloadLocation, Context context, PostDownload callback){
this.context = context;
this.callback = callback;
this.downloadLocation = downloadLocation;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection connection = url.openConnection();
connection.connect();
int lenghtOfFile = connection.getContentLength();
Log.d(TAG, "Length of the file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
file = new File(downloadLocation);
FileOutputStream output = new FileOutputStream(file); //context.openFileOutput("content.zip", Context.MODE_PRIVATE);
Log.d(TAG, "file saved at " + file.getAbsolutePath());
fd = output.getFD();
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(TAG,progress[0]);
}
#Override
protected void onPostExecute(String unused) {
if(callback != null) callback.downloadDone(file);
}
public static interface PostDownload{
void downloadDone(File fd);
}
}
Please help me. Sorry for my bad English.
Thank you.

You are starting the new Activity whenever AsyncTaskRunner finishes executing its background job. AsyncTaskRunner is basically just launching multiple DownloadFileAsync tasks.
AsyncTaskRunner won't wait for the launched tasks to complete. It will just launch them and finish the task which causes your new Activity to start.
The optimal way to fix this is to use only one AsyncTask that process each file sequentially. A dirty way would be to make AsyncTaskRunner wait for each DownloadFileAsync task to finish before launching the next. You can do this by calling the .get() method on each task:
download.execute(url).get();
But again, this defeats the purpose of AsyncTasks.

Related

Unable to fetch file from google drive

I am working on a project where user can upload a document to my server. This file can be selected either from local storage or a cloud storage ,say google drive. When i click on the file from file chooser all i am receiving is an account info and doc info as a uri, When i tried to fetch doc from this URI it is showing FileNotFound . I have gone through Drive API also but It is a bit confusing to me. Following are the points i came accross while trying Google Drive API:
1. How to select file from local storage.
2. How do I get FileId form the selected file.
I tried with the following code snippet:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("**/");
startActivityForResult(intent, 1000);
and In onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
// The ACTION_OPEN_DOCUMENT intent was sent with the request code
// READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
// response to some other intent, and the code below shouldn't run at all.
if (requestCode == 1000 && resultCode == Activity.RESULT_OK) {
// The document selected by the user won't be returned in the intent.
// Instead, a URI to that document will be contained in the return intent
// provided to this method as a parameter.
// Pull that URI using resultData.getData().
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
Log.i("URI", "Uri: " + uri.toString());
try {
readTextFromUri(uri);
getMimeType(this,uri);
} catch (IOException e) {
e.printStackTrace();
}
// showImage(uri);
}
}
}
private String readTextFromUri(Uri uri) throws IOException {
// FileInputStream fileInputStream=new FileInputStream(uri.)
InputStream inputStream = getContentResolver().openInputStream(uri);
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
// fileInputStream.close();
// parcelFileDescriptor.close();
return stringBuilder.toString();
}
Conclusion:
Can anyone please send me a link how to upload a document(I should even check the extension of the document) from both local storage and Google drive in a File chooser.
package com.example.ayyappaboddupalli.gdrive;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveClient;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.DriveResourceClient;
import com.google.android.gms.drive.OpenFileActivityOptions;
import com.google.android.gms.drive.query.Filters;
import com.google.android.gms.drive.query.SearchableField;
import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.TaskCompletionSource;
import com.google.api.services.drive.model.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Google drive";
private static final String SIGN_IN = "Sign In";
private static final String DOWNLOAD_FILE = "Download file";
private static final int REQUEST_CODE_SIGN_IN = 0;
private static final int REQUEST_CODE_OPEN_ITEM = 1;
private static final int REQUEST_WRITE_STORAGE = 112;
private GoogleSignInAccount signInAccount;
private Set<Scope> requiredScopes;
private DriveClient mDriveClient;
private DriveResourceClient mDriveResourceClient;
private OpenFileActivityOptions openOptions;
private TaskCompletionSource<DriveId> mOpenItemTaskSource;
private java.io.File storageDir;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_main);
initialize();
requestPermission();
signInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {
initializeDriveClient(signInAccount);
} else {
// onDriveClientReady();
signIn();
}
Button button=(Button)findViewById(R.id.Submit);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onDriveClientReady();
}
});
}
private void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_SIGN_IN:
if (resultCode == RESULT_OK) {
Task<GoogleSignInAccount> getAccountTask = GoogleSignIn.getSignedInAccountFromIntent(data);
if (getAccountTask.isSuccessful()) {
initializeDriveClient(getAccountTask.getResult());
showMessage("Sign in successfully.");
// binding.btnSubmit.setText(DOWNLOAD_FILE);
} else {
showMessage("Sign in failed.");
}
} else {
showMessage("Sign in failed.");
}
break;
case REQUEST_CODE_OPEN_ITEM:
if (resultCode == RESULT_OK) {
DriveId driveId = data.getParcelableExtra(OpenFileActivityOptions.EXTRA_RESPONSE_DRIVE_ID);
mOpenItemTaskSource.setResult(driveId);
} else {
mOpenItemTaskSource.setException(new RuntimeException("Unable to open file"));
}
break;
}
}
private void initialize() {
requiredScopes = new HashSet<>(2);
requiredScopes.add(Drive.SCOPE_FILE);
requiredScopes.add(Drive.SCOPE_APPFOLDER);
openOptions = new OpenFileActivityOptions.Builder()
.setSelectionFilter(Filters.eq(SearchableField.MIME_TYPE, "application/pdf"))
.setActivityTitle("Select file")
.build();
}
private void initializeDriveClient(GoogleSignInAccount signInAccount) {
mDriveClient = Drive.getDriveClient(getApplicationContext(), signInAccount);
mDriveResourceClient = Drive.getDriveResourceClient(getApplicationContext(), signInAccount);
}
private void signIn() {
GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.requestScopes(Drive.SCOPE_APPFOLDER)
.build();
GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
startActivityForResult(googleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
private void onDriveClientReady() {
mOpenItemTaskSource = new TaskCompletionSource<>();
mDriveClient.newOpenFileActivityIntentSender(openOptions)
.continueWith(new Continuation<IntentSender, Void>() {
#Override
public Void then(#NonNull Task<IntentSender> task) throws Exception {
startIntentSenderForResult(
task.getResult(), REQUEST_CODE_OPEN_ITEM, null, 0, 0, 0);
return null;
}
});
Task<DriveId> tasks = mOpenItemTaskSource.getTask();
tasks.addOnSuccessListener(this,
new OnSuccessListener<DriveId>() {
#Override
public void onSuccess(DriveId driveId) {
retrieveContents(driveId.asDriveFile());
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showMessage("File not selected.");
}
});
}
private void retrieveContents(final DriveFile file) {
// [START open_file]
final Task<DriveContents> openFileTask = mDriveResourceClient.openFile(file, DriveFile.MODE_READ_ONLY);
// [END open_file]
// [START read_contents]
openFileTask.continueWithTask(new Continuation<DriveContents, Task<Void>>() {
#Override
public Task<Void> then(#NonNull Task<DriveContents> task) throws Exception {
DriveContents contents = task.getResult();
Log.v(TAG, "File name : " + contents.toString());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
InputStream input = contents.getInputStream();
try {
java.io.File file = new java.io.File(getExternalFilesDir(null), "umesh.pdf");
Log.v(TAG, storageDir + "");
OutputStream output = new FileOutputStream(file);
try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
showMessage("Download file successfully.");
return mDriveResourceClient.discardContents(contents);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showMessage("Unable to download file.");
}
});
// [END read_contents]
}
private void requestPermission() {
String dirPath = getFilesDir().getAbsolutePath() + java.io.File.separator + "PDF";
storageDir = new java.io.File(dirPath);
if (!storageDir.exists())
storageDir.mkdirs();}}
//in gradle
implementation 'com.google.android.gms:play-services:11.8.0'
compile 'com.google.android.gms:play-services-auth:11.8.0'
compile 'com.google.api-client:google-api-client:1.23.0'
compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
compile 'com.google.apis:google-api-services-drive:v3-rev110-1.23.0'

Need to download a pdf and store in sd card in android

using below code and able to save in application cache but not in sd card..In sd card the file saved is of 0 bytes not able to get the exact error.....thanks in advance
final FileOutputStream f = new FileOutputStream(directory);
URL u = new URL(fileURL);
final HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
Thread thread = new Thread(new Runnable() {
#SuppressWarnings("deprecation")
#Override
public void run() {
try {
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
int flag = 0;
while ((len1 = in.read(buffer)) != -1) {
f.write(buffer, 0, len1);
Log.d("Thread ", String.valueOf(len1));
}
f.close();
thread.start();
} catch (Exception e) {
Toast.makeText(this, "In exception", Toast.LENGTH_LONG).show();
e.printStackTrace();
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
Use the following code to download any kind of file. I have checked this. It works like a charm.
Please check this out.
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
public class DownloadMultimedia extends AsyncTask<Void, Void, Void> {
protected static final int SHOW_PROGRESS_DIALOG = 0x5;
protected static final int STOP_PROGRESS_DIALOG = 0x6;
protected static final int NETWORK_FAILURE = 0x7;
protected static final int PROBLEM_IN_CONNECTING_SERVER = 0x8;
protected static final int DOWNLOADED_SUCCESS = 0x12;
protected static final int DOWNLOADED_FAILED = 0X13;
private URL url;
private String PATH;
private String fileName = "";
private Context context;
private String mReceivedURL = "";
public DownloadMultimedia(Context context,
String mReceivedURL) {
// TODO Auto-generated constructor stub
// Here Received URL is your url to download.
this.context = context;
this.mReceivedURL = mReceivedURL;
fileName = mReceivedURL.substring(mReceivedURL.lastIndexOf("/") + 1,
mReceivedURL.length());
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
downloadPhoto(mReceivedURL);
return null;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
mHandler.sendEmptyMessage(SHOW_PROGRESS_DIALOG);
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
mHandler.sendEmptyMessage(STOP_PROGRESS_DIALOG);
}
public void downloadPhoto(String Video_URL) {
try {
url = new URL(Video_URL);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
PATH = Environment.getExternalStorageDirectory()
+ "/Media/Videos/";
Log.d("", "the path to store : " + PATH);
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, fileName);
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
mHandler.sendEmptyMessage(DOWNLOADED_SUCCESS);
} catch (Exception e) {
mHandler.sendEmptyMessage(DOWNLOADED_FAILED);
Log.d("TAG", " downloadVideo exception " + e.getMessage());
}
}
Handler mHandler = new Handler() {
private ProgressDialog progressDialog;
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case SHOW_PROGRESS_DIALOG:
if (progressDialog == null) {
progressDialog = Utils.createProgressDialog(context);
progressDialog.show();
} else {
progressDialog.show();
}
mHandler.removeMessages(SHOW_PROGRESS_DIALOG);
break;
case STOP_PROGRESS_DIALOG:
progressDialog.dismiss();
mHandler.removeMessages(STOP_PROGRESS_DIALOG);
break;
case NETWORK_FAILURE:
Utils.displayToast(context, Constant.NO_NETWORK_CONNECTION);
mHandler.removeMessages(NETWORK_FAILURE);
break;
case PROBLEM_IN_CONNECTING_SERVER:
Utils.displayToast(context,
Constant.PROBLEM_IN_CONNECTING_SERVER);
mHandler.removeMessages(PROBLEM_IN_CONNECTING_SERVER);
break;
case DOWNLOADED_SUCCESS:
Utils.displayToast(context, "File has been downloaded");
mHandler.removeMessages(DOWNLOADED_SUCCESS);
break;
case DOWNLOADED_FAILED:
Utils.displayToast(context, "Error, Try again later");
mHandler.sendEmptyMessage(DOWNLOADED_FAILED);
break;
default:
break;
}
};
};
}
Meantime, I will go through your code and check what wrong with that.

Read a pdf file from assets folder

public void DOCS(View btnDocs)
{
File fileBrochure = new File("android.resource://com.project.datastructure/assets/abc.pdf");
if (!fileBrochure.exists())
{
CopyAssetsbrochure();
}
/** PDF reader code */
File file = new File("android.resource://com.project.datastructure/assets/abc.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try
{
getApplicationContext().startActivity(intent);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(Stack_dr.this, "NO Pdf Viewer", Toast.LENGTH_SHORT).show();
}
}
private void CopyAssetsbrochure() {
AssetManager assetManager = getAssets();
String[] files = null;
try
{
files = assetManager.list("");
}
catch (IOException e){}
for(int i=0; i<files.length; i++)
{
String fStr = files[i];
if(fStr.equalsIgnoreCase("abc.pdf"))
{
InputStream in = null;
OutputStream out = null;
try
{
in = assetManager.open(files[i]);
out = new FileOutputStream("/sdcard/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
break;
}
catch(Exception e){}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
I am trying to read a pdf file from assets folder which is present in my application folder . Everything is working perfectly when i click on my DOCS button a pop up comes to let me choose an application for opening the pdf i.e "abc.pdf" but after selecting an option i get an error message "The file path is not valid". I think their is some problem with the path which i have specified in the code.
please help
Try this
public class SampleActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CopyReadAssets();
}
private void CopyReadAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), "abc.pdf");
try
{
in = assetManager.open("abc.pdf");
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file://" + getFilesDir() + "/abc.pdf"),
"application/pdf");
startActivity(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
}
Make sure to include
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in manifest
You can do it like this (tested and working on API 27)
Step 1
Add following dependency in your app gradle:
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
Step 2
Add following XML code:
<com.github.barteksc.pdfviewer.PDFView
android:id="#+id/pdfv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.github.barteksc.pdfviewer.PDFView>
Step 3
Add following code in your java file:
public class MainActivity extends AppCompatActivity {
PDFView pdfView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView=findViewById(R.id.pdfv);
pdfView.fromAsset("filename.pdf").load();
}
}
These changes will load a PDF file on creation of your activity.
Though this has been answered, I wanted to share my solution as I think it is a bit easier to include.
Usage:
new OpenLocalPDF(context, 'nameOfPDFStoredInAssets').execute()
And here is the OpenLocalPDF class:
public class OpenLocalPDF {
private static String TAG = OpenLocalPDF.class.getSimpleName();
private WeakReference<Context> contextWeakReference;
private String fileName;
public OpenLocalPDF(Context context, String fileName) {
this.contextWeakReference = new WeakReference<>(context);
this.fileName = fileName.endsWith("pdf") ? fileName : fileName + ".pdf";
}
public void execute() {
Context context = contextWeakReference.get();
if (context != null) {
new CopyFileAsyncTask().execute();
}
}
private class CopyFileAsyncTask extends AsyncTask<Void, Void, File> {
final String appDirectoryName = BuildConfig.APPLICATION_ID;
final File fileRoot = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), appDirectoryName);
#Override
protected File doInBackground(Void... params) {
Context context = contextWeakReference.get();
AssetManager assetManager = context.getAssets();
File file = new File(fileRoot, fileName);
InputStream in = null;
OutputStream out = null;
try {
file.mkdirs();
if (file.exists()) {
file.delete();
}
file.createNewFile();
in = assetManager.open(fileName);
Log.d(TAG, "In");
out = new FileOutputStream(file);
Log.d(TAG, "Out");
Log.d(TAG, "Copy file");
copyFile(in, out);
Log.d(TAG, "Close");
in.close();
out.flush();
out.close();
return file;
} catch (Exception e)
{
Log.e(TAG, e.getMessage());
}
return null;
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
#Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
Context context = contextWeakReference.get();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.fromFile(file),
"application/pdf");
context.startActivity(intent);
}
}
}
add this permission in Manifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
like say sunsil, but in the case for external directory.
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
copyReadAssets();
}
private void copyReadAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
String strDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+ File.separator + "Pdfs";
File fileDir = new File(strDir);
fileDir.mkdirs(); // crear la ruta si no existe
File file = new File(fileDir, "example2.pdf");
try
{
in = assetManager.open("example.pdf"); //leer el archivo de assets
out = new BufferedOutputStream(new FileOutputStream(file)); //crear el archivo
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + "Pdfs" + "/example2.pdf"), "application/pdf");
startActivity(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
}
change parts of code like these:
out = new BufferedOutputStream(new FileOutputStream(file));
the before example is for Pdfs, in case of to example .txt
FileOutputStream fos = new FileOutputStream(file);
This works for me.
Step 1: In MainActivity.java
public class SampleActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//call this method by passing file name in params.
readFromAssets("User guide.pdf");
}
public static void readFromAssets(String fileName) {
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(mContext.getFilesDir(), fileName);
try {
in = assetManager.open(fileName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
out = mContext.openFileOutput(file.getName(), Context.MODE_PRIVATE);
} else {
out = mContext.openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
}
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
Uri pdfFileURI;
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pdfFileURI = FileProvider.getUriForFile(mContext,
BuildConfig.APPLICATION_ID + ".provider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
pdfFileURI = Uri.parse("file://" + mContext.getFilesDir() + "/" + fileName);
}
intent.setDataAndType(pdfFileURI, "application/pdf");
mContext.startActivity(intent);
}
private static void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
}
Step 2: Create provider_paths.xml inside res->xml->provider_paths.xml. See here
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<root-path
name="root"
path="." />
</paths>
Step 3: In AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppThemeMaterial">
<!-- INSIDE APPLICATION TAG -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
No answer worked for me out-of-the-box when attempting to open a file via an intent (in my case PDF) from the assets folder. So here is my solution combining 2 brilliant answers I'm sure it will help someone. Must be for api >= 24.
Once you have followed this link and added the your own GenericFileProvider and declared it in your manifest within the Application tag and created the provider_paths.xml simply use the below class and call it like:
OpenLocalPDF(this, "YOUR_PDF_NAME_IN_ASSETS_FOLDER.pdf").execute()
OpenLocalPdf.kt: (kudos too the OP https://stackoverflow.com/a/41212708/1133011)
import android.content.Context
import android.content.Intent
import android.content.res.AssetManager
import android.os.AsyncTask
import android.util.Log
import androidx.core.content.FileProvider
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.lang.ref.WeakReference
class OpenLocalPDF(context: Context?, fileName: String?) {
private val contextWeakReference: WeakReference<Context?>?
private val fileName: String?
fun execute() {
val context: Context = contextWeakReference!!.get()!!
if (context != null) {
CopyFileAsyncTask().execute()
}
}
private inner class CopyFileAsyncTask :
AsyncTask<Void?, Void?, File?>() {
val appDirectoryName: String? = co.za.umbiflow.BuildConfig.APPLICATION_ID
val fileRoot: File? = File(
android.os.Environment.getExternalStoragePublicDirectory(
android.os.Environment.DIRECTORY_DOCUMENTS
), appDirectoryName
)
override fun doInBackground(vararg params: Void?): File? {
val context: Context = contextWeakReference!!.get()!!
val assetManager: AssetManager = context.getAssets()
val file = File(fileRoot, fileName)
var `in`: InputStream? = null
var out: OutputStream? = null
try {
file.mkdirs()
if (file.exists()) {
file.delete()
}
file.createNewFile()
`in` = assetManager.open(fileName)
out = FileOutputStream(file)
copyFile(`in`, out)
`in`.close()
out.flush()
out.close()
return file
} catch (e: Exception) {
Log.e(TAG, e.message)
}
return null
}
private fun copyFile(`in`: InputStream, out: OutputStream) {
val buffer = ByteArray(1024)
var read: Int
while (`in`.read(buffer).also { read = it } != -1) {
out.write(buffer, 0, read)
}
}
override fun onPostExecute(file: File?) {
super.onPostExecute(file)
val context: Context = contextWeakReference!!.get()!!
var pdfUri =
FileProvider.getUriForFile(
context,
context.packageName + ".provider",
file!!
)
val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.setDataAndType(
pdfUri,
"application/pdf"
)
context.startActivity(intent)
}
}
companion object {
private val TAG = OpenLocalPDF::class.java.simpleName
}
init {
contextWeakReference = WeakReference(context)
this.fileName = if (fileName!!.endsWith("pdf")) fileName else "$fileName.pdf"
}
}
This is a way to open multiple PDF files from assets using a zip file.
Step1: Copy a zip file(pdf.zip) into assets folder that contains the list of pdfs
Step2: Write PDF's into external cache inside the app in a Utils class
public static void writePDFs(Context context) {
try {
InputStream inputStream = context.getApplicationContext().getAssets().open("pdf.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry zipEntry;
File file = new File(context.getExternalCacheDir().getAbsolutePath(), "PDFs");
if (!file.getAbsoluteFile().exists()) {
if (file.mkdir()) {
BufferedOutputStream outputStream;
byte[] buffer = new byte[1024];
int count;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
String s1 = file + "/" + zipEntry.getName();
File file1 = new File(s1);
if (!file1.exists()) {
file1.createNewFile();
}
outputStream = new BufferedOutputStream(new FileOutputStream(file1));
while ((count = zipInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
outputStream.flush();
outputStream.close();
zipInputStream.closeEntry();
}
}
zipInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Step3: Call the above function in Activities onCreate
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FileUtils.writePDFs(this);
}
Step4: Create a common function in Utils class to open the PDF
public static void openPDF(Activity activity, String fileName) {
if (activity == null) return;
File file = new File(activity.getExternalCacheDir().getAbsolutePath() + "/PDFs" + "/" + fileName);
Uri docUri = GenericFileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName(), file);
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(docUri, "application/pdf");
} else {
intent.setDataAndType(Uri.fromFile(file), "application/pdf");
}
activity.startActivityForResult(intent, ACTIVITY_VIEW_ATTACHMENT);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
Step5: Call the openPDF function on click on the view in Activity
myView.setOnClickListener(v -> ApplicationUtils.openPDF(this, "MyPdfFile.pdf"));
I had success, using the answer from cYrixmorten, with the OpenLocalPDF class.
But, Environment.DIRECTORY_DOCUMENTS is not supported for Android 18. To support Android 18 - 28, I had to make the following changes.
In "CopyFileAsyncTask", change the fileRoot declaration:
final File fileRoot = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), appDirectoryName);
To this:
final File fileRoot = new File(Environment.getExternalStorageDirectory() + "/YourAppName");
In "onPostExecute", change this:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.fromFile(file),
"application/pdf");
context.startActivity(intent);
To this:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(FileProvider.getUriForFile(context, "com.example.yourappname.provider", file), "application/pdf");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
Finally, setup your manifest to support the FileProvider as described in this post.
try this:
public String getAssetsPdfPath(Context context) {
String filePath = context.getFilesDir() + File.separator + "myFile.pdf";
File destinationFile = new File(filePath);
try {
FileOutputStream outputStream = new FileOutputStream(destinationFile);
InputStream inputStream = context.getAssets().open("myFile.pdf");
byte[] buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
outputStream.close();
inputStream.close();
} catch (IOException e) {
Log.e(context.getClass().getSimpleName(), "Error.");
}
return destinationFile.getPath();
}
If you want to open a .pdf file that is stored locally in the assets folder without using an Intent to launch an external app, I suggest using the Android class PdfRenderer. Documentation found here.
This is a good example that worked for me.
However, this example wouldn't run when I downloaded it. I had to change it a bit to use the copyReadAssets() function as mentioned in the other answers here, then to reference the file (after it has been copied) I use:
File file = new File("/data/data/" + getContext().getPackageName() + "/files/mypdf.pdf");
I also ended up modifying onAttach() because it was using the deprecated form of onAttach() and closeRenderer() because it was throwing errors for closing objects that were null.
So my complete PdfRendererBasicFragment.java file looks like this:
package com.example.android.pdfrendererbasic;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.pdf.PdfRenderer;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* This fragment has a big {#ImageView} that shows PDF pages, and 2 {#link android.widget.Button}s to move between
* pages. We use a {#link android.graphics.pdf.PdfRenderer} to render PDF pages as {#link android.graphics.Bitmap}s.
*/
public class PdfRendererBasicFragment extends Fragment implements View.OnClickListener {
/**
* Key string for saving the state of current page index.
*/
private static final String STATE_CURRENT_PAGE_INDEX = "current_page_index";
/**
* File descriptor of the PDF.
*/
private ParcelFileDescriptor mFileDescriptor;
/**
* {#link android.graphics.pdf.PdfRenderer} to render the PDF.
*/
private PdfRenderer mPdfRenderer;
/**
* Page that is currently shown on the screen.
*/
private PdfRenderer.Page mCurrentPage;
/**
* {#link android.widget.ImageView} that shows a PDF page as a {#link android.graphics.Bitmap}
*/
private ImageView mImageView;
/**
* {#link android.widget.Button} to move to the previous page.
*/
private Button mButtonPrevious;
/**
* {#link android.widget.Button} to move to the next page.
*/
private Button mButtonNext;
public PdfRendererBasicFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_pdf_renderer_basic, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Retain view references.
mImageView = (ImageView) view.findViewById(R.id.image);
mButtonPrevious = (Button) view.findViewById(R.id.previous);
mButtonNext = (Button) view.findViewById(R.id.next);
// Bind events.
mButtonPrevious.setOnClickListener(this);
mButtonNext.setOnClickListener(this);
// Show the first page by default.
int index = 0;
// If there is a savedInstanceState (screen orientations, etc.), we restore the page index.
if (null != savedInstanceState) {
index = savedInstanceState.getInt(STATE_CURRENT_PAGE_INDEX, 0);
}
showPage(index);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
openRenderer(context);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
getActivity().finish();
}
}
#Override
public void onDetach() {
try {
closeRenderer();
} catch (IOException e) {
e.printStackTrace();
}
super.onDetach();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mCurrentPage) {
outState.putInt(STATE_CURRENT_PAGE_INDEX, mCurrentPage.getIndex());
}
}
/**
* Sets up a {#link android.graphics.pdf.PdfRenderer} and related resources.
*/
private void openRenderer(Context context) throws IOException {
// Copy the pdf to a usable location
CopyReadAssets();
File file = new File("/data/data/" + context.getPackageName() + "/files/sample.pdf");
mPdfRenderer = new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));
}
/**
* Closes the {#link android.graphics.pdf.PdfRenderer} and related resources.
*
* #throws java.io.IOException When the PDF file cannot be closed.
*/
private void closeRenderer() throws IOException {
if (mCurrentPage != null) {
mCurrentPage.close();
}
if (mPdfRenderer != null) {
mPdfRenderer.close();
}
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
}
/**
* Shows the specified page of PDF to the screen.
*
* #param index The page index.
*/
private void showPage(int index) {
if (mPdfRenderer.getPageCount() <= index) {
return;
}
// Make sure to close the current page before opening another one.
if (null != mCurrentPage) {
mCurrentPage.close();
}
// Use `openPage` to open a specific page in PDF.
mCurrentPage = mPdfRenderer.openPage(index);
// Important: the destination bitmap must be ARGB (not RGB).
Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),
Bitmap.Config.ARGB_8888);
// Here, we render the page onto the Bitmap.
// To render a portion of the page, use the second and third parameter. Pass nulls to get
// the default result.
// Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
// We are ready to show the Bitmap to user.
mImageView.setImageBitmap(bitmap);
updateUi();
}
/**
* Updates the state of 2 control buttons in response to the current page index.
*/
private void updateUi() {
int index = mCurrentPage.getIndex();
int pageCount = mPdfRenderer.getPageCount();
mButtonPrevious.setEnabled(0 != index);
mButtonNext.setEnabled(index + 1 < pageCount);
getActivity().setTitle(getString(R.string.app_name_with_index, index + 1, pageCount));
}
/**
* Gets the number of pages in the PDF. This method is marked as public for testing.
*
* #return The number of pages.
*/
public int getPageCount() {
return mPdfRenderer.getPageCount();
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.previous: {
// Move to the previous page
showPage(mCurrentPage.getIndex() - 1);
break;
}
case R.id.next: {
// Move to the next page
showPage(mCurrentPage.getIndex() + 1);
break;
}
}
}
private void CopyReadAssets()
{
AssetManager assetManager = getActivity().getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getActivity().getFilesDir(), "sample.pdf");
if(!file.exists()) {
try {
in = assetManager.open("sample.pdf");
out = getActivity().openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
else {
Log.d("test", "file already exists");
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
}
This code work on every android version:
Activity:
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import unimedbh.UnimedBH.R;
public class MainActivity extends Activity {
private static final int MY_PERMISSION_REQUEST_STORAGE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSION_REQUEST_STORAGE);
} else {
copyReadAssets("YOUR_PDF_NAME.pdf");
}
}
private void copyReadAssets(String fileName) {
String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyFiles";
File dir = new File(dirPath);
if (!dir.exists()) {
dir.mkdirs();
}
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(fileName);
File outFile = new File(dirPath, fileName);
out = new FileOutputStream(outFile);
copyFile(in, out);
Intent intent = new Intent(Intent.ACTION_VIEW, FileProvider.getUriForFile(this, "com.package.name.fileprovider", outFile));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Error!", Toast.LENGTH_SHORT).show();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
}
Manifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.package.name.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
file_paths.xml:
<paths>
<files-path name="app_directory" path="directory/"/>
</paths>
Tested in API 16-28, worked on all apiĀ“s!

Android, java - Unable to update variable from asynctask

Here is the code
Variable declared
public String gpu2dcurent = "1234567";
Asynctask, after finished it should update variable gpu2dcurent, but it doesnt
private class readgpu2d extends AsyncTask<String, Void, String> {
protected String doInBackground(String... args) {
Log.i("MyApp", "Background thread starting");
String aBuffer = "";
try {
File myFile = new File("/sys/devices/platform/kgsl-2d0.0/kgsl/kgsl-2d0/gpuclk");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
String aDataRow = "";
//String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow + "\n";
}
;
myReader.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
return aBuffer.trim();
}
protected void onPostExecute(String result) {
// Pass the result data back to the main activity
gpu2dcurent = result;
//Toast.makeText(getBaseContext(), result,
//Toast.LENGTH_SHORT).show();
gpu.this.data = result;
if (gpu.this.pd != null) {
//gpu.this.pd.dismiss();
}
}
}
Test to see if a variable has a new value. It doesn't, it displays 1234567
TextView tx = (TextView)findViewById(R.id.textView3);
tx.setText(gpu2dcurent);
Am i missing something? When i update textView from inside onPostExecute method it works fine but when Asynctask finishes variable value resets to default
public class gpu extends Activity{
public String gpu2dcurent = "1234567";
I have a doubt you are trying to set text of TextView before completion of your Asynctask.
Yes, either make it, static public String gpu2dcurent = "1234567";
Or, set Text of TextView in onPostExecute()
protected void onPostExecute(String result) {
// Pass the result data back to the main activity
gpu2dcurent = result;
//Toast.makeText(getBaseContext(), result,
//Toast.LENGTH_SHORT).show();
gpu.this.data = result;
if (gpu.this.pd != null) {
//gpu.this.pd.dismiss();
}
tx.setText(gpu2dcurent);
}
}
Update:
After update your code in question,
change this line,
new readgpu2d().execute("blablabla");
to
new readgpu2d().execute("blablabla").get();
try to put setText into onPostExecute
protected void onPostExecute(String result) {
TextView tx = (TextView)findViewById(R.id.textView3);
tx.setText(result);
// Pass the result data back to the main activity
gpu2dcurent = result;
//Toast.makeText(getBaseContext(), result,
//Toast.LENGTH_SHORT).show();
gpu.this.data = result;
if (gpu.this.pd != null) {
//gpu.this.pd.dismiss();
}
}
In gpu class declare it as followin:
public String gpu2dcurent = "1234567";
In AsyncTask class readgpu2d, use it as following:
gpu.gpu2dcurent = result;
Update your UI=User Interface means TextView in
onProgressUpdate()
method of AsyncTask.
And check where have you declared gpu2dcurent variable???
Here is the whole code
package rs.pedjaapps.DualCore;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.TimeoutException;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.TextView;
import android.widget.Toast;
import com.stericson.RootTools.RootTools;
import com.stericson.RootTools.RootToolsException;
public class gpu extends Activity{
public String gpu2dcurent = "1234567";
private ProgressDialog pd = null;
private Object data = null;
private class readgpu2d extends AsyncTask<String, Void, String> {
protected String doInBackground(String... args) {
Log.i("MyApp", "Background thread starting");
String aBuffer = "";
try {
File myFile = new File("/sys/devices/platform/kgsl-2d0.0/kgsl/kgsl-2d0/gpuclk");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
String aDataRow = "";
//String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow + "\n";
}
//gpu2dcurent = aBuffer.trim();
myReader.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
return aBuffer.trim();
}
protected void onPostExecute(String result) {
// Pass the result data back to the main activity
gpu2dcurent = result;
//Toast.makeText(getBaseContext(), result,
//Toast.LENGTH_SHORT).show();
gpu.this.data = result;
if (gpu.this.pd != null) {
gpu.this.pd.dismiss();
}
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gpu);
this.pd = ProgressDialog.show(this, "Working..", "Loading...", true, false);
new readgpu2d().execute("blablabla");
TextView tx = (TextView)findViewById(R.id.textView3);
tx.setText(gpu2dcurent);
}
}

Track FTP upload data in android?

I have a working FTP system with android, but I want to be able to track the bytes as they get uploaded, so I can update a progress bar as the upload progresses. Is this possible with Android? Right now, I'm using org.apache.common.net.ftp and the code I'm using is below. Also, I am running this in an AsyncTask.
package com.dronnoc.ftp.complex;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;
import org.apache.commons.net.io.Util;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
public class Main extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
String text = "BIGFILE"; //Big file here
InputStream data = new ByteArrayInputStream(text.getBytes());
new ComplexFTPTransfer().execute(data);
}
private class ComplexFTPTransfer extends AsyncTask<InputStream, Long[], Void>
{
private FTPClient ftp = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
ftp = new FTPClient();
ftp.connect("hostname");
} catch (SocketException e) {
this.cancel(true);
} catch (IOException e) {
this.cancel(true);
}
Main.this.setProgressBarIndeterminateVisibility(true);
}
#Override
protected Void doInBackground(InputStream... params) {
if(!this.isCancelled())
{
try
{
if(ftp.login("user", "pass"))
{
ftp.enterLocalPassiveMode();
InputStream item = params[0];
int streamSize = 0;
while(item.read() != -1)
{
streamSize++;
}
InputStream is = new BufferedInputStream(params[0], streamSize);
OutputStream os = ftp.storeFileStream("/test.txt");
Util.copyStream(is, os, streamSize, streamSize, new CopyStreamListener() {
#Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
publishProgress(new Long[] {totalBytesTransferred, streamSize});
}
#Override
public void bytesTransferred(CopyStreamEvent event) {
}
});
ftp.completePendingCommand();
}
ftp.logout();
ftp.disconnect();
}
catch (IOException e) {
}
catch (Exception e) {
}
}
return null;
}
#Override
protected void onProgressUpdate(Long[]... values) {
super.onProgressUpdate(values);
Log.d("UPDATE", values[0] + " of " + values[1] + " copied.");
//TODO Put code here
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Main.this.setProgressBarIndeterminateVisibility(false);
}
}
}
What I want to know is if I can run a progress bar, updating every few uploaded bytes?
Cheers
This question has an implementation of an InputStream that includes a progress callback. Use that InputStream and call publishProgress from that callback for incremental updates during the file upload.
Download this .jar file
httpmime-4.1.1.jar and commons-net.jar
try {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(InetAddress
.getByName(Your host Url));
ftpClient.login(loginName, password);
System.out.println("status :: " + ftpClient.getStatus());
ftpClient.changeWorkingDirectory(your directory name);
ftpClient.setFileType(FTP.IMAGE_FILE_TYPE);
//Your File path set here
File file = new File("/sdcard/my pictures/image.png");
BufferedInputStream buffIn = new BufferedInputStream(
new FileInputStream(myImageFile));
ftpClient.enterLocalPassiveMode();
ProgressInputStream progressInput = new ProgressInputStream(
buffIn);
boolean result = ftpClient.storeFile(UPLOADFILENAME + ".png",
progressInput);
System.out.println("result is :: " + result);
buffIn.close();
ftpClient.logout();
ftpClient.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
//ProgressInputStream
import java.io.IOException;
import java.io.InputStream;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class ProgressInputStream extends InputStream {
/* Key to retrieve progress value from message bundle passed to handler */
public static final String PROGRESS_UPDATE = "progress_update";
private static final int TEN_KILOBYTES = 1024 * 40;
private InputStream inputStream;
//private Handler handler;
private long progress;
private long lastUpdate;
private boolean closed;
public ProgressInputStream(InputStream inputStream) {
this.inputStream = inputStream;
this.progress = 0;
this.lastUpdate = 0;
this.closed = false;
}
#Override
public int read() throws IOException {
int count = inputStream.read();
return incrementCounterAndUpdateDisplay(count);
}
#Override
public int read(byte[] b, int off, int len) throws IOException {
int count = inputStream.read(b, off, len);
return incrementCounterAndUpdateDisplay(count);
}
#Override
public void close() throws IOException {
super.close();
if (closed)
throw new IOException("already closed");
closed = true;
}
private int incrementCounterAndUpdateDisplay(int count) {
if (count < 0)
progress += count;
lastUpdate = maybeUpdateDisplay(progress, lastUpdate);
return count;
}
private long maybeUpdateDisplay(long progress, long lastUpdate) {
if (progress - lastUpdate < TEN_KILOBYTES) {
lastUpdate = progress;
sendLong(PROGRESS_UPDATE, progress);
}
return lastUpdate;
}
public void sendLong(String key, long value) {
Bundle data = new Bundle();
data.putLong(key, value);
Message message = Message.obtain();
message.setData(data);
//handler.sendMessage(message);
}
}
This can be done using Secure FTP Factory library.
You just need to implement an instance of the com.jscape.inet.ftp.FtpListener interface, register the instance with the Ftp class and overload the progress(FtpProgressEvent event) method to capture progress information.
JavaDoc: Overview (secure FTP Factory API)
Download: Java FTP, Java FTPS and Java SFTP Components

Categories