Access Skype db from data/app location - android

I want to get the Skype db file, which is called main.db and is not encrypted like WhatsApp etc. and copy that file to my custom folder.
What I am trying to do is the following: (my device is rooted and I am giving my app SuperUser access)
public void getSkypeDB() throws InterruptedException
{
Process sh;
try
{
sh = Runtime.getRuntime().exec("su", null, null);
File skypeDir= new File("/data/app", "/com.skype.raider");
Toast.makeText(getApplicationContext(), skypeDir.toString(), 0).show();
sh.waitFor();
}
catch (IOException e)
{
e.printStackTrace();
}
}
After doing this, my app crashed!
How can I get access to its database or access to the location of the database in the /data/app folder?

The database for an app won't be in /data/app/<app_package_name>, that's where the downloaded or pre-bundled APKs are located. The runtime data directory for an app is at /data/data/<app_package_name>. Also, be sure to include the stack trace from your exception catch or from the crash itself, otherwise it is a lot harder for people to help.

Related

Cannot view logged file on PC but can see it on my phone

public void appendLog(String text) {
File logFile = new File(Environment.getExternalStorageDirectory() + "/Nexus_Uroflow_" + m_Text + ".csv"); // newly changed
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
Log.e(TAG, "Error while creating file. ", e);
e.printStackTrace();
}
}
try {
// BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile,
true));
buf.append(text);
buf.newLine();
buf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
hi guys, i have an app that logs data to csv file. However i have can see it in my phone, but not in my PC until i moved those file to a folder in phone. Can anyone explain to me what is the problem ? Thanks in advance.
Phone storage
View in PC
As Far as I know, Environment.getExternalStorageDirectory() folder completely depends on phone. Quote from reference:
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.
It means each phone can consider a specific folder (even on internal memory) as its external storage directory and return it in getExternalStorageDirectory(). Maybe on your phone, this folder is not really on where you expect and that's why you cannot find it. At least I had similar problem in one of the famous brands.
I personally use /sdcard/ folder whenever I want to push something using adb to my phone/emulator. In this case I almost always can find it easily. But this is not correct approach if you want to use it for your app.
And finally always use Context.getExternalStorageDirectory() rather than Environment.getExternalStorageDirectory().

Android - unzip file during first app run

I have an apk file which contains zipped database (in asset folder). I want to unzip this database during first app run. For that case I am going to use zip4j like so:
public void unzipping() {
String source = "";//here source of zipped database
String destination = "";//here where database should be after installation
String password = "mypassword";
try {
ZipFile zipFile = new ZipFile(source);
if (zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
zipFile.extractAll(destination);
} catch (ZipException e) {
e.printStackTrace();
}
}
The problem is that I don't know what correct path to specify in "source" and "destination".
There is nothing wrong with using encryption to protect user data. But understand, that the attacker can always decompile/memory dump your app and grab the password you are using to read/write to the database.
I'd a SQLCipher , which makes it transparent to the other parts of the app.

Android file writing

Having a problem writing out to a file, this code is taken directly from the android developer page and then tweaked a bit by me. Is there something i am missing? Quite new to Android development so sorry if it's something blatantly obvious.
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FileOutputStream outputStream;
String data = "hello";
File fileDir = new File("data.txt");
if (!fileDir.exists())
fileDir.mkdirs();
try {
outputStream = openFileOutput("data.txt",Context.MODE_PRIVATE);
outputStream.write(data.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
Basically, your problem is that you are trying to do it twice, once in a way that won't work, and once in a way that will, but hides the result.
File fileDir = new File("data.txt");
if (!fileDir.exists())
fileDir.mkdirs();
This would create a Java File object connected to a hypothetical file called "data.txt" located in the current working directory, which for an Android app is the root directory of the device - a place you most definitely are not allowed to write to. However, this may not obviously cause any errors, as the root directory exists so mkdirs() will do nothing, and you only create a File object, you don't actually try to create a file on "disk". Effectively this code does nothing for you - get rid of it.
Next you try something basically workable:
try {
outputStream = openFileOutput("data.txt",Context.MODE_PRIVATE);
outputStream.write(data.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
openFileOutput() is a method of a Context (Activity or Service) which creates an output stream to write to an actual file located in the private internal storage area of your app. This is all fine and good, and normally a good choice for storing typical data. However, it is not a place that you will be able to examine when running a release app on a secured device, as neither ADB based tools nor Mass Storage or MTP access over USB have rights to it. So it's entirely possible that this code worked, but you had no way to discover that fact. If you are on an emulator, you can access this location with ADB or the DDMS browser, and if your apk is a debug one, you can use the run-as command line tool in the shell.
If you want to share the data, you might consider putting it on the External Storage instead.

Android, What is the right way to write a file to a subdirectory of the data/data/'package' folder

I have been trying for the last couple of days to find the right way of writing a file to a subdirectory of the android data folder.
Most answers i found were not clear or didn't address the problem in a right and working way so i finally decided to ask.
I am giving a user the possibility of backing up his data on my server by basically uploading the database to the server through a php script.
The database is located in
'/data/data/com.package/databases/data.db'
The problem here is when a user wants to reload a backed up database.
The application Downloads the file and should then write it (Overwriting the old one) to the /databases/data.db' file, and then reload.
I have managed to get everything to work up until where i have to write the downloaded file because FileOutputStream throws an illegal argument exception saying that i can't use path separators in the path.
I understand that FileOutputStream can only write to the first level of the data folder and not to subdirectories.
How can this be done?
If it can't be done, is there any way to set the default database path to the first level of the 'data' directory to solve this problem?
If this is a completely wrong approach to what i want to obtain i am open to critique but it would still be nice to get an answer, just for future knowing.
public void aSyncDatabaseDownloadFileFinish(PhpWrapper feed) {
if (validateServerResponse(feed.Result)) {
// Copy Database to Directory
try {
FileOutputStream fos = ctx.openFileOutput(ctx.getDatabasePath(DataDatabaseHelper.DBNAME).getAbsolutePath(),
Context.MODE_PRIVATE);
fos.write(feed.DownloadedBytes, 0, feed.DownloadedBytes.length);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
else
Toast.makeText(ctx, ctx.getResources().getString(R.string.nofilesonserver), Toast.LENGTH_SHORT).show();
}
Thanks in advance.
How can this be done?
In your case, use getDatabasePath() to write a file into the standard location for databases for your app.
Regardless of your path separator issue, openFileOutput() will work with files/ directory in your internal storage, not the databases/ directory.
Ok,
I got the answer thanks to Squonk, Still can't believe that it was that simple.
For anybody having the same problem here is an example:
if (validateServerResponse(feed.Result)) {
// Copy Database to Directory
try {
// This Solved the Exception
FileOutputStream fos = new FileOutputStream(ctx.getDatabasePath(DataDatabaseHelper.DBNAME), true);
fos.write(feed.DownloadedBytes, 0, feed.DownloadedBytes.length);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
else
Toast.makeText(ctx, ctx.getResources().getString(R.string.nofilesonserver), Toast.LENGTH_SHORT).show();
Thank you Squonk!

Check for file existence in androids assets folder?

My app has .txt files in subdirectories in the assets folder. It reads those .txt files and puts them in a textview. It's working great and no problems.
Should I be concerned about the files in the assets folder getting deleted by the user or missing. If this ever could happen, my app would get an error because the file would not be there when it tried to read it into the stream.
Is there a need for me to check the existence of an asset file before I read it or does the asset manager take care of it all? I also was wondering if there's a chance that a user would or could delete and asset file.
Like I say, everything works fine without me inserting code to check for file existence. I just wondered if people use the .exists() statement every time they go to read in a stream from assets.
You may be concerned that the file have been removed and the apk resigned
You can check using:
Arrays.asList(getResources().getAssets().list("")).contains("myFile")
if you really want to check for the file existence:
AssetManager mg = getResources().getAssets();
InputStream is = null;
try {
is = mg.open(pathInAssets);
//File exists so do something with it
} catch (IOException ex) {
//file does not exist
} finally {
if (is != null) {
is.close();
}
}
If your file is located in assets/folder/file.ext, then pathInAssets would be
"folder/file.ext"
Ideally after apk is built, nobody can remove any assets from it, but if someone decompiled it and recompiles than it may be possible.
Though for other scenarios also when an asset is not present in apk at Runtime, we can check the existence of asset.
In our app, we have a provision to build app using gradle, ant and eclipse, and for each build mechanism some of our assets file are bundled in apk and some are not, so to identify if any asset file is present in current build apk at runtime,
we do this as follows:
private boolean isAssetExists(String pathInAssetsDir){
AssetManager assetManager = AppContext.get().getResources().getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open(pathInAssetsDir);
if(null != inputStream ) {
return true;
}
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
Yes and No.
A normal user would not be able to delete them, but a user on a rooted phone who doesn't know what they're doing… that's a different situation.
If you ask me, the extra code is not needed. Also if you try and open a file that doesn't exist, you will get an exception thrown at some point, catch that and display a dialog if you really want to.
AssetManager am = getAssets();
try {
List<String> mapList = Arrays.asList(am.list("path/in/assets/folder"));
if (mapList.contains("file_to_check")) {
Log.e("ERROR", "exists");
} else {
Log.e("ERROR", "not exists");
}
} catch ( IOException ex){
ex.printStackTrace();
}
Convert to function or method can be easy ;)
I think you should be OK. From having a root around in my phone I can't see any way of deleting the assests without deleting the app as it all seems to be wrapped up in the .apk file. You can do it but I think you need to be rooted or use adb.
I would personally surround any reading/writing with a try/catch block anyway, just to be safe.

Categories

Resources