I'm having a problem downloading and installing the app.
On android below 10 this code works.
I am trying to update my application from the server.
Manifest
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
Activity
If there is an update, then a snackbar appears and by clicking update the application should download and install
private void showSnackbar() {
Snackbar snackbar =
Snackbar.make(
findViewById(android.R.id.content),
"update available",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("update", new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onClick(View v) {
try {
if (checkPermission()) {
UpdateApp atualizaApp = new UpdateApp();
atualizaApp.setContext(CommonListObjects.this);
atualizaApp.execute("http://195.200.000.000:0000/app.apk");
} else {
requestPermission();
}
} catch (android.content.ActivityNotFoundException anfe) {
}
}
});
snackbar.show();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0) {
boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean cameraAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (locationAccepted && cameraAccepted) {
UpdateApp updateApp = new UpdateApp();
updateApp.setContext(CommonListObjects.this);
updateApp.execute("http://195.200.000.000:0000/app.apk");
}
}
}
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
this is how it loads
#Override
protected String doInBackground(String... arg0) {
try {
URL url = new URL(arg0[0]);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
int lenghtOfFile = c.getContentLength();
String PATH = Environment.getExternalStorageDirectory() + "/" + "app.apk";
File file = new File(PATH);
boolean isCreate = file.mkdirs();
File outputFile = new File(file, "app.apk");
if (outputFile.exists()) {
boolean isDelete = outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1;
long total = 0;
while ((len1 = is.read(buffer)) != -1) {
total += len1;
fos.write(buffer, 0, len1);
publishProgress((int) ((total * 100) / lenghtOfFile));
}
fos.close();
is.close();
if (mPDialog != null)
mPDialog.dismiss();
installApk();
} catch (Exception e) {
Log.e("UpdateAPP", "Update error! " + e.getMessage());
}
return null;
}
this is how the installation works
void installApk(){
String PATH = Environment.getExternalStorageDirectory() + "/" + "app.apk"+ "/" + "app.apk";
File file = new File(PATH);
if(file.exists()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uriFromFile(getApplicationContext(), new File(PATH)), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
getApplicationContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Error in opening the file!",Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(getApplicationContext(),"installing",Toast.LENGTH_LONG).show();
}
}
Uri uriFromFile(Context context, File file) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
} else {
return Uri.fromFile(file);
}
}
on android below 10 works, but in 10 and 11 does not work. even the file does not load.
Related
Java code:
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_camera:
if (i==21) {
Toast.makeText(FileUploadActivity.this,R.string.max_file_upload,Toast.LENGTH_SHORT).show();
}
else {
++i;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(FileUploadActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS);
} else if (ActivityCompat.checkSelfPermission(FileUploadActivity.this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA}, MY_PERMISSIONS);
} else {
openCamera();
}
} else {
openCamera();
}
}
break;
public void openCamera() {
File photoFile = null;
try {
photoFile = createTempFile("Images", "IMG_", ".jpg"); //error
Log.i(TAG, "openCamera: Camera access"+photoFile);
} catch (IOException e) {
e.printStackTrace();
}
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
if (photoFile != null) {
mCameraPhotoPath = photoFile.getAbsolutePath();
}else {
Toast.makeText(FileUploadActivity.this,"Unable to open",Toast.LENGTH_LONG).show();
}
// takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
// startActivityForResult(takePictureIntent, SELECT_PICTURE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));
} else {
File file = new File(Uri.fromFile(photoFile).getPath());
Uri photoUri = FileProvider.getUriForFile(getApplicationContext(), getApplicationContext().getPackageName() + ".provider", file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
}
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (takePictureIntent.resolveActivity(getApplicationContext().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, SELECT_PICTURE);
}
}
private File createTempFile(String storage,String fileName,String fileType) throws IOException {
File imageFile = null;
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "CTrack" + File.separator + storage);
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
String timeStamp = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date());
String imageFileName = fileName + timeStamp + "_";
imageFile = File.createTempFile(imageFileName, fileType, folder);
}
return imageFile;
}
private String encodeImage(String path) {
File imagefile = new File(path);
FileInputStream fis = null;
String encodeResponse="";
try {
fis = new FileInputStream(imagefile);
Bitmap bm = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
encodeResponse=Base64.encodeToString(b, Base64.DEFAULT);
} catch (FileNotFoundException e) {
e.printStackTrace();
encodeResponse="nofile";
}
catch (OutOfMemoryError e) {
e.printStackTrace();
encodeResponse="memory";
}
return encodeResponse;
}
Permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
error:
2021-05-03 12:52:30.921 9669-9669/com.transasia.ctrack E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.transasia.ctrack, PID: 9669
android.os.FileUriExposedException: file:///storage/emulated/0/CTrack/Images/IMG_2021-05-03T12%3A52%3A30_6074100336714487332.jpg exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:2083)
at android.net.Uri.checkFileUriExposed(Uri.java:2388)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:977)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10759)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10744)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1703)
at android.app.Activity.startActivityForResult(Activity.java:5192)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675)
at android.app.Activity.startActivityForResult(Activity.java:5150)
App is working in android 9 and below 9 but when it comes to android 10 and 11, app is crashing and getting file error. I thought problem with creating temp file because there it gives me an error.
Thank you,........................................................................Thanks...........................................................................................................
Try this
In Manifest file - add provider inside
<application android:requestLegacyExternalStorage="true">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
create provider_path.xml (res -> xml -> provider_path.xml)
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="." />
</paths>
Add Camera permission
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
I am trying to get the file from picking image from photos and get intent data, save the file in internal memory and use the file to load on Image views.
But I am getting the error as follows:
java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.dailyfaithapp.dailyfaith/Files/MI_10052020_1711.png: open failed: ENOENT (No such file or directory)
I checked on the lower version of api i.e. on 24 it worked once or twice but again it failed.
And on api 29 its not working at all. For that I followed this url :
https://medium.com/#sriramaripirala/android-10-open-failed-eacces-permission-denied-da8b630a89df
I checked the code in java and tried the same but still its giving the error.
I am also checking for runtime permissions and have specified permissions in manifest file.
Following is my code:
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name = "android.permission.WAKE_LOCK" />
<uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name = "com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />
Checking runtime permissions :
private boolean checkPermission() {
return ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
;
}
private void requestPermissionAndContinue() {
if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, WRITE_EXTERNAL_STORAGE)
&& ActivityCompat.shouldShowRequestPermissionRationale(this, READ_EXTERNAL_STORAGE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Allow Daily Faith to access photos," +
"media, and files on your device?");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(ThemesActivity.this,
new String[]{WRITE_EXTERNAL_STORAGE
, READ_EXTERNAL_STORAGE}, 200);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
Log.e("", "permission denied, show dialog");
} else {
ActivityCompat.requestPermissions(ThemesActivity.this,
new String[]{WRITE_EXTERNAL_STORAGE,
READ_EXTERNAL_STORAGE}, 200);
}
} else {
selectImageFromGallery();
}
}
Checking if permission is given:
if (!checkPermission()) {
selectImageFromGallery();
} else {
if (checkPermission()) {
requestPermissionAndContinue();
} else {
selectImageFromGallery();
}
}
Opening intent :
public void selectImageFromGallery()
{
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto , 2);
}
Get intent data on result :
#RequiresApi(api = Build.VERSION_CODES.KITKAT) #Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a image.
// The Intent's data Uri identifies which item was selected.
if (data != null) {
customTheme = true;
// This is the key line item, URI specifies the name of the data
mImageUri = data.getData();
// Saves image URI as string to Default Shared Preferences
SharedPreferencesData sharedPreferencesData =
new SharedPreferencesData(this);
sharedPreferencesData.setStr("customThemeSet","true");
try {
Bitmap bitmap =
MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri);
/* Utils.storeImage(bitmap,
ThemesActivity.this);
File file = Utils.getOutputMediaFile(ThemesActivity.this);
*/
try {
final ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(
mImageUri, "r");
final FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
Utils.storeImage(bitmap,
ThemesActivity.this);
File file = Utils.getOutputMediaFile(ThemesActivity.this);
int color = Utils.getDominantColor(bitmap);
Log.d("Bitmap", bitmap.toString());
Boolean isDark = Utils.isColorDark(color);
if(customTheme) {
for (Themes themes : themesArrayList) {
themes.setCustomTheme(file.getPath());
themes.setDark(isDark);
}
if(isDark)
sharedPreferencesData.setStr("ThemeColor","dark");
else
sharedPreferencesData.setStr("ThemeColor","light");
themesAdapter = new ThemesAdapter(themesArrayList, this,customTheme);
recyclerView.setAdapter(themesAdapter);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
Log.e("Failed", "Failed to Parse Image Uri", e);
try {
throw new Exception("failed to parse image uri");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
}
Saving and getting file
public static File getOutputMediaFile(Context context){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ context.getApplicationContext().getPackageName()
+ "/Files");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
mediaStorageDir.mkdirs();
}
else {
return null;
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="MI_"+ timeStamp +".png";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
public static void storeImage(Bitmap image,Context context) {
File pictureFile = getOutputMediaFile(context);
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
Before I was getting EACCESS error when I only used above two funtions to save the file.
Later I tried Parcel file descriptor but not working
Why am I getting this error? Is it only on api level 29 or below too?
What can be the solution for this to run on all devices?
Here is what worked for me Using the downloads folder which all phones old and new have public access to..
try{
File csvfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/brcOrdersaved.csv");
final String filename = csvfile.toString();
if (!csvfile.exists()) {
// displayMsg(context, "No Saved Order: ");
return (false);
}
FileReader fr = new FileReader(filename);
BufferedReader reader = new BufferedReader(fr);
String csvLine = "";
final char Separator = ',';
final char Delimiter = '"';
final char LF = '\n';
final char CR = '\r';
boolean quote_open = false;
if (reader.equals(null)) {
displayMsg(context, "NULL");
return (false);//rww 11/13/2021
}
int i = 0;
while (!myendofcsvfile) {
csvLine = reader.readLine();
if (csvLine == null) {
myendofcsvfile = true;
}
// do stuff here
}
fr.close();
fileexists = true;
} catch (Exception e) {
String msg = "Can not Load Saved Order ";
fileexists = false;
return (fileexists);
}
I add this permissions, and it works.
<uses-permission
enter code hereandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
code below is used for trying out the file provider in preparation for android Nougat:
manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.securefilesharing"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="25" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".HomeSecureFileShareTestActivity"
android:label="#string/title_activity_home_secure_file_share_test" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.securefilesharing.fileprovider"
android:enabled="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_path" />
</provider>
</application>
</manifest>
file provider xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="/"/>
</paths>
constructing URI and passing to camera intent:
private Uri createImageFile() throws Exception {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), System.currentTimeMillis() + ".jpg");
//File file = new File(System.currentTimeMillis() + ".jpg");
Uri photoUri = null;
try{
photoUri = FileProvider.getUriForFile(this, "com.securefilesharing.fileprovider", file);
}
catch(Exception e){
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
}
return photoUri;
}
View.OnClickListener ocl = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
try {
uri = createImageFile();
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (Exception e) {
Log.e(TAG, TAG + ": " + e.toString());
}
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
};
I also did the activity.requestPermissions(forPermissions.toArray(new String[0]), PERMISSION_CODE); for the camera, read and write external file
below is the exception message:
06-22 15:04:13.962: E/HomeSecureFileShareTestActivity(31851): HomeSecureFileShareTestActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.securefilesharing.fileprovider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_path" />
</provider>
change your provider part of manifest...
Refer:: https://developer.android.com/guide/topics/manifest/provider-element.html#enabled
Try this,
private Context mContext=YourActivity.this;
private static final int REQUEST = 112;
View.OnClickListener ocl = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 23) {
String[] PERMISSIONS = {android.Manifest.permission.WRITE_EXTERNAL_STORAGE,android.Manifest.permission.READ_EXTERNAL_STORAGE,android.Manifest.permission.CAMERA};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST );
} else {
openCamera()
}
} else {
openCamera()'
}
}
};
get Permissions Result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera();
} else {
Toast.makeText(mContext, "The app was not allowed to write in your storage", Toast.LENGTH_LONG).show();
}
}
}
}
check permissions for marshmallow
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;
}
Manifest
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus" />
openCamera Funtion
public void openCamera()
{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
try {
uri = createImageFile();
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
} catch (Exception e) {
Log.e(TAG, TAG + ": " + e.toString());
}
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
createImageFile funtion:
public Uri createImageFile() {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/TEST");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fName = "Image_" + n + ".jpg";
File file = new File(myDir, fName);
if (file.exists()) {
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Uri uriImage = Uri.fromFile(file);
return uriImage;
}
File file = new File(Environment.getExternalStorageDirectory(), "/download/"+ GlobalVars.apkname+".apk");
System.out.println("file>>>>>"+file);
Uri fileUri = Uri.fromFile(file);
if (Build.VERSION.SDK_INT >= 24) {
fileUri = FileProvider.getUriForFile(MainActivity.this,getPackageName(), file);
System.out.println("File URI>>>>>"+fileUri);
//fileUri = FileProvider.get
}
Below is my code for MainActivity.java.The error according to toasts is in creating directory.
MainActivity.java
#Override
protected void onActivityResult(int requestcode,int resultcode,Intent data){
super.onActivityResult(requestcode,resultcode,data);
if (requestcode == TAKE_PICTURE)
{
if(resultcode== Activity.RESULT_OK){
ImageView imageHolder = (ImageView)findViewById(R.id.image_camera);
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
String partFilename = currentDateFormat();
storeCameraPhotoInSDCard(bitmap, partFilename);
// display the image from SD Card to ImageView Control
String storeFilename = "photo_" + partFilename + ".jpg";
Bitmap mBitmap = getImageFileFromSDCard(storeFilename);
imageHolder.setImageBitmap(mBitmap);
}
}
}
private String currentDateFormat(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HH_mm_ss");
String currentTimeStamp = dateFormat.format(new Date(0));
return currentTimeStamp;
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
Toast.makeText(MainActivity.this, "WriteMode ON", Toast.LENGTH_SHORT).show();
return true;
}
Toast.makeText(MainActivity.this, "WriteMode OFF", Toast.LENGTH_SHORT).show();
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Toast.makeText(MainActivity.this, "Mounted or ReadMode", Toast.LENGTH_SHORT).show();
return true;
}
Toast.makeText(MainActivity.this, "no-Mounted or no-ReadMode", Toast.LENGTH_SHORT).show();
return false;
}
private void storeCameraPhotoInSDCard(Bitmap bitmap, String currentDate){
boolean isAvailable=isExternalStorageWritable();
if(isAvailable){
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,90, bytes);
String imgUri = "photo_" + currentDate + ".jpg";
File appDirectory = new File(Environment.getExternalStorageDirectory(),"CountDotsAppImages");
boolean success = appDirectory.mkdirs();
if (success) {
Toast.makeText(MainActivity.this, "Directory Created", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Failed - Error", Toast.LENGTH_SHORT).show();
}
File destination = new File(Environment.getExternalStorageDirectory(),"CountDotsAppImages/"+imgUri);
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
private Bitmap getImageFileFromSDCard(String filename){
File storageDir = new File(Environment.getExternalStorageDirectory() + "/", "CountDotsAppImages");
Bitmap bitmap = null;
File imageFile = new File(storageDir.getPath()+File.separator + filename);
try {
FileInputStream fis = new FileInputStream(imageFile);
Toast.makeText(MainActivity.this, imageFile.toString() , Toast.LENGTH_LONG).show();
bitmap = BitmapFactory.decodeStream(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap;
}
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> permission is added
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.countdots"
android:versionCode="1"
android:versionName="1.0" android:installLocation="auto">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Toasts Output :
Mounted or ReadMode
WriteMode ON
Directory Does Not Exist, Create It
Failed -Error //Error in creating directory mkdir
I tried using both mkdir() and mkdirs()
Figured it out.
As, I was compiling with Android 6.0. It requires user to grant permission.
So,following code should be inserted and checked if user grants app permission or not.Then if user grants permission to read and write manifest will be updated and volia !!!
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE},
1);
} else {
//do something
}
} else {
//do something
}
This code works for me
try{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,90, bytes);
imgUri = "photo_" + System.currentTimeMillis() + ".jpg";
File appDirectory = new File(Environment.getExternalStorageDirectory(),"CountDotsAppImages");
appDirectory.mkdirs();
File destination = new File(Environment.getExternalStorageDirectory(),"CountDotsAppImages/"+imgUri);
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
For adding directory you can use this method.
isAvailable=ExternalStorageChecker.isExternalStorageWritable();
if(isAvailable){
dir = new File(myContext.getExternalFilesDir(null), newAlbumDir.getText().toString().trim());
if(!dir.mkdirs()){
Log.e("++++++","Directoy Already Exist");
Log.e("External Directory Path","++++"+dir.getAbsolutePath());
}
else{
Log.e("++++","Directory Created");
Toast.makeText(myContext,"File Created on External",Toast.LENGTH_SHORT).show();
Log.e("Externa Directory Path","++++"+dir.getAbsolutePath());
}
}
else{
Toast.makeText(myContext,"File Created on Internal",Toast.LENGTH_SHORT).show();
Log.e("Internal Directory Path","++++"+myContext.getFilesDir().getPath());
dir=new File(myContext.getFilesDir(),newAlbumDir.getText().toString());
}
After it created the directory(dir) you can use to create the File.
I am having trouble in writing the file to sd card. (I am using Android 5.1 sdk version 23).
I have even tried the following code which prompts the user to select the user, where I select the "Sd card" and persist the permissions.
Manifest also has the write permission.
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public writeToFile() {
String filePath = "/storage/sdcard1/FileBrowser/Music";
File file = new File(filePath);
File parentDir = file.getParentFile();
if (parentDir != null) {
Log.d(TAG, parentDir.toString());
Log.d(TAG, file.getName());
File newFile = new File(parentDir + "/test.txt");
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(newFile));
writer.write("Hello", 0, "Hello".length());
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.d(TAG, "Parent file is null");
}
}
private void takeWritePermission() {
if(Build.VERSION.SDK_INT > 19) {
List<UriPermission> permissionList = getActivity().getContentResolver().getPersistedUriPermissions();
if (permissionList != null) {
UriPermission permission = permissionList.get(0);
if (permission == null) {
startPermissionActivity();
} else {
if (permission.isWritePermission()) {
writeToFile();
} else {
startPermissionActivity();
}
}
} else {
startPermissionActivity();
}
}
}
private void startPermissionActivity() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
}
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if(Build.VERSION.SDK_INT > 19) {
if (resultCode == AppCompatActivity.RESULT_OK) {
Uri treeUri = resultData.getData();
getActivity().getContentResolver().takePersistableUriPermission(treeUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
writeToFile();
}
}
}
> Exception: java.io.FileNotFoundException:
> /storage/sdcard1/FileBrowser/Music/test.txt: open failed: EACCES
> (Permission denied) at libcore.io.IoBridge.open(IoBridge.java:456)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:87) at
> java.io.FileOutputStream.<init>(FileOutputStream.java:72) at
> java.io.FileWriter.<init>(FileWriter.java:42)