Good morning. I have the following problem in ANDROID STUDIO, I have an application in which the user chooses a pdf or word file, gets the path of the path and if the user decides to upload the file to the server, the application copies the file selected and paste it into an internal directory created and from there it just proceeds to upload the file to the server. The application works from a minimum of 18 to 27. has been tested on a device of Android 21 Android 5.0.2 and there are no problems; When I tested with a device of api level 19 android 4.4.2 of the downloads folder, the following problem arises in the Logcat:
11-15 13:53:27.303 4363-4363/? E/CrearCarpteaAlIn: Error: No se creo el directorio privado
11-15 13:53:27.303 4363-4363/? E/Error: java.io.IOException: open failed: EACCES (Permission denied)
11-15 13:53:27.303 4363-4363/? W/System.err: java.io.IOException: open failed: EACCES (Permission denied)
11-15 13:53:27.313 4363-4363/? W/System.err: at java.io.File.createNewFile(File.java:972)
at com.example.usuario.prueba.SubirArchivosPDFWORD.onClick(SubirArchivosPDFWORD.java:161)
at android.view.View.performClick(View.java:4578)
at android.view.View$PerformClick.run(View.java:18654)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
11-15 13:53:27.323 4363-4363/? W/System.err: at dalvik.system.NativeStart.main(Native Method)
Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
at java.io.File.createNewFile(File.java:965)
... 12 more
Although it says Permissions Error, I have attaching the permissions in the manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I have searched the problem on the internet and I can not find the solution to the problem, it seems to me that it is because it does not get the path correctly when it gets it from downlodas since what it gets is
E/PATH: /data/user/0/com.android.providers.downloads/cache/ordcom64-doc2018-06-15.pdf
On the other hand, on the Path in another version of android it is
E/PATH: /storge/emulated/0/Download/solucione.pdf
This is my complete manifesto:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity" />
<activity android:name=".DescargarArchivosPDF">
</activity>
<activity android:name=".SubirImagenes">
</activity>
<activity android:name=".Galeria">
</activity>
<activity android:name=".SubirArchivosPDFWORD">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
This is my activity:
import android.Manifest;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
//FUNCIONA, SUBE ARCHIVOS DE INTERNO Y EXTERNO
public class SubirArchivosPDFWORD extends AppCompatActivity implements View.OnClickListener {
private Button BtnExaminar_Archivos, BtnSubir_Archivos;
private TextView TxVwNombre;
private static final int SELECT_FILE = 1;
private final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 124;
private boolean PERM_WRITE = false;
private String PATHIREAL, PATHREAL = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subir_archivos_pdf_word);
BtnExaminar_Archivos = (Button) findViewById(R.id.BtnExaminar_Archivos);
BtnSubir_Archivos = (Button) findViewById(R.id.BtnSubir_Archivos);
TxVwNombre = (TextView) findViewById(R.id.TxVwNombre);
BtnExaminar_Archivos.setOnClickListener(this);
BtnSubir_Archivos.setOnClickListener(this);
SolicitarPermiso();
}
void SolicitarPermiso() {
///Pregunta los Permisos
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//PERMISO DENEGADO
//HAY RESPUESTA
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "HAY RPA", Toast.LENGTH_SHORT).show();
//PERMISO DENEGADO
if (getPackageManager().PERMISSION_DENIED == -1) {
//PERMISO DENEGADO ANTERIORMENTE
Toast.makeText(this, "DENEGADO", Toast.LENGTH_SHORT).show();
///PIDE PERMISO
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {///PERMISO ACEPTADO
PERM_WRITE = true;
}
} else {
///NO HAY RESPUESTA
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
Toast.makeText(this, "NOHAY RPA", Toast.LENGTH_SHORT).show();
PERM_WRITE = false;
}
} else {//PERMISO ACEPTADO
PERM_WRITE = true;
Toast.makeText(this, "Aceptado Write", Toast.LENGTH_SHORT).show();
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "HAY RPTA READ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Aceptado Read", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//LLega Sirve para procesar la respuesta del Permiso
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "SI HAY PERMISO", Toast.LENGTH_SHORT).show();
PERM_WRITE = true;
} else {
Toast.makeText(this, "NO HAY PERMISO", Toast.LENGTH_SHORT).show();
PERM_WRITE = false;
}
break;
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.BtnExaminar_Archivos:
SolicitarPermiso();
if (PERM_WRITE) {
String[] mimeTypes = {"application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"};
Intent intent = new Intent();
intent.setType("application/*").putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
//intent.setType("image/JPG");
//intent.setType("image/jpeg");
//intent.setType("image/jpg");
//intent.setType("image/png");
//intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setAction(Intent.ACTION_GET_CONTENT);
Uri mImageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
startActivityForResult(
Intent.createChooser(intent, "Seleccione un DOCUMENTO"),
1);
}
break;
case R.id.BtnSubir_Archivos:
try {
File interno = new File(crearCarpetaAlmInterno() + "/" + new File(PATHREAL).getName());
File temp = new File(PATHREAL);
temp.createNewFile();
copyFile(temp, interno);
new UploadFile(interno.getAbsolutePath()).execute();
} catch (IOException e) {
Log.e("Error", e.toString());
e.printStackTrace();
}
//new UploadFile(PATHREAL).execute();
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri selectedImage;
if (requestCode == 1 && resultCode == RESULT_OK && null != data) {
String name = data.getData().getLastPathSegment();
PATHIREAL = data.getData().getPath();
try {
PATHREAL = getFilePath(this, data.getData());
TxVwNombre.setText("name=" + name + " PATH=" + PATHREAL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
Log.e("PATH", PATHREAL);
}
}
public static String getFilePath(Context context, Uri uri) throws URISyntaxException {
String selection = null;
String[] selectionArgs = null;
// Uri is different in versions after KITKAT (Android 4.4), we need to
if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
uri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("image".equals(type)) {
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
selection = "_id=?";
selectionArgs = new String[]{
split[1]
};
}
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {
MediaStore.Images.Media.DATA
};
Cursor cursor = null;
try {
cursor = context.getContentResolver()
.query(uri, projection, selection, selectionArgs, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/***crear Directorio en la memoria interna */
public File crearCarpetaAlmInterno() {
String nombreDirectorio = "TCompra";
//Crear directorio en la memoria interna.
File directorioInterno = new File(getFilesDir(), nombreDirectorio);
//Muestro un mensaje en el logcat si no se creo la carpeta por algun motivo
if (!directorioInterno.mkdirs()) {
Log.e("CrearCarpteaAlIn", "Error: No se creo el directorio privado");
}
if (directorioInterno.exists() && directorioInterno.isDirectory()) {//SI EXISTE
Toast.makeText(this, "DIRECTORIO EXISTE", Toast.LENGTH_SHORT).show();
} else {//NO EXISTE
Toast.makeText(this, "DIRECTORIO NO EXISTE", Toast.LENGTH_SHORT).show();
}
return directorioInterno;
}
public static void copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.exists()) {
destFile.createNewFile();
}
FileChannel origen = null;
FileChannel destino = null;
try {
origen = new FileInputStream(sourceFile).getChannel();
destino = new FileOutputStream(destFile).getChannel();
long count = 0;
long size = origen.size();
while ((count += destino.transferFrom(origen, count, size - count)) < size) ;
} finally {
if (origen != null) {
origen.close();
}
if (destino != null) {
//destFile.mkdirs();
destino.close();
}
}
}
private class UploadFile extends AsyncTask<String, String, String> {
String PATREAL = null;
public UploadFile(String PATREAL) {
this.PATREAL = PATREAL;
}
@Override
protected String doInBackground(String... strings) {
File f = new File(this.PATREAL);
//String content_type = getMimeType(this.PATREAL);
String content_type = getMimeType2(PATREAL);
Log.i("content_type ", content_type);
String file_path = PATREAL;
Log.d("File ", file_path);
OkHttpClient client = new OkHttpClient();
RequestBody file_body = RequestBody.create(MediaType.parse(content_type), f);
RequestBody request_body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("type", content_type)
.addFormDataPart("uploaded_file", file_path.substring(file_path.lastIndexOf("/") + 1), file_body)
.build();
Request request = new Request.Builder()
.url("http://www.nube.com/Surbir.php")
.post(request_body)
.build();
try {
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
//Toast.makeText(SubirImagenes.this, "Archivo no subido", Toast.LENGTH_SHORT).show();
throw new IOException("Error : " + response);
}
} catch (IOException e) {
e.printStackTrace();
Log.e("Error", e.toString());
}
return null;
}
}
private String getMimeType(String path) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(path);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
}
return type;
}
public static String getMimeType2(String url) {
String extension = url.substring(url.lastIndexOf("."));
String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl(extension);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(mimeTypeMap);
return mimeType;
}
}
Thank you for your time.