I try to save the captured image but got an error like the title.
private File createPhotoFile(){
File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES +"/sidentanpic/");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(storageDir)));
try{
if(storageDir.exists()){
System.out.println("Folder tersedia");
}else{
storageDir.mkdir();
System.out.println("Folder telah dibuat");
}
}catch(Exception e){
e.printStackTrace();
}
String name = new SimpleDateFormat("yyyyMMddd_HHmmss").format(new Date());
File image =null;
try{
image = File.createTempFile(name,".jpg", storageDir);
}catch(Exception e){
Log.d("Failed","Gagal menyimpan "+ e.toString());
}
return image;
}
should I add something in AndroidManifest?
getExternalStoragePublicDirectory() is static method in Environment class. So, please try as below:
Environment.getExternalStoragePublicDirectory()
But, This method is deprecated in Android Q version. Please check the documentation for more info on this.
Related
I have written codes for adding sticker pack dynamically. But I want to know how to update the sticker pack after adding to whatsapp?
I can add sticker file to the pack which is listed on my app only but it is not reflecting in whatsapp. I tried adding files to the same location (file:///...) from where the pack was sent to whatsapp.
I want to try updating content provider. But how to do that? Can I add files to whatsapp's 'content://...' uri or should I update my app's content provider or anything else?
I am using react-native-whatsapp-stickers module for react-native.
react-native code
invoking after adding single sticker from UI
const addOne = (path, packName) =>{
// log('path ',path[0])
// log('packName ',packName)
RNWhatsAppStickers.addSticker(path[0],packName)
.then(res=>RNWhatsAppStickers.send(packName,packName))
.then(res=>console.log('response ',res))
}
Java code of module RNWhatsAppStickers
#ReactMethod
public void send(String identifier, String stickerPackName, Promise promise) {
Intent intent = new Intent();
intent.setAction("com.whatsapp.intent.action.ENABLE_STICKER_PACK");
intent.putExtra(EXTRA_STICKER_PACK_ID, identifier);
intent.putExtra(EXTRA_STICKER_PACK_AUTHORITY, getContentProviderAuthority(reactContext));
intent.putExtra(EXTRA_STICKER_PACK_NAME, stickerPackName);
try {
Activity activity = getCurrentActivity();
ResolveInfo should = activity.getPackageManager().resolveActivity(intent, 0);
if (should != null) {
activity.startActivityForResult(intent, ADD_PACK);
promise.resolve("OK");
} else {
promise.resolve("OK, but not opened");
}
} catch (ActivityNotFoundException e) {
promise.reject(ERROR_ADDING_STICKER_PACK, e);
} catch (Exception e) {
promise.reject(ERROR_ADDING_STICKER_PACK, e);
}
}
// saving image to same pack
public static void SaveImage(Bitmap finalBitmap, String name, String identifier) {
String root = path + "/" + identifier;
File myDir = new File(root);
myDir.mkdirs();
String fname = name;
File file = new File(myDir, fname);
if (file.exists()){
// Log.d("ReactNative","root "+root);
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.WEBP, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Please give any idea what to do? Thanks
I found the solution on official doc. You have to increase the image_data_Version for that pack after adding new images.
To track the image_data_Version you can query the ContentProvider of your app or Store the image_data_Version somewhere and make changes accordingly .
I'm developing image editor app.. so each time the user have to save the image.
So first i inserted
String savedImageURL = MediaStore.Images.Media.insertImage(
getContentResolver(),
bitmap,
"Bird",
"Image of bird"
);
this code, but it creating new file instead of overwriting.
So i use another method
public String saveImage(String folderName, String imageName) {
String selectedOutputPath = "";
if (isSDCARDMounted()) {
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), folderName);
// Create a storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("PhotoEditorSDK", "Failed to create directory");
}
}
// Create a media file name
selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
Log.d("PhotoEditorSDK", "selected camera path " + selectedOutputPath);
File file = new File(selectedOutputPath);
try {
FileOutputStream out = new FileOutputStream(file,true);
if (parentView != null) {
parentView.setDrawingCacheEnabled(true);
parentView.getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 80, out);
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return selectedOutputPath;
}
But it also didn't work.
Does anyone know about overwrite a bitmap in the same name?
Pass false as 2nd argument, to set append to false, so that you will overwrite the existing file:
FileOutputStream out = new FileOutputStream(file,false);
Check out the constructor documentation:
here is your code:
public String saveImage(String folderName, String imageName) {
String selectedOutputPath = "";
if (isSDCARDMounted()) {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), folderName);
// Create a storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("PhotoEditorSDK", "Failed to create directory");
}
}
// Create a media file name
selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
Log.d("PhotoEditorSDK", "selected camera path " + selectedOutputPath);
File file = new File(selectedOutputPath);
if (file.exists())
{
try {
file.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
file.createNewFile();
FileOutputStream out = new FileOutputStream(file,false);
if (parentView != null) {
parentView.setDrawingCacheEnabled(true);
parentView.getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 80, out);
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return selectedOutputPath;
}
I also had this situation, but it turns out that this is not a problem with saving, but with displaying in ImageViev. I used Glide, and it turns out to be stored in the cache when outputting. And I did not change the name and path of the file. That is, I rewrote them. But Glide did not know this. He thought they were the same file. To fix this problem, I added the following
Glide.with(context)
.load(file)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(view)
If you also have this situation and these solutions helped you, I'm glad to this.
I'm trying to copy files from the assets folder to the device folder using this function:
public static void copyJSON(Context aContext) {
AssetManager assetManager = aContext.getResources().getAssets();
String[] pFiles = null;
try {
pFiles = assetManager.list("ConfigurationFiles");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (pFiles != null) for (String pJsonFileName : pFiles) {
InputStream tIn = null;
OutputStream tOut = null;
try {
tIn = assetManager.open("ConfigurationFiles" + File.separator + pJsonFileName);
String[] pList = aContext.getFilesDir().list(); //just for test
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
tOut = new FileOutputStream(pOutFile);
if (pOutFile.exists()) {
copyFile(tIn, tOut);
}
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: " + pJsonFileName, e);
} finally {
if (tIn != null) {
try {
tIn.close();
} catch (IOException e) {
Log.e("tag", "Fail closing", e);
}
}
if (tOut != null) {
try {
tOut.close();
} catch (IOException e) {
Log.e("tag", "Fail closing", e);
}
}
}
}
}
If I delete the App and run the code, the variable pList is empty as I expect but the pOutFile.exists()returns true ALWAYS!!.
I don't want to copy them again every time I open my App, and I'm doing this because all my app uses JSON to navigate thru all the screens, so If I change any value in my BBDD a WS send a new JSON file and the App respond in accordance for example a button is no longer needed, so the first time you download my App I copy the original JSON and then if you use the app an if you have internet connection you will download a new JSON file that it is more accurate than the one that is in the Bundle and it will be override, this is because as far as I know I can't change the files that are in the assets folder.
I have read everywhere and all say the same use this:
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
And then ask for this:
pOutFile.exists()
I don't know what I'm doing wrong.
Thanks for all your help.
put it this way:
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
if (pOutFile.exists()) {
tOut = new FileOutputStream(pOutFile);
copyFile(tIn, tOut);
}
and everything should work fine. Remember the FileOutputStream creates the file it should stream to if possible and non existing
The problem is you're essentially creating a file and then checking if it exists.
try {
tIn = assetManager.open("ConfigurationFiles" + File.separator + pJsonFileName);
String[] pList = aContext.getFilesDir().list(); //just for test
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
// See here: you're creating a file right here
tOut = new FileOutputStream(pOutFile);
// And that file will be created in the exact location of the file
// you're trying to check:
if (pOutFile.exists()) { // Will always be true if FileOutputStream was successful
copyFile(tIn, tOut);
}
}
You should instead create your FileOutputStream AFTER you've done your existence check.
Source: http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html
A file that you have just created without getting an exception always exists. The test is pointless. Remove it.
How do I delete an internal save file dynamically in an Android application? I saved it in the default directory so I don't know the exact file path. Here is the code I used to save my files if that helps any:
public void saveAssignments(){
String saveData = "";
String FILENAME = name.replaceAll(" ", "") + ".txt";
//Context context = getApplicationContext();
Context context = getActivity();
FileOutputStream fos;
for(int i = 0; i < allEds.size(); i++){
saveData = saveData + allEds.get(i).getText().toString() + ", ";
}
try{
fos = context.openFileOutput( FILENAME, Context.MODE_PRIVATE );
try{
fos.write(saveData.getBytes());
fos.close();
//Toast.makeText(context, "Saved as " + FILENAME, 5000).show(); //popup message
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
You can delete file created by using openFileOutput method as:
File file=new File(context.getFilesDir().getAbsolutePath()+"/"+FILENAME);
if(file.exists())file.delete();
You could use method
deleteFile(String filename)
on your context-object.
http://developer.android.com/reference/android/content/Context.html#deleteFile%28java.lang.String%29
Furthermore you could use
String[] fileList ()
to query your files.
http://developer.android.com/reference/android/content/Context.html#fileList%28%29
You should try
getFilesDir() from context to return path or refer to here. Then you can delete it.
I'm trying to create a file on the SD on my device. This worked a week ago, but now it isn't, and I don't understand why.
The Logcat prints:
java.io.FileNotFoundException ...pathtofile... (no such file or directory)
So, the file is not being created. I have the correct permissions on the android manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
I create the file this way:
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
base = Environment.getExternalStorageDirectory().getAbsolutePath();
}
String fname = File.separator +"VID_"+ timeStamp + ".3gp";
mediaFile = new File(base+fname);
Then I check if it exists:
if(mediaFile.exists()){
Log.v("mediaFile","ex");
}else{
Log.v("mediaFile","no ex");
}
And the log says that IT DOESN'T EXIST. I also have tried with file.createNewFile() and it doesn't work.
So, a week ago it was working, now it doesn't work, it could be a problem with the SD card ???? Could it be some type of BUG!!!????
Thanks
EDIT: More Code
The function where the file is created is :
private static File getOutputMediaFile()
Called from:
private static Uri getOutputMediaFileUri(){
return Uri.fromFile(getOutputMediaFile());
}
And setted to mediarecorder output as:
vMediaRecorder.setOutputFile(getOutputMediaFileUri().toString());
So, when I do mediarecorder.prepare():
try {
vMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.v("RELEASE VIDREC1",e.toString());
releaseMediaRecorder();
return false;
} **catch (IOException e) {
Log.v("RELEASE VIDREC2",e.toString());
releaseMediaRecorder();
return false;**
}
The bold catch is the one that runs, and prints:
java.io.FileNotFoundException ...pathtofile... (no such file or directory)
just try this
String fname = "VID_"+ timeStamp + ".3gp";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
mediaFile = new File(android.os.Environment.getExternalStorageDirectory(),fname);
if(!mediaFile.exists())
{
mediaFile.createNewFile();
}
}
if(mediaFile.exists()){
Log.v("mediaFile","ex");
}else{
Log.v("mediaFile","no ex");
}
You merely create the object mediaFile, not the actual file. Use this:
if(!f.exists()){
f.createNewFile();
}
I tried this, for me it works.
final String filename = "file.3gp";
final String path = Environment.getExternalStorageDirectory() + "/" + filename;
File outputfile = new File(path);
if (!outputfile.exists()) {
try {
outputfile.createNewFile();
}
catch (IOException e) {
e.printStackTrace();
}
}
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(outputfile.toString());
try {
recorder.prepare();
recorder.start();
/*recorder.stop();
recorder.reset();
recorder.release();*/
}
catch (IllegalStateException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
Try and see whether or not it works. If not, can you add the full code of getOutputMediaFile()?
My answer here:
First open the path, then add the file:
String dir = Environment.getExternalStorageDirectory(); // getAbsolutePath is not requried
File path = new File(dir);
File root = new File(path, "VID_"+ timeStamp + ".3gp";);
Thanks for your help, I've solved the problem using old code. It is strange because the "file saving" part has no modification. Thanks for all guys, kinda.