Loading PDF from internal storage Error invalid format - java

So I've been practising download manager and i was trying out some program.
A first button will download a said Pdf to a location in my phone.
The second button is supposed to open the Pdf file with a Pdf reader installed by the user such as WP Reader etc..
The download works fine, but when i open the pdf , it says invalid format.
I uploaded a sample Pdf to the google drive , so I know that the uploaded file isnt corrupted in any case. There muse be some problem when the file is being downloaded from the server. Please help me find the mistake. And I am relatively new to Android.
And the download button uses an Onclicklistener while the loadPdf is given in the xml file android:onClick="downloadPdf" .
public class MainActivity extends AppCompatActivity {
String myHTTPUrl = "https://drive.google.com/open?id=0B5Pev9zz5bVjZTFFZ1dLZVp1WVU";
String TAG = "My app";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button download = (Button) findViewById(R.id.download);
download.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG,"download method called");
downloadPdf();
Toast.makeText(MainActivity.this,"Listener Called",Toast.LENGTH_SHORT).show();
Log.v(TAG,"On Click Listener Called");
}
});
}
public void loadPdf(View view) {
Log.v(TAG,"Pdf load called");
File pdfFile = new File(Environment.getExternalStorageDirectory()+"/notes","ssp.pdf");
if(pdfFile.exists())
{
Uri path = Uri.fromFile(pdfFile);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Intent intent = Intent.createChooser(pdfIntent, "Open File");
try
{
startActivity(intent);
}
catch(ActivityNotFoundException e)
{
Toast.makeText(MainActivity.this, "No Application available to view pdf", Toast.LENGTH_LONG).show();
}
}
else
{
Toast.makeText(MainActivity.this,"Pdf not found",Toast.LENGTH_SHORT).show();
}
}
public void downloadPdf()
{
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(myHTTPUrl));
request.setTitle("Solid State Physics");
request.setDescription("File is being Downloaded...");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir("/notes","ssp.pdf");
manager.enqueue(request);
}}
EDITED :
This is the exact error I'm facing with screenshot
Error : File format error , Cannot be opened
Screenshot of the error.

You're not downloading the PDF, you're downloading the web-page displaying the contents of the PDF. If you want to download the PDF file directly, use the following URL:
String myHTTPUrl = "https://drive.google.com/uc?export=download&id=0B5Pev9zz5bVjZTFFZ1dLZVp1WVU";
and your application should work.
(Don't forget to delete the invalid notes/ssp.pdf file first, otherwise the DownloadManager will download the file under a different name, like notes/ssp-1.pdf.)

Related

How I can prompt a file manager into a known path in an android app?

I have the following activity in my application:
public class DisplaySettingsActivity extends AppCompatActivity implements View.OnClickListener {
Button saveIntoFile;
TextView msg;
private ActivityResultLauncher<String> requestPermissionLauncher;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_settings);
requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
Log.d("H300s","Permissions Callback");
if (isGranted) {
Log.d("H300s","Permission Accepted 2");
saveFile();
} else {
permissionSaveDenied();
}
});
this.saveIntoFile = (Button)findViewById(R.id.save);
this.saveIntoFile.setOnClickListener(this);
}
private void saveFile(){
Log.d("Η300s","Saving");
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
Log.e("H300s","Unable to detect external storage");
saveMsgHandler(null);
return;
}
this.saveIntoFile.setEnabled(false);
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyMMdd");
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
file = new File( file.getAbsolutePath(),"voip_h300s_"+pattern.format(LocalDate.now())+".txt");
Log.d("H300s",file.toString());
try {
file.createNewFile();
PrintWriter out = new PrintWriter(new FileWriter(file));
out.println("SOME VALUES");
out.close();
saveMsgHandler(file.getAbsolutePath());
} catch (Exception e) {
saveMsgHandler(null);
}
}
#Override
public void onBackPressed() {
return;
}
private void saveMsgHandler(String savePath){
if (savePath == null) {
msg.setText(R.string.could_not_save_settings);
int errorColor = ContextCompat.getColor(this, R.color.error);
msg.setBackgroundColor(errorColor);
} else {
String string = String.format(getString(R.string.save_success),savePath);
msg.setText(string);
int success = ContextCompat.getColor(this, R.color.success);
msg.setBackgroundColor(success);
}
msg.setVisibility(View.VISIBLE);
this.saveIntoFile.setEnabled(true);
}
private void permissionSaveDenied(){
msg.setVisibility(View.VISIBLE);
msg.setText(R.string.could_not_save_settings);
int errorColor = ContextCompat.getColor(this, R.color.error);
msg.setBackgroundColor(errorColor);
this.saveIntoFile.setEnabled(true);
}
#Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.d("H300s","Permission Accepted");
saveFile();
} else {
requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE );
}
}
}
And I want once I save the file to be able to prompt into androids file manager and list the saved file. Any provided solution tells me hot to select a path before saving as seen in this answer or in this question, but instead I want just to show the file into device's file manager after I successfully saving it.
So far, what I've developed is this method:
public void displayFileIntoFileManager(String path){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivity(intent, 7);
}
As a method to call from a button, once I saved the file in saveFile method. But how I can provide the path to the intent in order to be shown?
I just want to list the file into device's file manager.
I want just to show the file into device's file manager after I successfully saving it.
There is no standard Intent action for "open a file manager on a directory containing a specific file", sorry.
So far, what I've developed is this method
ACTION_GET_CONTENT is to allow the user to select a piece of content. If you are not looking to have the user do that, then this is not a suitable Intent action.
How I can prompt a file manager into a known path in an android app?
Wrong question.
You should have asked:
How can i let ACTION_GET_CONTENT, ACTION_OPEN_DOCUMENT and ACTION_OPEN_DOCUMENT_TREE open in a pre determined directory?
That question has been answered before.
The trick is to use extra INITIAL_URI.

How to upload images gotten from camera using Android Upload Service

I have been able to make users upload photos to server taken from their gallery, but when a user uses camera to capture live and upload, I get this error unsupported scheme: file::///storage/...
I am using android upload service library
implementation "net.gotev:uploadservice:3.5.2"
I searched and discovered that file:// scheme is not allowed to be attached with Intent.
1. Selecting image from camera on button click
capture_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(UploadActivity2.this, BuildConfig.APPLICATION_ID + ".provider",
createImageFile()));
startActivityForResult(intent, 0);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
2. Getting the image captured
if (resultCode == Activity.RESULT_OK)
switch (requestCode){
case 0:
try {
Uri cameraPath = FileProvider.getUriForFile(UploadActivity2.this,
BuildConfig.APPLICATION_ID + ".provider", createImageFile());
String stringUri = cameraPath.toString();
selectedImages.add(stringUri);
}catch (IOException ex) {
ex.printStackTrace();
Glide.with(this)
.load(cameraFilePath)
.into(display_image);
break;
}
}
As you see, I am using file provider to get Uri and storing the uri in a variable called selectedimages so I can pass it through an intent to another activity where the upload occurs
createImageFile method
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.UK).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
//This is the directory in which the file will be created. This is the default location of Camera photos
File storageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "Camera");
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for using again
cameraFilePath = "file://" + image.getAbsolutePath();
return image;
}
3. Passing intent PATH, to uploadActivity
next_upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(UploadActivity2.this, UploadActivity3.class);
intent.putStringArrayListExtra("PATH", selectedImages);
startActivity(intent);
}
});
5. UploadAcvity where the upload happens
public void upload() {
ArrayList<String> selectedImages = getIntent().getStringArrayListExtra("PATH");
try {
String uploadId = UUID.randomUUID().toString();
//Creating a multi part request
new MultipartUploadRequest(this, uploadId, EndPoints.UPLOAD_URL)
.addFileToUpload(selectedImages.get(0), "image") //Adding file
.addParameter("caption", captionx) //Adding text parameter to the request
.setNotificationConfig(new UploadNotificationConfig())
.setMaxRetries(0)
.startUpload(); //Starting the upload
} catch (Exception exc) {
Toast.makeText(this, exc.getMessage(), Toast.LENGTH_SHORT).show();
}
}
Using this.
a. The image is not displaying in point 2 using Glide.with(this)
.load(cameraFilePath)
.into(display_image);
b. The image uploads but it is an empty file of 0 bytes.
But when I change the value of the variable of selectedImages in point 2 from selectedImages.add(stringUri); to selectedImages.add(cameraFilePath);
b. After clicking upload, I get error unsupported scheme: file::///storage/
Found the answer.
1. In the createImageFile method. I had to get the coontent:// url from the captured file using -
File newFile = new File(storageDir, image.getName());
contentUrl = FileProvider.getUriForFile(UploadActivity2.this,
BuildConfig.APPLICATION_ID + ".provider", newFile);
stringContentUrl = contentUrl.toString();
2. Then I passed the stringContentUrl into selected images String while getting the image captured.
selectedImages.add(stringContentUrl);
3. Passed it through an intent Extra and called it in the uploadActivity as seen in point 3 and 4 in the question.

How to save Captured Images to Custom path in android Storage

I have built an Camera application following a Tutorial from Youtube. It saves the Files on External Storage with following code
public void takePicture(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
file = Uri.fromFile(getOutputMediaFile());
intent.putExtra(MediaStore.EXTRA_OUTPUT, file);
startActivityForResult(intent, 100);
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "CameraDemo");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("CameraDemo", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(mediaStorageDir.getPath() + File.separator +
"IMG_" + timeStamp + ".jpg");
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
if (resultCode == RESULT_OK) {
imageView.setImageURI(file);
}
}
}
But, I would like to show a Dialog box to user when app starts with directory chooser dialog where they want to save images which I followed the Tutorial from this link https://www.codeproject.com/Articles/547636/Android-Ready-to-use-simple-directory-chooser-dial
The code for Directory choose dialog is below
DirectoryChooserDialog directoryChooserDialog =
new DirectoryChooserDialog(MainActivity.this,
new DirectoryChooserDialog.ChosenDirectoryListener()
{
#Override
public void onChosenDir(String chosenDir)
{
m_chosenDir = chosenDir;
Toast.makeText(
MainActivity.this, "Chosen directory: " +
chosenDir, Toast.LENGTH_LONG).show();
}
});
// Toggle new folder button enabling
directoryChooserDialog.setNewFolderEnabled(m_newFolderEnabled);
// Load directory chooser dialog for initial 'm_chosenDir' directory.
// The registered callback will be called upon final directory selection.
directoryChooserDialog.chooseDirectory(m_chosenDir);
m_newFolderEnabled = ! m_newFolderEnabled;
And also indeed, I have a separate class of DirectoryChooserDialog.
Now how do I merge the first code with second one such that when Image taken from camera will save to the folder that users selected from second code not to external storage Directory as specified by first code.
Image file for DirectoryChooserDialog appears as

Refresh activity without open again?

I have button for for install apk file download from server in specific folder and user some time delete apk file from folder but this button do not disable in same time but should exit activity and open again ... my question is how refresh status button after delete file apk by user without open activity again
Button install = (Button) findViewById(R.id.install_font);
final File file_1 = new File(Environment.getExternalStorageDirectory() + "/download/app-debug.apk");
if(file_1.exists()){
install.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/"+"app-debug.apk")),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}else {
install_font.setEnabled(false);
}
}
and i try add onResume but disable button all time mean if apk file exists the button is disable and apk file not exists the button is disable
#Override
public void onResume() {
super.onResume();
final File file = new File(Environment.getExternalStorageDirectory() + "/download/app-debug.apk");
final Button install_font = (Button) findViewById(R.id.install_font);
install_font.setEnabled(false);
}
You could check if your file exist every time the user enter to the application , then set the enabled flag based on it.
Try this code:
#Override
public void onResume() {
super.onResume();
final File file = new File(Environment.getExternalStorageDirectory() + "/download/app-debug.apk");
final Button install_font = (Button) findViewById(R.id.install_font);
install_font.setEnabled(file.exists());
}

Parsing Error on downloading and running an .apk file

I have a feature in my app which allows the user to download a new version.
But my problem is when I start the intent which should start the installation proccess there is a message:
Parse error. There was a problem parsing the package
This is my code
Button button;
String urlApp = "example.com/app.apk"
String fileName = "app.apk";
DownloadManager downloadManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File file = new File(Environment.DIRECTORY_DOWNLOADS, fileName);
if (file.exists()){
boolean deleted = file.delete();
Toast.makeText(getApplicationContext(), "Deleted", Toast.LENGTH_SHORT).show();
}
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urlApp));
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("Click to update");
downloadManager.enqueue(request);
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
});
}
private void openFile() {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(new File(Environment.DIRECTORY_DOWNLOADS+"/"+fileName)),
"application/vnd.android.package-archive");
startActivity(install);
}
BroadcastReceiver onComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
openFile();
}
};
}
It's just for .apk files, .txt files work fine. There is neither a error on the logcat.
The deleting is also not working but this isn't my primary problem.
Thanks in advance :D
Sorry if this is a stupid problem but this is my first time working with the download manager
Ok, i finally solved it
Instead of:
install.setDataAndType(Uri.fromFile(new File(Environment.DIRECTORY_DOWNLOADS+"/"+fileName)),
"application/vnd.android.package-archive");
i used
install.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/"+fileName)),
"application/vnd.android.package-archive");
I have come across the same problem earlier.
Please check the Min API level for your new Application version and the API level of the device you are using.

Categories

Resources