Offline wallet on Android: can't access the JSON file - java

I'm trying to develop an app with Android Studio that creates a wallet file for the Ethereum Blockchain. I'm following this example.
I have two problems:
When I'm testing the app on my physical device, I can track down where is the JSON file, open it and see what is inside. On the Android Studio emulator I cannot find it.
Either on the emulator or physical device, the WalletUtils.loadCredentials function throws an error saying "some_filepath" (is a directory).
Code here:
public void createWallet(View view){
try{
WalletUtils.generateNewWalletFile(password, walletDir);
toastAsync("Wallet generated as" + walletDir);
}
catch (Exception e){
toastAsync("ERROR:" + e.getMessage());
}
}
public void getAddress(View view){
try {
Credentials credentials = WalletUtils.loadCredentials(password, walletDir.getAbsoluteFile());
toastAsync("Your address is " + credentials.getAddress());
}
catch (Exception e){
toastAsync("ERROR:" + e.getMessage());
}
}
I suppose loadCredentials can't reach the file, but I don't know why. I'm afraid the emulator actually doesn't create a file, because I couldn't find any, but on my physical device the file is there and loadCredentials still throws error

A File object in Java can represent both files and directories. I understand that walletDir File object is pointing to a directory where createWallet() method will store your credentials file. Then getAbsoluteFile() will return the same directory File object. You have to check the documentation on how to get a reference to the credentials file, or the path to it. Maybe WalletUtils.generateNewWalletFile() returns this information?

Related

Creating a text file in android

so i know there are alot of questions about creating a text file in android but i cant find any answers to my specific questions.
So the device I'm using is not an phone or a tablet, its a controller with android on it so the file directory is getting me confused. i want to create a new file either on the sd card or the device itself (it doesn't really matter as long as i can see it). firstly, the device doesn't have google docs or sheets or anything like that, will i need to install one of these apps on it for it to be able to read .txt files? or does android have some sort of internal software to do that?
Secondly, i've found alot of code on how to create a new file but most of it seems to gloss over how to get file directory, is there a specific way i can get the file directory?
This is what im using so far and im not getting any errors but its also not creating any files (or at-least none that i can see).
public void WriteToText(){
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = null;
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
1, I think all devices have Html viewer which can view the text files. If you click a text file in a file manager app, it should prompt you with a list of apps that can view the text file.
2, Your code is correct, but it creates a file in the app's private file directory, which is not visible to all other apps, including file manager apps. This is because of Android security policy to prevent any app to steal information from other apps.
If you want to write a file which is visible to other apps like file manager, there are 2 ways.
in old api level (<29?) you can get the get external storage with
Environment.getExternalStorageDirectory()
you will need to request permission for it.
save the file in your app's private directory like what you have done, then create a chooser to share it out with correct mime type (txt/plain?), it will prompt you to select app that can view this mime type like what file manager does.

CodenameOne - filesystem access problems on iOS for Library folder

My CodenameOne app is being tested on the iOS simulator (iPad 8th iOS 14).
It writes some files in the private folder by means of this method:
public void writeFile() throws IOException {
try(OutputStream os = FileSystemStorage.getInstance().openOutputStream(Utils.getRootPath()+DATA_FILE);)
{
os.write(JSONText.getBytes("UTF-8"));
os.flush();
os.close();
} catch(IOException err) {
System.out.println("exception trying to write");
}
}
It works on the CN simulator (writes inside the .cn1/ folder)
but on iOS the exception is catched. The Library folder is of paramount importance on iOS.
Below is the method to get the root path
public static String getRootPath()
{
String documentsRoot=FileSystemStorage.getInstance().getRoots()[0];
String os=Display.getInstance().getPlatformName();
if (os.toLowerCase().contains("ios")) {
int pos=documentsRoot.lastIndexOf("Documents");
if (pos==-1) return documentsRoot+"/";
String libraryRoot=documentsRoot.substring(0,pos)+"Library";
String result=libraryRoot+"/";
return result;
}
The CN version of my app has to write those private files in the same location as the swift version, that is Library.
There is string manipulation, and no extra '/' are added, the file path seems legit.
So the string
file:///Users/mac/Library/Developer/CoreSimulator/Devices/alphanumeric-string/data/Containers/Data/Application/another-alphanumeric-string/Documents/
is transformed and
the getRootPath() method returns
file:///Users/mac/Library/Developer/CoreSimulator/Devices/alphanumeric-string/data/Containers/Data/Application/another-alphanumeric-string/Library/
But there is exception.
Furthermore, at some point after the writing attempt, I see in the console output something I think is relevant:
Failed to create directory /Users/mac/Library/Developer/CoreSimulator/Devices/alphanumeric-string/data/Containers/Data/Application/another-alphanumeric-string/Documents/cn1storage/
What is this? Is it related to my problem?
Is CN filesystem access broken or flawed?
I know io access permissions are automatically created by the CN compiler, but are they working?
So how to fix my issue about the Library folder?
The cn1storage printout just means the storage directory already exists.
The way to get the library path is this: Getting an iOS application's "~/Library" path reliably
You need to use that approach. I think your assumption that Document and Library reside under the exact same hierarchy is just incorrect.

Android internal files seems to disappear after I restart my application

I am new to android and currently trying to save a few files in a little "play-around" application I am making to learn, however the files only seem to persist until the application is shut down. When I run:
file.exists()
file.isFile()
or any similar methods they always return false when the application is restarted.
This is the method I found online to save files:
public void writeToFile(String data, String filePath, Context context){
File file = new File(context.getFilesDir(), filePath);
if(!file.exists()){
try{
file.createNewFile();
}catch(IOException e) {
e.printStackTrace();
Log.e("Exception", "File couldn't be created");
}
}
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput(filePath, Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
I have been googling a lot trying to find a solution but none of them worked. It seems to work when the application is running since I can write and read the files, however at a restart of the application, it cannot find the files. (file.exists() returns false)
I just spend an hour tracking down this same bug and it turned out it was because the "Clear User Data" flag was set under "Deployment" in the project properties. I'm using NVIDIA CodeWorks for Android with Visual Studio 2017.
I assume that you are attempting to write to internal storage here? If not and you wish to access external storage, I would suggest having a look through the guidance on Android.com below.
https://developer.android.com/guide/topics/data/data-storage.html#filesInternal
If this is internal storage that you are trying to write to, then you need to make sure that you are passing the correct context to the method. For example, if you were running from your MainActivity class and the method was contained within that class, your call would be something along the lines of:
writeToFile("Some data", "aFile.txt", MainActivity.this)

Creating file for internal storage returns Null Pointer Exception

Hi I have a project that should save a JSON Array to internal storage.
Here's my code:
public void createFile(String data){
try{
FileOutputStream fos = openFileOutput("userObj", Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
Log.d(TAG, "Successfully created userObj file.");
}catch (Exception e){
Log.d(TAG, "Failed to create userObj " + e);
}
}
but when I'm calling createFile(response);
I'm getting
java.lang.NullPointerException at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:180)
check whether you have the permission WRITE_EXTERNAL_STORAGE no matter you use internal storage or external storage.
check whether the file path is correct. You have to create the file path by Environment.getExternalStorageDirectory ()
Note: don't be confused by the word "external" here. This directory
can better be thought as media/shared storage. It is a filesystem that
can hold a relatively large amount of data and that is shared across
all applications (does not enforce permissions). Traditionally this is
an SD card, but it may also be implemented as built-in storage in a
device that is distinct from the protected internal storage and can be
mounted as a filesystem on a computer.
I'm getting java.lang.NullPointerException at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:180
You don't have a valid Context you're working with.
Likely it's an Activity you have instantiated yourself with new. Don't do that. Activities should only by instantiated via an Intent by the framework. If you need to pass a Context around, pass a reference to a framework-initialized Context object such as an Activity around.

Private file for an app

I would like to create a file which stores some data that can be accessed only by my app.Outside users should not be able to access this file or make any changes to it.I will store a key in the file which maybe accessed by the app whenever needed.
Use Environment.getDataDirectory(),
http://developer.android.com/reference/android/os/Environment.html#getDataDirectory()
This gives a File object that is the path to a private, app specific data directory. The files created therein are owned by your app's user ID, preventing any other app from accessing them.
File myPrivateFile = new File(Environment.getDataDirectory(), context.getPackageName() + File.separator + "secret.txt");
Note that if the device is rooted, all bets are off. A root process can read any file on the device. The best you can do is only store information for user of the device. That way if it's compromised, only one user account is compromised. In other words, don't store credentials, keys, access tokens, etc. That would allow a malicious agent access to a server where it could steal data for other users.
To create an application private file (that is not readable by other applications) you should use Context.openFileOutput() with a flag MODE_PRIVATE.
If you are concerned you could wrap the returned InputStream in CiperOutputStream and encrypt the contents.
If you are storing keys in a standard crypto format (X.509 or PKCS#12) you could use the new KeyChain API introduced in ICS.
Why not just stored it in a SharedPreference ??
Make your SharedPreference private to your activity by calling..
getSharedPreferences(yourfile, MODE_PRIVATE);
This will make sure only your Activity can access that SharedPreference.
To open a file from a private app folder, one can use this file path:
File myFilePath = new File(getContext().getFilesDir() + File.separator + "myFile")
You can check if the file exists if(myFilePath.exists()) ...
To save a text file to the private app directory
FileOutputStream fos = null;
try {
fos = getContext().openFileOutput("myFile",Context.MODE_PRIVATE);
} catch (FileNotFoundException e) { }
try {
fos.write(myTextString.getBytes());
} catch (IOException e) { }
try {
fos.close();
} catch (IOException e) { }
To save an image to the private app directory:
try {
myBitmapImage.compress(CompressFormat.JPG, 90,
openFileOutput("myimage.jpg", MODE_PRIVATE));
} catch (Exception e) { }
Your best bet is to store an encrypted file and decrypt it run-time, so even a rooted phone would not be able to read your data even if it has access to it. Of course, it's a chicken-egg condition (where would you store your key for the encrypted file), and the only thing better than putting the key in a variable is to generate that key runtime using some obscure method (see this)

Categories

Resources