I have been trying to copy a file from one location to another. To my understanding the copying mechanism of my program is working properly, however when I run the app I constantly get a file path error. I happen to be working with the data files within the xbmc app.
AssetManager-->addDefaultAssets CIP path not exsit /data/data/org.xbmc.xbmc/.xbmc/userdata/guisettings.bak: open failed: ENOENT (No such file or directory)
The problem seems to occur when I create File objects for the string paths. Here is the code snippet for that portion of the program:
File inputFile = new File(inputPath);
File outputFile = new File(outputPath);
No matter how I try to access the files, I keep getting the above error. I have tried using the File, FileInputStream, and Uri libraries to get the file paths with no luck. Could I be having issues with write privileges, or am I just not specifying the file paths correctly? I am posting the whole solution just in case the problem lies elsewhere within the code.
public class myActivity extends Activity {
private static final String TAG = "myActivity.java";
//The package name representing the application directory that is to be accessed
String packageName = "org.xbmc.xbmc";
//The input filename to read and copy
String inputFileName = "guisettings.bak";
//The output filename to append to
String outputFileName = "guisettings.xml";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
//Check the status of the external storage
if(isExternalReady()) {
//The external file system is ready
//Start the specific file operation
restoreFile();
} else {
//Not ready. Create a Broadcast Receiver and wait for the filesystem to mount
BroadcastReceiver mExternalInfoReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent intent) {
//The external filesystem is now mounted
//Start the specific file operation
restoreFile();
}
};
//Get the IntentFilter Media Mounted
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
//Specify the filesystem data type
filter.addDataScheme("file");
//Register the receiver as "mExternalInfoReceiver" with the Media Mount filter
registerReceiver(mExternalInfoReceiver, new IntentFilter(filter));
}
}
//Restore the specific xml file
public void restoreFile() {
/*
//Get the internal storage of this app (Android/data/com.website.appname/files/)
String internalStorage = Environment.getFilesDir();
//Get the external storage path now that it is available
String externalStorage = Environment.getExternalStorageDirectory().toString();
//The directory of the file desired
String filePath = "Android/data/org.xbmc.xbmc/files/.xbmc/userdata/";
*/
//The information of the desired package
ApplicationInfo desiredPackage;
//Get the path of the application data folder if the application exists
try {
//Get the info of the desired application package
desiredPackage = getPackageInfo(packageName);
} catch (Exception e) {
//Output the stack trace
e.printStackTrace();
//Stop the function
return;
}
//Get the data dir of the package
String rootPackageDir = desiredPackage.dataDir;
//The path to the file in the package
String packageFilePath = "/.xbmc/userdata/";
//Construct the complete path of the input and output files respectively
//based on the application path
String inputPath = String.format("%s%s%s", rootPackageDir, packageFilePath, inputFileName);
String outputPath = String.format("%s%s%s", rootPackageDir, packageFilePath, outputFileName);
try {
//Copy the input file to the output file
if(copyFile(inputPath, outputPath)) {
//The file has been successfully copied
//Exit the application
System.exit(0);
}
} catch (IOException e) { e.printStackTrace(); return; }
}
//Is the external storage ready?
public boolean isExternalReady() {
//Get the current state of the external storage
//Check if the state retrieved is equal to MOUNTED
Boolean isMounted = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if(isMounted) {
//The external storage is ready
return true;
}
//The external storage is not ready
return false;
}
//Get the data dir of a specific app if it exists
public ApplicationInfo getPackageInfo(String packageName) throws PackageNotFoundException {
List<ApplicationInfo> packages;
PackageManager pm;
//Init the package manager as pm
pm = getPackageManager();
//Get all installed applications
packages = pm.getInstalledApplications(0);
//Get the ApplicationInfo as packageInfo from each packages
for(ApplicationInfo packageInfo:packages) {
//Check for a name that matches the packageName
if(packageInfo.packageName.equals(packageName)) {
//The package exists
return packageInfo;
}
}
//The package was not found
//Throw an exception
throw new PackageNotFoundException("Package not found");
}
//Copy a file from an input directory to an output directory
public boolean copyFile(String inputPath, String outputPath) throws IOException {
//Construct the input and output paths as File objects with respective read/write privileges
//File inputFile = new File("/data/data/org.xbmc.xbmc/files/.xbmc/userdata/guisettings.bak");
//File outputFile = new File("/data/data/org.xbmc.xbmc/files/.xbmc/userdata/guisettings.xml");
//File inputFile = getDir(inputPath, MODE_PRIVATE);
//File outputFile = getDir(outputPath, MODE_PRIVATE);
File inputFile = new File(inputPath);
File outputFile = new File(outputPath);
//Check if the input and output files exist
if(!inputFile.exists()) {
return false;
}
if(!outputFile.exists()) {
//Create the output file
new File(outputPath);
}
//Get the input read state
boolean canReadInput = inputFile.canRead();
//Get the output write state
boolean canWriteOutput = outputFile.canWrite();
//Check if the input file can be read and if the output file can be written
if(canReadInput && canWriteOutput) {
//Open respective input and output buffer streams
InputStream in = new FileInputStream(inputFile);
OutputStream out = new FileOutputStream(outputFile);
//Create a byte array
byte[] buffer = new byte[1024];
//The current position of the byte buffer
int bufferPosition;
//While the bufferPosition is reading the file 1024 bytes at a time (-1 = no longer reading)
while((bufferPosition = in.read(buffer)) != -1) {
//Append the current buffer in memory to the output file
//With a pointer offset of 0 and a count of the current bufferPosition
out.write(buffer, 0, bufferPosition);
}
//Close the file streams
in.close();
out.close();
return true;
}
return false;
}
//The Package Error Class
private class PackageNotFoundException extends Exception {
//If an error is thrown with a message parameter
PackageNotFoundException(String m) {
//Pass the message to the super Exception class
super(m);
}
}
}
It turns out that my android device was having some issues connecting to my computer, hence the CIP Error.
After switching to another device, I also discovered that the input file itself was not being found, as I was trying to access the it through the "data/data" directory. The app data directories for installed apps can only be accessed through the external storage path. Since this varies from device to device, it needs to be retrieved dynamically.
Environment.getExternalStorageDirectory().getAbsolutePath();
After accessing the file this way I was able to successfully copy it.