I want to show whatsapp statuses in my app.
Till now I have done following:
public final String getStatusPath(boolean z) {
if (Build.VERSION.SDK_INT < 30) {
if (z) {
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp Business/Media/.Statuses";
}
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";
} else if (z) {
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp.w4b/WhatsApp Business/Media/.Statuses";
} else {
return Environment.getExternalStorageDirectory().getAbsolutePath()+ "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";
}
}
private ArrayList<WhatStatusData> getStatusList() {
ArrayList<WhatStatusData> arrayList = new ArrayList<>();
File[] listFiles = new File(FileConstants.INSTANCE.getStatusPath(isBusiness)).listFiles();
int i = 0;
if (listFiles != null) {
if (listFiles.length == 0) {
Arrays.sort(listFiles);
}
int length = listFiles.length;
while (i < length) {
File file = listFiles[i];
i++;
String absolutePath = file.getAbsolutePath();
Uri fromFile = Uri.fromFile(file);
String name = file.getName();
if (!name.equals(".nomedia")) {
arrayList.add(new WhatStatusData(absolutePath, fromFile, name));
}
}
}
return arrayList;
}
In manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
But I am not getting data in android 11.In other versions code is working properly.
Got the solution
There are two possibility for getting hidden files access in android 11
give MANAGE_EXTERNAL_STORAGE permission as said by #Subarata Talukder
give particular folder access permission using storage manager as explained below (without using MANAGE_EXTERNAL_STORAGE permission)
Here I am showing how to access whatsapp statuses programmatically
//give permissions in manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
//give run time permissions
static final int REQUEST_PERMISSION_KEY = 1;
int REQUEST_ACTION_OPEN_DOCUMENT_TREE = 101;
SharedPreferences sharedPreferences;
check if run time permissions are given or not on button click
if(sharedPreferences.getString("WATREE","").equals("")){
if(checkAndRequestPermissions()){
if (SDK_INT >= Build.VERSION_CODES.Q) {
askPermission();
}else {
callActivity();
}
}
}else{
callActivity();
}
private boolean checkAndRequestPermissions() {
int writePerm = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPerm = ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.READ_EXTERNAL_STORAGE);
List<String> listPermissionsNeeded = new ArrayList<>();
if (writePerm != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if(readPerm != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(GBV_StartActivity.this,
listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),
REQUEST_PERMISSION_KEY);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_KEY) {
try {
Map<String, Integer> permsLogin = new HashMap<>();
// Initialize the map with both permissions
permsLogin.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
permsLogin.put(Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
// Fill with actual results from user
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
permsLogin.put(permissions[i], grantResults[i]);
// Check for both permissions
if (permsLogin.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& permsLogin.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
if (SDK_INT >= Build.VERSION_CODES.Q) {
askPermission();
}else {
callActivity();
}
// process the normal flow
//else any one or both the permissions are not granted
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
showDialogOK((dialog, which) -> {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
break;
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(getApplicationContext(), "Go to settings and enable permissions.", Toast.LENGTH_LONG)
.show();
finish();
//proceed with logic by disabling the related features or quit the app.
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void showDialogOK(DialogInterface.OnClickListener okListener) {
android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(GBV_StartActivity.this);
alertDialogBuilder.setMessage("You need to allow access to the permissions.")
.setCancelable(false)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener);
android.app.AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
public void callActivity(){
startActivity(new Intent(GBV_StartActivity.this, MainActivity.class));
}
private String getWhatsupFolder() {
String oldPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";
String oldBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp Business/Media/.Statuses";
String newPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";
String newBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp.w4b/WhatsApp Business/Media/.Statuses";
String finalPath;
if(new File(newBusinessPath).exists()){
finalPath = "Android%2Fmedia%2Fcom.whatsapp.w4b%2FWhatsApp Business%2FMedia%2F.Statuses";
}else if(new File(newPath).exists()){
finalPath = "Android%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses";
}else if(new File(oldBusinessPath).exists()){
finalPath = "WhatsApp Business%2FMedia%2F.Statuses";
}else {
finalPath = "WhatsApp%2FMedia%2F.Statuses";
}
return finalPath;
}
#RequiresApi(Build.VERSION_CODES.Q)
private void askPermission() {
StorageManager storageManager = (StorageManager) getSystemService(STORAGE_SERVICE);
Intent intent = storageManager.getPrimaryStorageVolume().createOpenDocumentTreeIntent();
String targetDirectory = getWhatsupFolder(); // add your directory to be selected by the user
Uri uri = intent.getParcelableExtra("android.provider.extra.INITIAL_URI");
String scheme = uri.toString();
scheme = scheme.replace("/root/", "/document/");
scheme += "%3A"+targetDirectory;
uri = Uri.parse(scheme);
Log.w("TAG", "askPermission: uri::"+uri );
intent.putExtra("android.provider.extra.INITIAL_URI", uri);
startActivityForResult(intent, REQUEST_ACTION_OPEN_DOCUMENT_TREE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == this.REQUEST_ACTION_OPEN_DOCUMENT_TREE && resultCode == -1) {
Uri data = intent.getData();
try {
getContentResolver().takePersistableUriPermission(data, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (Exception e) {
e.printStackTrace();
}
SharedPreferences.Editor editor2 = sharedPreferences.edit();
editor2.putString("WATREE", data.toString());
editor2.apply();
callActivity();
}
}
now after giving all permissions try to get images or videos from storage like below:
if (SDK_INT >= Build.VERSION_CODES.Q) {
DocumentFile[] allFiles = getFromSdcard();
if (allFiles != null) {
for(int i = 0 ; i <allFiles.length ; i++){
if (!allFiles[i].getUri().toString().contains(".nomedia")) {
Log.e("path:",allFiles[i].getUri().toString());
//add data in your arraylist
}
}
}
}else {
String oldPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";
String oldBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp Business/Media/.Statuses";
String newPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";
String newBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp.w4b/WhatsApp Business/Media/.Statuses";
String finalPath;
if (!new File(oldPath).exists()) {
if (!new File(oldBusinessPath).exists()) {
if (!new File(newPath).exists()) {
if (!new File(newBusinessPath).exists()) {
finalPath = oldPath;
} else {
finalPath = newBusinessPath;
}
} else {
finalPath = newPath;
}
} else {
finalPath = oldBusinessPath;
}
} else {
finalPath = oldPath;
}
File file2 = new File(finalPath);
if (file2.exists()) {
File[] listFiles = file2.listFiles();
if (listFiles != null) {
for (int i = 0; i < listFiles.length; i++) {
Log.e("path:",listFiles[i].getPath()+"");
//add data in your arraylist
}
}
}
}
public DocumentFile[] getFromSdcard() {
DocumentFile fromTreeUri = DocumentFile.fromTreeUri(getContext(), Uri.parse(sharedPreferences.getString("WATREE","")));
if (fromTreeUri == null || !fromTreeUri.exists() || !fromTreeUri.isDirectory() || !fromTreeUri.canRead() || !fromTreeUri.canWrite()) {
return null;
}
return fromTreeUri.listFiles();
}
Related
Hi in the below code When I am trying click it is showing you don't have read and access permission.But in the manifest file I has given those two permission.Both read and write permission are not triggering with my below code.Both the permission I am calling haspermission evry time failing
Can any one help me where I did the mistake.
java:
private static final String[] PERMISSIONS = {android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE};
private static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
String modality_name = opportunity.getModality();
if (modality_name.equals("LCS")||modality_name.equals("Ultrasound")||modality_name.equals("DI")) {
// Toast.makeText(mContext, modality_name, Toast.LENGTH_LONG).show();
holder.pdf.setVisibility(View.GONE);
}else {
holder.pdf.setVisibility(View.VISIBLE);
holder.pdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!hasPermissions(mContext, PERMISSIONS)) {
Log.v(TAG, "download() Method DON'T HAVE PERMISSIONS ");
Toast t = Toast.makeText(mContext, "You don't have read access !", Toast.LENGTH_LONG);
t.show();
} else {
File d = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); // -> filename = maven.pdf
String url_path = opportunity.getPdf_link();
///Log.d("url_path", url_path);
String file_name = url_path.substring(url_path.lastIndexOf('/') + 1);
//Log.d("file_name", file_name);
File pdfFile = new File(d, file_name);
Log.v(TAG, "view() Method pdfFile " + pdfFile.getAbsolutePath());
if(pdfFile!=null) {
Uri path = GenericFileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", pdfFile);
Log.v(TAG, "view() Method path " + url_path);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
mContext.startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(mContext, "No Application available to view PDF", Toast.LENGTH_SHORT).show();
}
// }
}
Log.v(TAG, "view() Method completed ");
// download(v);
//request(v);
}
download(v);
// request(v);
}
public void request(View v) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, 112);
}
public void download(View v) {
Log.v(TAG, "download() Method invoked ");
if (!hasPermissions(mContext, PERMISSIONS)) {
Log.v(TAG, "download() Method DON'T HAVE PERMISSIONS ");
Toast t = Toast.makeText(mContext, "You don't have write access !", Toast.LENGTH_LONG);
t.show();
} else {
Log.v(TAG, "download() Method HAVE PERMISSIONS ");
String url_path = opportunity.getPdf_link();
Log.d("url_path", url_path);
String file_name = url_path.substring(url_path.lastIndexOf('/') + 1);
Log.d("file_name", file_name);
new DownloadFile().execute(url_path, file_name);
}
Log.v(TAG, "download() Method completed ");
}
});
}
}
// public DragListener getDragInstance() {
// if (mlistener != null) {
// return new DragListener(mlistener);
// } else {
// Log.e("Route Adapter: ", "Initialize listener first!");
// return null;
// }
// }
private class DownloadFile extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... strings) {
Log.v(TAG, "doInBackground() Method invoked ");
String fileUrl = strings[0];
Log.d("fileurl",fileUrl);
String fileName = strings[1]; // -> maven.pdf
Log.d("fileName",fileName);
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File pdfFile = new File(folder, fileName);
Log.v(TAG, "doInBackground() pdfFile invoked " + pdfFile.getAbsolutePath());
Log.v(TAG, "doInBackground() pdfFile invoked " + pdfFile.getAbsoluteFile());
try {
pdfFile.createNewFile();
Log.v(TAG, "doInBackground() file created" + pdfFile);
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "doInBackground() error" + e.getMessage());
Log.e(TAG, "doInBackground() error" + e.getStackTrace());
}
FileDownloader.downloadFile(fileUrl, pdfFile);
Log.v(TAG, "doInBackground() file download completed");
return null;
}
}
First of all, WRITE permission grants you both READ/WRITE access, so you don't need to send a request for both
Check if permission is granted by this method, no need for all of those API checks:
private boolean isPermissionGranted(String permission) {
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
}
If permission is not granted first before everything else just request the permission:
requestPermissions(new String[Manifest.permission.WRITE_EXTERNAL_STORAGE], 123);
Check if permission is granted and then continue your work:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == 123 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Do your work
}
else {
//Permission is not granted do what you want
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
In your code:
inside holder.pdf.setOnClickListener()'s onCLick()
if (!isPermissionGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
requestPermissions(new String[Manifest.permission.WRITE_EXTERNAL_STORAGE], 123);
} else {
//Do your job
}
I am trying to save some arrays in an application to use them in other platform (C++) are serialized. I use a pick method to let the user choose the file name and directory, but first I am trying to define the root directory like this, since the handling of the Create Document needs Android 10 to start in the proper defined directory:
'''
String a = getExternalStorageDirectory().getPath();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
String public_dir = "sistemaderiegoandroid_arduino" + MyDocuments.fileSeparator;
file = new File(a, public_dir);
file.setWritable(true);
if (!file.mkdirs()) {
file.mkdir();
}
;
DocumentsContract.createDocument(context.getContentResolver(), DocumentsContract.buildRootUri(MyDocuments.AUTORITY,MyDocuments.ROOT), DocumentsContract.Document.MIME_TYPE_DIR,MyDocuments.INITIALURI);
fileUri = DocumentsContract.buildDocumentUri(MyDocuments.AUTORITY,MyDocuments.INITIALURI);
} catch (Exception e) {
errorMsg(MyDocuments.falloCrear + e.toString());
}
}else{
file = new File(a);
file.setWritable(true);
};
String StfileR = "arduino_data_resumen.bin";
String StfileT = "arduino_data_tiempo.bin";
String StfileH = "arduino_data_humedad.bin";
String StfileL = "arduino_data_luz.bin";
try{
createFile(fileUri, StfileT, CREATE_FILE_T);
createFile(fileUri, StfileL, CREATE_FILE_L);
createFile(fileUri, StfileH, CREATE_FILE_H);
createFile(fileUri, StfileR, CREATE_FILE_R);
} catch (Exception e) {
errorMsg(MyDocuments.falloCrear + e.toString());
}
try {
allData.saveData(context);
} catch (Exception e) {
errorMsg(MyDocuments.falloGrabar + e.toString());
}
private void createFile(Uri pickerInitialUri, String file_name, int result_option_Flag) {
//DocumentsUI
Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
intent.setType(MyDocuments.MINETYPE);
intent.putExtra(Intent.EXTRA_TITLE, file_name);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, RESULT_OK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
intent.putExtra(Intent.EXTRA_RETURN_RESULT, RESULT_OK);
}
// intent.putExtra(DocumentsContract.EXTRA_EXCLUDE_SELF,true);
startActivityForResult(intent, result_option_Flag);
};
'''
The permission in the manifest are:
'''
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission-sdk-23 android:name="android.permission.READ_EXTERNAL_STORAGE"/>
'''
and the provider is:
'''
<provider
android:name="com.sistemaderiegoandroid_arduino.MyDocuments"
android:authorities="com.sistemaderiegoandroid_arduino.documents"
android:grantUriPermissions="true"
android:exported="true"
android:permission="android.permission.MANAGE_DOCUMENTS">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
</intent-filter>
</provider>
'''
To save the data in the file I use a FileDescriptor with the method getContentResolver().openFileDescriptor MODE_APPEND, this gives a ParcelFileDescriptor and with the method getFileDescriptor() I make the FileOuputStream like this:
'''
FileDescriptor fdR = null;
parcelFileDescriptorL = getContentResolver().openFileDescriptor(fileNameL, "MODE_APPEND", null);
fdL = parcelFileDescriptorL.getFileDescriptor();
arduinoDataL = new FileOutputStream(fdL);
serializatorDataL = new ObjectOutputStream(arduinoDataL);
for (int i = 0; i < allData.arrayDatosLuz.length; i++) {
serializatorDataL.writeObject(allData.arrayDatosLuz[i]);
serializatorDataL.flush();
fdL.sync();
}
;
serializatorDataL.close();
'''
The complete package is here:
https://github.com/DarioLobos/sistemariego
I added this grant permission request but anyway the phone don't ask for the permissions. I reset, in the applications manager of the phone the caches of restriction and permits, anyway don't ask for grant them when I install the program. Other application don't have problems while are installing and the phone request grant permissions.
'''
int granted = PackageManager.PERMISSION_GRANTED;
grantRequested =
ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) != granted;
if ((grantRequested)) {
if ((ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) != PackageManager.PERMISSION_GRANTED)) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle(grantDialog).setMessage(R.string.requestWriteSetting);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (callBackFlag == 0) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
startActivity(intent);
callBackFlag++;
int granted = PackageManager.PERMISSION_GRANTED;
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == granted) {
grantRequested =
ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) != granted;
if (grantRequested) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN}, RESULT_OK);
} else {
if (grantRequested) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle(exit).setMessage(R.string.permitNotGranted);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.this.finish();
System.exit(0);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
}
} else {
dialog.dismiss();
alertDialogBuilder.setTitle(exit).setMessage(R.string.permitNotGranted);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.this.finish();
System.exit(0);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
});
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
boolean grantChecker = false;
if (grantResults.length > 0) {
grantChecker = true;
for (int i = 0; grantResults.length > i; i++) {
boolean a = grantResults[i] == PackageManager.PERMISSION_GRANTED;
grantChecker = grantChecker & a;
}
}
if (requestCode != RESULT_OK) {
int granted = PackageManager.PERMISSION_GRANTED;
if (!grantChecker & (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == granted)) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
ResumenFragment.errorMsg(permitHandling);
ActivityCompat.requestPermissions(this,
new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN}, RESULT_OK);
} else {
grantRequested =
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) != granted |
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) != granted;
if (grantRequested) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle(exit).setMessage(R.string.permitNotGranted);
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.this.finish();
System.exit(0);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
;
}
}
}
'''
The Intents for result for OPENDOCUMENT and CREATEDOCUMENT give the information about the picked file in the overrided method onActivityResult. There using intent.getData() if obtained the URI for the file, then using contentResolver.openFileDescriptor can be open and with the method getFileDescriptor() do a FileOutputStream or FileInputStream sync. Like This:
'''
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (resultCode == Activity.RESULT_OK) {
// The result data contains a URI for the document or directory that
// the user selected.
if (resultData != null) {
Uri uriData = resultData.getData();
// String fileId =DocumentsContract.getDocumentId(uriData);
if (requestCode == CREATE_FILE_L) {
Data.fileNameL = uriData;
}
if (requestCode == CREATE_FILE_H) {
Data.fileNameH = uriData;
}
if (requestCode == CREATE_FILE_R) {
Data.fileNameR = uriData;
}
if (requestCode == CREATE_FILE_T) {
Data.fileNameR = uriData;
}
if (requestCode == PICK_FILE_T) {
Data.fileNameT = uriData;
}
if (requestCode == PICK_FILE_L) {
Data.fileNameL = uriData;
}
if (requestCode == PICK_FILE_H) {
Data.fileNameH = uriData;
}
if (requestCode == PICK_FILE_R) {
Data.fileNameR = uriData;
'''
I NEED TO KNOW THE PROPER WAY TO DEFINE THE ROOT DIRECTORY AND THE DIRECTORY DOWNLOAD AND THE THE PICK UP NAME AND DIRECTORY COLLECTED FROM THE INTENT RESULT. I did plenty trials without solution any help is welcome.
I have a profile picture concept in my app. User has options to upload an image from camera or gallery in the app but the problem is the image is being uploaded to some devices not all. Mainly the problem occurs with Android version 8 & 9. I tried almost everything but failed to achieve. Please help.
Code:
dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.dialog_image_upload);
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
TextView txtTakePhoto = (TextView) dialog.findViewById(R.id.txtTakePhoto);
TextView txtPictureFromGallery = (TextView) dialog.findViewById(R.id.txtPictureFromGallery);
ImageView imgClose = (ImageView) dialog.findViewById(R.id.imgClose);
imgClose.setOnClickListener(this);
txtTakePhoto.setOnClickListener(this);
txtPictureFromGallery.setOnClickListener(this)
Code for take photo from camera:
case R.id.txtTakePhoto:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
{
cameraIntent();
}
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
Toast.makeText(getActivity(), "App requires Phone permission.\nPlease allow that in the device settings.", Toast.LENGTH_LONG).show();
}
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, PHONE_PERMISSION_CODE);
}
} else {
cameraIntent();
}
break;
Code for take photo from gallery:
case R.id.txtPictureFromGallery:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
{
imageBrowse();
}
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
Toast.makeText(getActivity(), "App requires Phone permission.\nPlease allow that in the device settings.", Toast.LENGTH_LONG).show();
}
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PHONE_PERMISSION_CODE);
}
} else {
imageBrowse();
}
break;
Pending code for image uploading :
private void cameraIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}
private void imageBrowse() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, PICK_IMAGE_REQUEST);
}
//handling the image chooser activity result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == PICK_IMAGE_REQUEST) {
onSelectFromGalleryResult(data);
} else if (requestCode == REQUEST_CAMERA) {
onCaptureImageResult(data);
}
}
//
if (requestCode == 2 && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri DbsUri = data.getData();
fileDbs = FilePath.getPath(getActivity(), DbsUri);
File f1 = new File(fileDbs);
edtCertificatesValue.setText(f1.getName());
Log.e("tag", "filedbs" + fileDbs);
} else if (requestCode == 3 && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri picUri = data.getData();
filePath = FilePath.getPath(getActivity(), picUri);
File f2 = new File(filePath);
edtIdentityDocumentValue.setText(f2.getName());
Log.e("tag", "filePath" + filePath + " " + f2.getName());
} else if (requestCode == 4 && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri picUri = data.getData();
fileAddress = FilePath.getPath(getActivity(), picUri);
File f3 = new File(fileAddress);
edtProofOfAddressValue.setText(f3.getName());
Log.e("tag", "fileAddress" + fileAddress);
} else if (requestCode == 5 && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri CvUri = data.getData();
fileCvPath = FilePath.getPath(getActivity(), CvUri);
File f4 = new File(fileCvPath);
edtCurriculumVitaeValue.setText(f4.getName());
Log.e("tag", "fileCvPath" + fileCvPath);
//
}
//
// } else
}
#SuppressWarnings("deprecation")
private void onSelectFromGalleryResult(Intent data) {
bm = null;
File imageFile = getTempFile(getActivity());
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
boolean isCamera = (data == null ||
data.getData() == null ||
data.getData().toString().contains(imageFile.toString()));
if (isCamera) { /* CAMERA */
selectedImageUri = Uri.fromFile(imageFile);
} else { /* ALBUM */
selectedImageUri = data.getData();
}
bm = getImageResized(getActivity(), selectedImageUri);
int rotation = getRotation(getActivity(), selectedImageUri, isCamera);
bm = rotate(bm, rotation);
ByteArrayOutputStream bytes1 = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 99, bytes1);
byte[] byteImage = bytes1.toByteArray();
encodeImage = Base64.encodeToString(byteImage, Base64.DEFAULT);
imgProfile.setImageBitmap(bm);
Uri picUri = data.getData();
Log.e("TAG", "onSelectFromGalleryResult: " + bm);
fileImagePath = getPath(picUri);
if (fileImagePath != null) {
try {
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), R.string.some_error_occured, Toast.LENGTH_LONG).show();
}
dialog.dismiss();
}
private String getPath(Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
CursorLoader loader = new CursorLoader(getActivity(), contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String result = cursor.getString(column_index);
cursor.close();
return result;
}
// new code
private static File getTempFile(Context context) {
File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME);
imageFile.getParentFile().mkdirs();
return imageFile;
}
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes1 = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 99, bytes1);
byte[] byteImage = bytes1.toByteArray();
encodeImage = Base64.encodeToString(byteImage, Base64.DEFAULT);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
Log.d("TAG", "onActivityResult: " + Uri.fromFile(destination));
try {
rotateImageIfRequired(thumbnail, getActivity(), Uri.fromFile(destination));
} catch (Exception e) {
e.printStackTrace();
}
Log.d("TAG", "thumbnail: " + thumbnail);
imgProfile.setImageBitmap(thumbnail);
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes1.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fileImagePath = destination.toString();
if (fileImagePath != null) {
try {
// execMultipartPost();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), getResources().getString(R.string.some_error_occured), Toast.LENGTH_LONG).show();
}
dialog.dismiss();
}
//This method will be called when the user will tap on allow or deny
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(getActivity(), "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(getActivity(), "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
API hit Code:
private void execMultipartPost() throws Exception {
RequestBody requestBody;
pBar.setVisibility(View.VISIBLE);
final HashMap<String, String> loggedDetail = sessionManager.getLoggedDetail();
HashMap<String, String> params = new HashMap<String, String>();
String api_token = loggedDetail.get("api_token");
if (filePath != null) {
File file = new File(filePath);
String contentType = file.toURL().openConnection().getContentType();
fileBody = RequestBody.create(MediaType.parse(contentType), file);
filename = "file_" + System.currentTimeMillis() / 1000L;
Log.e("TAG", "filename: " + filename);
requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image_file", filename + ".jpg", fileBody)
.addFormDataPart("name", edtName.getText().toString())
.addFormDataPart("user_id", loggedDetail.get("id"))
.addFormDataPart("email", edtEmailValue.getText().toString())
.addFormDataPart("postal_code", edtPostCodeValue.getText().toString())
.addFormDataPart("phone", edtPhoneNumber.getText().toString())
.addFormDataPart("type", loggedDetail.get("type"))
.addFormDataPart("address", edtAddressValue.getText().toString())
.addFormDataPart("gender", edtGenderValue.getText().toString())
.addFormDataPart("skype_id", edtSkypeNameIdValue.getText().toString())
.build();
} else {
requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image_file", "")
.addFormDataPart("name", edtName.getText().toString())
.addFormDataPart("user_id", loggedDetail.get("id"))
.addFormDataPart("email", edtEmailValue.getText().toString())
.addFormDataPart("postal_code", edtPostCodeValue.getText().toString())
.addFormDataPart("phone", edtPhoneNumber.getText().toString())
.addFormDataPart("type", loggedDetail.get("type"))
.addFormDataPart("address", edtAddressValue.getText().toString())
.addFormDataPart("gender", edtGenderValue.getText().toString())
.addFormDataPart("skype_id", edtSkypeNameIdValue.getText().toString())
.build();
}
okhttp3.Request request = new okhttp3.Request.Builder()
.url(Constants.EDIT_PROFILE_DATA)
.post(requestBody)
.addHeader("Authorization", "Bearer " + loggedDetail.get("api_token"))
.build();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(150, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, final IOException e) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
pBar.setVisibility(View.GONE);
Toast.makeText(getActivity(), R.string.some_error_occured, Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
});
}
#Override
public void onResponse(Call call, final okhttp3.Response response) throws IOException {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Yes, you need to configure the FileProvider. In your app's manifest, add a provider to your application:
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
...
</application>
Make sure that the authorities string matches the second argument to getUriForFile(Context, String, File). In the meta-data section of the provider definition, you can see that the provider expects eligible paths to be configured in a dedicated resource file, res/xml/file_paths.xml. Here is the content required for this particular example:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>
Read the android documentation https://developer.android.com/training/camera/photobasics
I couldn't get popup for my android webview app, I have tried everything possible could someone help me please, here is my mainActivity code.
What I am trying to do is to load my webview which I get successfully but there is a personal page where if a user click on profile picture it should prompt either to open camera or load image from galler and again there is an upload option if pressed same thing should happen either to upload photos or open camera, Its working fine if I do it from my browser but not from my webview android app
public class MainActivity extends AppCompatActivity {
private static final int MY_BLINK_ID_REQUEST_CODE = 0x101;
public static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 101;
private static final int REQUEST_WEBFORM = 300;
public static final int REQUEST_SELECT_FILE = 100;
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> uploadMessageLP;
private Uri directUploadImageUri;
private static final String TAG = MainActivity.class.getSimpleName();
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupToolbar();
loadHtml();
}
public void cancelFileUpload() {
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
}
if (uploadMessageLP != null) {
uploadMessageLP.onReceiveValue(null);
uploadMessageLP = null;
}
this.directUploadImageUri = null;
}
public void setUploadMessageLP(ValueCallback<Uri[]> uploadMessageLP) {
this.uploadMessageLP = uploadMessageLP;
}
/**
* setup toolbar
*/
private void setupToolbar() {
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//change title color
toolbar.setTitleTextColor(ContextCompat.getColor(this, R.color.white));
//set title
getSupportActionBar().setTitle(getString(R.string.app_name));
}
private void loadHtml() {
mWebView = (WebView) findViewById(R.id.wv);
mWebView.setWebViewClient(new WebViewClient());
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);
settings.setAllowContentAccess(true);
settings.setAllowFileAccess(true);
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
// Render the HTML file on WebView
mWebView.loadUrl("http://new.techyardnepal.com");
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_favorite) {
startOCRScan();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* start ocr on scan id click
*/
private void startOCRScan() {
// Intent for MyScanActivity
Intent intent = new Intent(this, MRPScanActivity.class);
startActivityForResult(intent, MY_BLINK_ID_REQUEST_CODE);
}
/**
* This method is called whenever control is returned from activity started with
* startActivityForResult.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// onActivityResult is called whenever we are returned from activity started
// with startActivityForResult. We need to check request code to determine
// that we have really returned from BlinkID activity.
if (requestCode == MY_BLINK_ID_REQUEST_CODE) {
if (resultCode == MRPScanActivity.RESULT_OK && data != null) {
// depending on settings, we may have multiple scan results.
// we first need to obtain recognition results
RecognitionResults results = data.getParcelableExtra(ScanActivity.EXTRAS_RECOGNITION_RESULTS);
BaseRecognitionResult[] resArray = null;
if (results != null) {
// get array of recognition results
resArray = results.getRecognitionResults();
}
if (resArray != null) {
Log.i(TAG, "Data count: " + resArray.length);
int i = 1;
for (BaseRecognitionResult res : resArray) {
Log.i(TAG, "Data #" + Integer.valueOf(i++).toString());
// Each element in resultArray inherits BaseRecognitionResult class and
// represents the scan result of one of activated recognizers that have
// been set up.
res.log();
}
} else {
Log.e(TAG, "Unable to retrieve recognition data!");
}
data.setComponent(new ComponentName(this, ResultActivity.class));
startActivity(data);
}
}
if (data != null && data.getBooleanExtra("exit", false))
finish();
if (requestCode == REQUEST_SELECT_FILE) {
if (resultCode != RESULT_OK) {
cancelFileUpload();
return;
}
// from documents (and video camera)
if (data != null && data.getData() != null) {
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(data.getData());
mUploadMessage = null;
}
return;
}
// we may get clip data for multi-select documents
if (data != null && data.getClipData() != null) {
ClipData clipData = data.getClipData();
ArrayList<Uri> files = new ArrayList<>(clipData.getItemCount());
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
if (item.getUri() != null) {
files.add(item.getUri());
}
}
if (mUploadMessage != null) {
// shouldn never happen, but just in case, send the first item
if (files.size() > 0) {
mUploadMessage.onReceiveValue(files.get(0));
} else {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = null;
}
if (uploadMessageLP != null) {
uploadMessageLP.onReceiveValue(files.toArray(new Uri[files.size()]));
uploadMessageLP = null;
}
return;
}
// from camera
if (this.directUploadImageUri != null) {
// check if we have external storage permissions
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSION_READ_EXTERNAL_STORAGE);
// wait for the onRequestPermissionsResult callback
return;
}
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(this.directUploadImageUri);
mUploadMessage = null;
}
if (uploadMessageLP != null) {
uploadMessageLP.onReceiveValue(new Uri[]{this.directUploadImageUri});
uploadMessageLP = null;
}
this.directUploadImageUri = null;
return;
}
// Should not reach here.
cancelFileUpload();
}
}
}
Try this code:
public class MainActivity extends Activity {
private RelativeLayout mLayout;
private ProgressBar progressBar;
private WebView webView;
String loadUrl;
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private WebSettings webSettings;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
ValueCallback<Uri[]> chooserPathUri;
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
WebView chooserWV;
WebChromeClient.FileChooserParams chooserParams;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadUrl = "https:google.com";
mLayout = (RelativeLayout) findViewById(R.id.activity_main);
progressBar = (ProgressBar)findViewById(R.id.indicator);
webView = (WebView) findViewById(R.id.webView);
webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setDomStorageEnabled(true);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAllowFileAccess(true);
if (Build.VERSION.SDK_INT >= 19) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
else if(Build.VERSION.SDK_INT >=11 && Build.VERSION.SDK_INT < 19) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.setWebChromeClient(new ChromeClient());
webView.loadUrl(loadUrl); //change with your website
this.webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.INVISIBLE);
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
}
#SuppressWarnings("deprecation")
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return handleUrl(url);
}
#TargetApi(Build.VERSION_CODES.N)
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
final Uri uri = request.getUrl();
return handleUrl(request.getUrl().toString());
}
});
}
public boolean handleUrl(String url){
if (url.startsWith("geo:") || url.startsWith("mailto:") || url.startsWith("tel:") || url.startsWith("sms:")) {
Intent searchAddress = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(searchAddress);
}else
webView.loadUrl(url);
return true;
}
private boolean checkAndRequestPermissions() {
int permissionCamera = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
int permissionStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (permissionCamera != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CAMERA);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
Log.e(TAG, "Returned falseeeee-------");
return false;
}
Log.d(TAG, "Permission returned trueeeee-------");
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
Log.d(TAG, "Permission callback called-------");
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
// Initialize the map with both permissions
perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
// Fill with actual results from user
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for both permissions
if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "camera & Storage permission granted");
Toast.makeText(this, "Permissions granted! Try now.", Toast.LENGTH_SHORT).show();
//chromClt.openChooser(chooserWV, chooserPathUri, chooserParams);
// process the normal flow
//else any one or both the permissions are not granted
} else {
Log.d(TAG, "Some permissions are not granted ask again ");
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// shouldShowRequestPermissionRationale will return true
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showDialogOK("Camera and Storage Permission required for this app",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG).show();
// //proceed with logic by disabling the related features or quit the app.
}
}
}
break;
}
}
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}else {
if (Build.VERSION.SDK_INT >= 16) {
if (data.getClipData() != null) {
final int numSelectedFiles = data.getClipData().getItemCount();
results = new Uri[numSelectedFiles];
for (int i = 0; i < numSelectedFiles; i++) {
results[i] = data.getClipData().getItemAt(i).getUri();
}
}
}
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
return;
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
public class ChromeClient extends WebChromeClient {
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
// callback.invoke(String origin, boolean allow, boolean remember);
Log.e(TAG, "onGeolocationPermissionsShowPrompt: " );
callback.invoke(origin, true, false);
}
// For Android 5.0
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
chooserWV = view;
chooserPathUri = filePath;
chooserParams = fileChooserParams;
if(checkAndRequestPermissions()){
openChooser(chooserWV, chooserPathUri, chooserParams);
return true;
}else {
return false;
}
}
public void openChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams){
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent;
takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e(TAG, "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
if (Build.VERSION.SDK_INT >= 18) {
contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
contentSelectionIntent.setType("*/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
}
// openFileChooser for Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
// Create AndroidExampleFolder at sdcard
// Create AndroidExampleFolder at sdcard
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "AndroidExampleFolder");
if (!imageStorageDir.exists()) {
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
// Camera capture image intent
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
// Create file chooser intent
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
// Set camera intent to file chooser
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
// On select image call onActivityResult method of activity
chooserIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
// openFileChooser for Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
//openFileChooser for other Android versions
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType,
String capture) {
openFileChooser(uploadMsg, acceptType);
}
}
#SuppressLint("NewApi")
#Override
protected void onResume() {
super.onResume();
webView.onResume();
// ...
}
#SuppressLint("NewApi")
#Override
protected void onPause() {
webView.onPause();
// ...
super.onPause();
}
int mExit = 0;
#Override
public void onBackPressed() {
if(webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
Don't forget to add permissions in Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
i try to copy a sqlite database from file in my external storage this worked fine in android version ( 4 and 5 ) but doesn't work in android 6 (marshmallow) why ?? please help , As required, in its manifest, the following permissions are requested :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
here is my code :
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(Main2ActivityAdmin.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(Main2ActivityAdmin.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Main2ActivityAdmin.this,
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE},
1);
} else {
Toast.makeText(Main2ActivityAdmin.this, "permission erreur", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(Main2ActivityAdmin.this, "ok", Toast.LENGTH_LONG).show();
}
private boolean copyDatabase(Context context) {
try {
//InputStream inputStream = context.getAssets().open(DatabaseHelper.DBNAME);
File sdcard = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file = new File(sdcard, "sample.sqlite");
InputStream inputStream = null;
inputStream = new BufferedInputStream(new FileInputStream(file.getAbsolutePath()));
String outFileName = DatabaseHelper.DBLOCATION + DatabaseHelper.DBNAME;
OutputStream outputStream = new FileOutputStream(outFileName);
byte[]buff = new byte[1024];
int length = 0;
while ((length = inputStream.read(buff)) > 0) {
outputStream.write(buff, 0, length);
}
outputStream.flush();
outputStream.close();
Log.w("MainActivity","DB copied");
return true;
}catch (Exception e) {
e.printStackTrace();
return false;
}
Try this to put the permission
Also change WRITE_EXTERNAL_STORAGE to READ_EXTERNAL_STORAGE for Read permission
public class MyActivity extends AppCompatActivity {
private static final int REQUEST_RUNTIME_PERMISSION = 123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (CheckPermission(MyActivity .this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// you have permission go ahead
} else {
// you do not have permission go request runtime permissions
RequestPermission(MyDevIDS.this, Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_RUNTIME_PERMISSION);
}
}
#Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) {
switch (permsRequestCode) {
case REQUEST_RUNTIME_PERMISSION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// you have permission go ahead
} else {
// you do not have permission show toast.
}
return;
}
}
}
public void RequestPermission(MyActivity thisActivity, String Permission, int Code) {
if (ContextCompat.checkSelfPermission(thisActivity,
Permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Permission)) {
} else {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Permission},
Code);
}
}
}
public boolean CheckPermission(MyActivity context, String Permission) {
if (ContextCompat.checkSelfPermission(context,
Permission) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
}