Reputation: 970
Bundle bundle;
//set data to bundle
//......
File file = new File(context.getFilesDir().getAbsolutePath() + "/data/");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
//fos.write
fos.close();
} catch (FileNotFoundException exp1) {
exp1.printStackTrace();
} catch ( IOException exp2) {
exp2.printStackTrace();
}
I have the aforementioned code. All I want to do is to save the bundle to the file. I found the method write but I can't pass there a bundle but only a byte[].I tried to convert the bundle to byte[] but I didn't succeed it. What Should I do to make this work? What is the most efficient way?
Upvotes: 6
Views: 10280
Reputation: 635
I thing the best idea is static serializable or everything, as Bundle is iterable from keys, serialized and unserialized on another side, you can use then json, or anything. For example, if You will use the same class in server and receiver, ...
bundle->serializable_object->json->file->serializable_object->bundle
any os version guaranted working
Upvotes: 0
Reputation: 1479
You cannot save a bundle in to local file. You will get Non Serialization Exception. There may be other shortcuts to store. After reading and constructing the original object is not 100% assured.
Upvotes: 0
Reputation: 10255
Here are function that can help you convert a Bundle
to a JSONObject
, note that it will only work if the bundle contains int
s and String
s only
public static JSONObject bundleToJsonObject(Bundle bundle) {
try {
JSONObject output = new JSONObject();
for( String key : bundle.keySet() ){
Object object = bundle.get(key);
if(object instanceof Integer || object instanceof String)
output.put(key, object);
else
throw new RuntimeException("only Integer and String can be extracted");
}
return output;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
public static Bundle JsonObjectToBundle(JSONObject jsonObject) {
try {
Bundle bundle = new Bundle();
Iterator<?> keys = jsonObject.keys();
while( keys.hasNext() ){
String key = (String)keys.next();
Object object = jsonObject.get(key);
if(object instanceof String)
bundle.putString(key, (String) object);
else if(object instanceof Integer)
bundle.putInt(key, (Integer) object);
else
throw new RuntimeException("only Integer and String can be re-extracted");
}
return bundle;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
Upvotes: 1
Reputation: 116
I didn't like the formatting of the code in my comment above, so this is how you would read it back out:
Read it like this:
try {
FileInputStream fis = openFileInput(localFilename);
byte[] array = new byte[(int) fis.getChannel().size()];
fis.read(array, 0, array.length);
fis.close();
parcel.unmarshall(array, 0, array.length);
parcel.setDataPosition(0);
Bundle out = parcel.readBundle();
out.putAll(out);
} catch (FileNotFoundException fnfe) {
} catch (IOException ioe) {
} finally {
parcel.recycle();
}
Upvotes: 4
Reputation: 3417
Bundle in=yourBundle;
FileOutputStream fos = context.openFileOutput(localFilename, Context.MODE_PRIVATE);
Parcel p = Parcel.obtain(); //creating empty parcel object
in.writeToParcel(p, 0); //saving bundle as parcel
fos.write(p.marshall()); //writing parcel to file
fos.flush();
fos.close();
Upvotes: 3
Reputation: 10518
There is no general way to save and restore bundle from persistent storage. This is because Parcel class doesn't give any android version compatibility guarantee. So we better not serialize it.
But if you really want you can searialize Bundle via Parceable interface. Convert bundle to a Parcel (writeToParcel()/readFromParcel()), then use Parcel's marshall() and unmarshall() methods to get a byte[]. Save/Load byte Array to file. But there is a chance, that one day you wont be able to restore your data in case user updates his Android OS to a newer version.
There is one legal but very paifull and unreliable way to serialize bundle using ObjectOutput/InputStream. (get all keys, iterate through keys and save serializable key=value pairs to a file, then read key=value pair from file, determine value's type, put data back in Bundle via appropriate putXXX(key, value) method) But it is not worth it )
I suggest you to put your custom serializable structure in Bundle to store all required values in it and save/load from file only this structure.
Or find a better way to manage your data without using Bundle.
Upvotes: 5
Reputation: 15424
You could do something like this
public void write(String fileName, Bundle bundle)
{
File root = Environment.getExternalStorageDirectory();
File outDir = new File(root.getAbsolutePath() + File.separator + "My Bundle");
if (!outDir.isDirectory())
{
outDir.mkdir();
}
try
{
if (!outDir.isDirectory())
{
throw new IOException("Unable to create directory My bundle. Maybe the SD card is mounted?");
}
File outputFile = new File(outDir, fileName);
writer = new BufferedWriter(new FileWriter(outputFile));
String value=bundle.getString("key");
writer.write(value);
Toast.makeText(context.getApplicationContext(), "Report successfully saved to: " + outputFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
writer.close();
} catch (IOException e)
{
Log.w("error", e.getMessage(), e);
Toast.makeText(context, e.getMessage() + " Unable to write to external storage.", Toast.LENGTH_LONG).show();
}
}
Here, the idea is simple. You pass the Bundle
to this method and then extract whatever data you have in that (Example in this case we have a string with the key key
) and then write that to a file.
Upvotes: 0