I created an encrypted OBB file from the JOBB tool and I am trying to access the files inside of it, there are some images "image1.jpg, image2.jpg" etc. So far I am able to successfully mount it with:
public void mountExpansion() {
final StorageManager storageManager = (StorageManager) this.getSystemService(Context.STORAGE_SERVICE);
String packageName = "com.nick.app";
String filePath = Environment.getExternalStorageDirectory()
+ "/Android/obb/" + packageName + "/" + "main."
+ getString(R.string.apk_expansion_version) + "." + packageName + ".obb";
final File mainFile = new File(filePath);
if (mainFile.exists()) {
Log.d("STORAGE", "FILE: " + filePath + " Exists");
} else {
Log.d("STORAGE", "FILE: " + filePath + " DOESNT EXIST");
}
String key = "123456";
if (!storageManager.isObbMounted(mainFile.getAbsolutePath())) {
if (mainFile.exists()) {
if(storageManager.mountObb(mainFile.getAbsolutePath(), key,
new OnObbStateChangeListener() {
#Override
public void onObbStateChange(String path, int state) {
super.onObbStateChange(path, state);
Log.d("PATH = ",path);
Log.d("STATE = ", state+"");
expansionFilePath = storageManager.getMountedObbPath(path);
if (state == OnObbStateChangeListener.MOUNTED) {
expansionFilePath = storageManager
.getMountedObbPath(path);
Log.d("STORAGE","-->MOUNTED");
Log.d("NICK","length()"+mainFile.length());
Log.d("NICK","getAbsolutePath()"+mainFile.getAbsolutePath());
Log.d("NICK","isDirectory()"+mainFile.isDirectory());
}
else {
Log.d("##", "Path: " + path + "; state: " + state);
}
}
}))
{
Log.d("STORAGE_MNT","SUCCESSFULLY QUEUED");
}
else
{
Log.d("STORAGE_MNT","FAILED");
}
} else {
Log.d("STORAGE", "Patch file not found");
}
}
}
And in my log I see the state "1" returned from OnObbStateChangeListener indicating the encrypted OBB file is successfully mounted. However at this point I am at a loss for how I can access the files inside of it and make use of them. For example load them into an ImageView etc. Any suggestions for what I am missing here?
storageManager.mountObb(main.getPath(), null, new OnObbStateChangeListener() {
#Override
public void onObbStateChange(String path, int state) {
super.onObbStateChange(path, state);
if (state == MOUNTED) {
Toast.makeText(MainActivity.this, "obb mounted", Toast.LENGTH_LONG).show();
File file = new File(storageManager.getMountedObbPath(path));
} else
Toast.makeText(MainActivity.this, "mount fail :" + path, Toast.LENGTH_LONG).show();
}
});
The file object is directory to all your files in obb.
To access those you may call listFiles() on it.
Related
Now I copy mp4 file from external storage folder and save copy file in gallery with folder. But My gallery app doesn't have folder I code. Surely, File too. But In File Browser, There are exists correctly in DCIM folder.
So, How can I save file in gallery with folder that I code. Please let me know If you can solve this issue.
private void saveToGallery(String recVideoPath) {
progressdialog = new CNetProgressdialog(this);
progressdialog.show();
String folderName = "DuetStar";
String fromPath = recVideoPath;
String toPath = Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DCIM;
File toPathDir = new File(toPath + "/" + folderName);
final File fromPathFile = new File(fromPath);
File toPathFile = new File(toPath + "/" + folderName, recVideoPath.substring(recVideoPath.lastIndexOf("/") + 1, recVideoPath.length()));
Log.d(TAG, "saveToGallery: " + RecordActivity.currentCreateFileName);
Log.d(TAG, "saveToGallery: " + toPathDir.toString());
Log.d(TAG, "saveToGallery: " + fromPath.toString());
Log.d(TAG, "saveToGallery: " + toPath.toString());
if (!toPathDir.exists()) {
toPathDir.mkdir();
} else {
}
FileInputStream fis = null;
FileOutputStream fos = null;
try {
if (toPathDir.exists()) {
fis = new FileInputStream(fromPathFile);
fos = new FileOutputStream(toPathFile);
byte[] byteArray = new byte[1024];
int readInt = 0;
while ((readInt = fis.read(byteArray)) > 0) {
fos.write(byteArray, 0, readInt);
}
Log.d(TAG, "saveToGallery: " + readInt);
fis.close();
fos.close();
Log.d(TAG, "saveToGallery: " + "Seucceful");
} else {
Toast.makeText(this, "There is no directory", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.getMessage();
}
progressdialog.dismiss();
}
You can save in specific folder as you wish see this code snippet for idea
String extStorageDirectory;
extStorageDirectory = Environment.getExternalStorageDirectory().toString() + "/Video Folder name/";
//making the folder
new File(extStorageDirectory).mkdirs();
when i am deleting the file the code is running and showing me the toast of deleted file also but not deleting it from SD card.
code is below :
delete_btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
fn = baseAppDir.getPath()+ File.separator + folderName + File.separator
+ folderName + "_" + Integer.toString(imgNo) + ".jpg";
FileName = folderName + "_" + Integer.toString(imgNo)
+ ".jpg";
if (FileName!=null)
{
deleteFile(FileName);
Toast.makeText(ImageCaptureActivity.this, "Deleted",
Toast.LENGTH_LONG).show();
image1.setVisibility(View.GONE);
} else {
Toast.makeText(ImageCaptureActivity.this, "Not Deleted",
Toast.LENGTH_LONG).show();
}
}});
Have a look on following : Delete a file
Your can do like as below :
try {
deleteFile(FileName);
Toast.makeText(ImageCaptureActivity.this, "Deleted", Toast.LENGTH_LONG).show();
image1.setVisibility(View.GONE);
} catch (NoSuchFileException x) {
System.err.format("%s: no such" + " file or directory%n", path);
} catch (DirectoryNotEmptyException x) {
System.err.format("%s not empty%n", path);
} catch (IOException x) {
// File permission problems are caught here.
System.err.println(x);
}
Try this may be its help full too..
File dir = new File(Environment.getExternalStorageDirectory() + "/DCIM/Camera");
Log.e(TAG, " get path ..**... " + dir.getPath());
Log.e(TAG, " get Directory ..**... " + dir.isDirectory());
Log.e(TAG, " get Name ..**... " + dir.getName());
Log.e(TAG, " get strign ..**... " + dir.list());
if (dir.isDirectory()) {
String[] children = dir.list();
Log.e(TAG, " children .... ... " + children.length);
for (int i = 0; i < children.length; i++) {
Log.e(TAG, "Delete old Image ...");
new File(dir, children[i]).delete();
}
}
this is code for delete multiple image from SD card.
replace
if (FileName!=null) {
deleteFile(FileName);
Toast.makeText(ImageCaptureActivity.this, "Deleted",
Toast.LENGTH_LONG).show();
image1.setVisibility(View.GONE);
} else {
Toast.makeText(ImageCaptureActivity.this, "Not Deleted",
Toast.LENGTH_LONG).show();
}
with
File file = new File(FileName);
if (file.delete()){
Toast.makeText(ImageCaptureActivity.this, "Deleted",
Toast.LENGTH_LONG).show();
image1.setVisibility(View.GONE);
} else {
Toast.makeText(ImageCaptureActivity.this, "Not Deleted",
Toast.LENGTH_LONG).show();
}
In my app i want to store camera images taken by the user in a folder.So for that i have created a folder ,but when erer i open my sd-card i cannot find that folder.Whats wrong with my code.
Create FIle
protected void createFile(Context context, String mainName, String subName) {
file = new File(Environment.getExternalStorageDirectory() + "/" + mainName + "/" + subName);
if (!file.exists()) {
file.mkdirs();
Toast.makeText(getActivity(), "File created" + file.toString(), Toast.LENGTH_LONG).show();
}
}
Class where i am user the above method
public void onClick(View view) {
setUp();
createFile(getActivity(),"pocketDocs","Camera");
switch (view.getId()) {
case R.id.bt_choose_file:
displayPopup(getActivity(), "Choose File", chooseDocumentArray, btChooseDoc, false, new GetNamePosition() {
#Override
public void getName(String name) {
userSelection = name;
if (userSelection.equals("Camera")) {
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
btChooseDoc.setText("Choose File");
}
Use
file = new File(Environment.getExternalStorageDirectory() + "/" + mainName
+ "/" + subName + "/");
Instead of
file = new File(Environment.getExternalStorageDirectory() + "/" + mainName
+ "/" + subName);
Without the trailing separator (in your case /), Android (which is based on UNIX), interprets this as a file (not a directory). This is due to the File class in Java representing files and directories. And you simply cannot create directories inside a file.
Also add WRITE_EXTERNAL_STORAGE permission in your manifest.
Should I be using something other than the MediaScannerConnection.scanFile method to refresh the gallery?
After saving a new jpg I run media scanner to refresh the gallery app like so
MediaScannerConnection.scanFile(this,
new String[] { fullname }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.d("ExternalStorage", "#### Scanned " + path + ":");
Log.d("ExternalStorage", "#### -> uri=" + uri);
}
});
The output of the log shows the following correct output
#### Scanned /data/data/com.mypackage/files/skit_106_01.jpg:
#### -> uri=content://media/external/images/media/95
The gallery app shows no media available
This code has been working perfectly for some time now. It was only when I created an Android avd against version 4.4.2 for further testing that the problem has surfaced.
The code I have seems to be the recommended way of refreshing the gallery app according to Androids documentation so maybe this issue is related to the way I am saving the file, the code for which is as follows.
UPDATE
The code checks for external storage availability and will write to external storage and if external storage is not available it will write the file to internal storage.
private void doSave(String fname, boolean doShare) {
fname = "skit_"+mCurrentSkitId +
"_"+mSkitManager.getCurrentFrameCount(
mCurrentSkitId)+1;
Log.d(TAG, "#### doSave fName = " + fname + " Current skit id = " + mCurrentSkitId);
CharSequence text = getResources().getString(R.string.saved_as)
+ " " + fname;
try {
Bitmap b = mMainView.getSaveBitmap();
if (b == null) {
text = getResources().getString(R.string.save_fail_1);
;
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
return;
}
fname = FileUtils.replaceInvalidFileNameChars(fname);
String value = fname;
File folder = FileUtils.getWritableFolder(this);
/*
* String folder =
* Environment.getExternalStorageDirectory().toString() +
* "/Pictures"; try { folder =
* Environment.getExternalStoragePublicDirectory
* (Environment.DIRECTORY_PICTURES).toString(); } catch
* (NoSuchFieldError e) {
*
* }
*/
String ext = ".jpg";
if (mPrefs.getString("format", "JPG").equals("PNG"))
ext = ".png";
String fullname = folder.getAbsolutePath() + File.separator + value
+ ext;
Map<String, String> hm = new HashMap<String, String>();
hm.put("filename", fullname);
FileOutputStream fos;
if (folder == getFilesDir())
fos = openFileOutput(value + ext, Context.MODE_WORLD_WRITEABLE);
else {
File f2 = new File(fullname);
fos = new FileOutputStream(f2);
}
b.compress(CompressFormat.JPEG, 95, fos);
fos.close();
String[] str = new String[1];
str[0] = fullname;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.FROYO) {
MediaScannerConnection.scanFile(this,
new String[] { fullname }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.d("ExternalStorage", "#### Scanned " + path + ":");
Log.d("ExternalStorage", "#### -> uri=" + uri);
}
});
}
text = text + value + ext + " "
+ getResources().getString(R.string.saved_end);
;
mLastSaveName = value;
setDetailTitle();
mSkitManager.createFrame(mCurrentSkitId, fullname);
} catch (Exception e) {
Map<String, String> hm = new HashMap<String, String>();
hm.put("text", e.toString());
e.printStackTrace();
text = getResources().getString(R.string.save_fail_2)
+ e.toString();
} catch (Error e) {
Map<String, String> hm = new HashMap<String, String>();
hm.put("text", e.toString());
e.printStackTrace();
text = getResources().getString(R.string.save_fail_2)
+ e.toString();
}
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
The code that does the check for external storage availability looks like this
public static File getWritableFolder(Context context) {
File folder = context.getFilesDir();
if (externalStorageAvailable()) {
try {
folder = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!folder.exists() || !folder.canWrite()) {
folder = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
}
if (!folder.exists() || !folder.canWrite()) {
folder = Environment.getExternalStorageDirectory();
}
} catch (Exception e) {
folder = Environment.getExternalStorageDirectory();
} catch (Error e) {
folder = Environment.getExternalStorageDirectory();
}
if (!folder.exists() || !folder.canWrite()) {
folder = context.getFilesDir();
}
}
return folder;
}
private static boolean externalStorageAvailable() {
boolean mExternalStorageAvailable;
boolean mExternalStorageWriteable;
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but
// all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
return mExternalStorageAvailable && mExternalStorageWriteable;
}
If anyone is able to pick holes in any of the above that might help to solve this issue then that would be great.
i was having mixed results with MediaScannerConnection so i used the sendBroadcast method instead. I do not know if the sendBroadcast method is not standard/should not be used but it works for me.
public void galleryAddPic(File currentPhotoPath) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(currentPhotoPath);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
Also regarding the MediaScannerConnection : https://stackoverflow.com/a/4825615/1497188
I'm currently working on an App that receives multiple images via socket. To save them, I wrote the following methods:
public static boolean saveTempImageToGallery(Context c) {
try {
FileInputStream fis = c.openFileInput(Settings.TEMP_PHOTO_STORAGE);
// create name of file: [date]-[time]-baby
final String tFilename = new SimpleDateFormat("dd-MM-yyyy_hh-mm-ss")
.format(new Date()) + ".png";
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
Log.d(TAG, "External storage available.");
// sd card available
File dir = getExternalStorageDir("Photos");
if (dir.mkdirs() || dir.isDirectory()) {
Log.i(TAG, "Directory: "+dir.getAbsolutePath());
File newImage = new File(dir, tFilename);
if (newImage.createNewFile() && newImage.isFile()) {
Log.i(TAG, "Saving image to "+newImage.getAbsolutePath());
final Bitmap bmp = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// compress image to png
bmp.compress(Bitmap.CompressFormat.PNG, 40, baos);
FileOutputStream fo = new FileOutputStream(newImage);
fo.write(baos.toByteArray());
fo.close();
Log.i(TAG, "Image saved!");
return true;
}
} else {
Log.d(TAG, "Could not create directory.");
}
} else {
Log.d(TAG, "External storage not available.");
}
} catch (Exception e) {
}
return false;
}
public static File getExternalStorageDir() {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/"
+ Settings.EXT_STORAGE_DIRECTORY);
return dir;
}
public static File getExternalStorageDir(String subdir) {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/"
+ Settings.EXT_STORAGE_DIRECTORY + "/" + subdir);
return dir;
}
After saving them, I'd like to offer the user the possibility to view them in the default gallery app. After reading some post, I adapted the following code:
MediaScannerConnectionClient mScanClient = new MediaScannerConnectionClient() {
#Override
public void onScanCompleted(String path, Uri uri) {
try {
Log.d("onScanCompleted", uri + "success");
if (uri != null) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
}
} finally {
if (mScanCon != null)
mScanCon.disconnect();
mScanCon = null;
}
}
#Override
public void onMediaScannerConnected() {
Log.i(TAG, "Media Scan Connected.");
String[] files = Support.getExternalStorageDir("Photos")
.list();
Log.i(TAG,
Support.getExternalStorageDir("Photos").list().length
+ " elements in dir.");
if (files.length > 0) {
for (String cur : files) {
if (cur.equals(".") || cur.equals(".."))
continue;
Log.i(TAG, "Using "
+ cur
+ " to scan stuff. "
+ Support.getExternalStorageDir("Photos")
.getAbsolutePath() + "/" + cur);
Log.i(TAG, "Not using "
+ cur
+ " to scan stuff. "
+ Support.getExternalStorageDir("Photos")
.toString() + "/" + cur);
mScanCon.scanFile(
Support.getExternalStorageDir("Photos")
.getAbsolutePath() + "/" + cur,
"image/*");
break;
}
} else {
Toast.makeText(getApplicationContext(),
"No images available.", Toast.LENGTH_LONG)
.show();
}
}
};
if (mScanCon != null)
mScanCon.disconnect();
mScanCon = new MediaScannerConnection(getApplicationContext(),
mScanClient);
mScanCon.connect();
Weird thing: Seems like onMediaScannerConnected is never fired - anyone has an idea? I've been searching the web and stackoverflow for the last hour..
Thank you.
You really don't have to connect to the media scanner to start a scan, you can use this static method instead.
MediaScannerConnection.scanFile(context, new String[] {dir.getAbsolutePath()}, null, null);
edit:
Uri uri = Uri.parse(filePath);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(uri, "image/*");
startActivity(i);