I'm using Azure Storage with the Android API. I'm trying to copy one block blob from one location to another (in the SAME blob container).
However, when I make the copy I get a "CannotVerifyCopySource" error after invoking the startCopy method.
Example Code:
private void sample(String path1, String path2, File file) {
CloudBlockBlob blob1 = container.getBlockBlobReference(path1);
CloudBlockBlob blob2 = container.getBlockBlobReference(path2);
blob1.upload(new FileInputStream(file), file.length());
blob1.startCopy(blob2);
}
Any ideas on what might be the problem?
Best regards,
see source about startCopy below. I think you should use blob2.startCopy(blob1) here.
/**
* Requests the service to start copying a block blob's contents, properties, and metadata to a new block blob.
*
* #param sourceBlob
* A <code>CloudBlockBlob</code> object that represents the source blob to copy.
*
* #return A <code>String</code> which represents the copy ID associated with the copy operation.
*
* #throws StorageException
* If a storage service error occurred.
* #throws URISyntaxException
*/
#DoesServiceRequest
public final String startCopy(final CloudBlockBlob sourceBlob) throws StorageException, URISyntaxException {
return this.startCopy(sourceBlob, null /* sourceAccessCondition */,
null /* destinationAccessCondition */, null /* options */, null /* opContext */);
}
Related
I am using this code (android-sqlite-asset-helper) to load a database from a file place in the asset folder. This works great.
However, the processing of refreshing/upgrading the database is not simple, and I am wondering if there is a simple way to manually remove all data from the databases in the app; in order to load a new database from the asset file.
You can use simple copy file to override data in default database. Simply by overwriting default database with your new database file.
The following code work only with a file, so you need a little change here and there to make it work with asset file.
Here the method to overwrite the database file:
/**
* Copies the database file at the specified location over the current
* internal application database.
**/
public boolean importDatabase(Context context, String dbPath) throws IOException {
File OldDbFile = context.getApplicationContext().getDatabasePath(DBSchema.DATABASE_NAME);
// Close the SQLiteOpenHelper so it will commit the created empty
// database to internal storage.
close();
File newDb = new File(dbPath);
if (newDb.exists()) {
FileUtils.copyFile(new FileInputStream(newDb), new FileOutputStream(OldDbFile));
// Access the copied database so SQLiteHelper will cache it and mark
// it as created.
getWritableDatabase().close();
return true;
}
return false;
}
FileUtils class:
public class FileUtils {
/**
* Creates the specified <code>toFile</code> as a byte for byte copy of the
* <code>fromFile</code>. If <code>toFile</code> already exists, then it
* will be replaced with a copy of <code>fromFile</code>. The name and path
* of <code>toFile</code> will be that of <code>toFile</code>.<br/>
* <br/>
* <i> Note: <code>fromFile</code> and <code>toFile</code> will be closed by
* this function.</i>
*
* #param fromFile - FileInputStream for the file to copy from.
* #param toFile - FileInputStream for the file to copy to.
*/
public static void copyFile(FileInputStream fromFile, FileOutputStream toFile)
throws IOException {
FileChannel fromChannel = null;
FileChannel toChannel = null;
try {
fromChannel = fromFile.getChannel();
toChannel = toFile.getChannel();
fromChannel.transferTo(0, fromChannel.size(), toChannel);
} finally {
try {
if (fromChannel != null) {
fromChannel.close();
}
} finally {
if (toChannel != null) {
toChannel.close();
}
}
}
}
}
I really forget where I took the copyFile method :(.
There is one caveat: when user cleaning app data, the database will be back to default.
It seems to work with this in the main activity creation:
getApplicationContext().deleteDatabase("mydatabase.db");
I am trying to create /data/data/package name/files directory to put my preloaded realm file as part of application start up. But the directory is not creating at all. I am not sure what mistake I am making, please point out
public class GlobalDataAccess: Application() {
val TAG = "GlobalDataAccess"
override fun onCreate() {
super.onCreate()
copyRealmFile();
}
private fun copyRealmFile() {
val filePath = Environment.getDataDirectory().getAbsolutePath()
Log.d(TAG,"**************************************************************************************************************File path =>"+filePath)
val file = File(filePath, "data/"+getPackageName()+"/files")
if(file.exists())
file.delete()
file.mkdirs()
}
}
My Manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:name=".application.GlobalDataAccess"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
Don't hardcode your path. Instead use context to get your application package.
via:
http://developer.android.com/reference/android/content/Context.html#getFilesDir()
Details
You don't have access to
data/<mypackage>/files
You do however; have access to
data/data/<mypackage>/files
Which when you use Context.getFilesDir() will return your context package in data/data/
Avoid hardcoding if you don't know the path. Depend on what is reliable for your usecase.
It seems you want to create files in app's private data directory rather than SD card.
You can use this method to open a FileOutputStream in your app's data directory.
/**
* Open a private file associated with this Context's application package
* for writing. Creates the file if it doesn't already exist.
*
* #param name The name of the file to open; can not contain path
* separators.
* #param mode Operating mode. Use 0 or {#link #MODE_PRIVATE} for the
* default operation, {#link #MODE_APPEND} to append to an existing file,
* {#link #MODE_WORLD_READABLE} and {#link #MODE_WORLD_WRITEABLE} to control
* permissions.
*
* #return FileOutputStream Resulting output stream.
*
* #see #MODE_APPEND
* #see #MODE_PRIVATE
* #see #MODE_WORLD_READABLE
* #see #MODE_WORLD_WRITEABLE
* #see #openFileInput
* #see #fileList
* #see #deleteFile
* #see java.io.FileOutputStream#FileOutputStream(String)
*/
public abstract FileOutputStream openFileOutput(String name, int mode)
throws FileNotFoundException;
I am using the open source library: https://code.google.com/p/flickrj-android/ and there is an example how do I get photos from flickr. Main problem is that I get only public photos. How can I manage getting private streams/photos?
Did anyone managed to get private streams?
With Flickrj-android you'd want to use this method:
Flickr flickr = new Flickr(API_KEY,SHARED_SECRET,new REST());
Set<String> extras = new HashSet();
// A set of extra info we want Flickr to give back. Go to the API page to see the other size options available.
extras.add("url_o");
extras.add("original_format");
//A request for a list of the photos in a set. The first zero is the privacy filter,
// the second is the Pages, and the third is the Per-Page (see the Flickr API)
PhotoList<Photo> photoList = flickr.getPhotosetsInterface().getPhotos(PHOTOSET_ID, extras, 0, 0, 0);
//We'll use the direct URL to the original size of the photo in order to download it. Remember: you want to make as few requests from flickr as possible!
for(Photo photo : photoList){
//You can also get other sizes. Just ask for the info in the first request.
URL url = new URL(photo.getOriginalSize().getSource());
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(PATH_OF_FOLDER + photo.getTitle() + "." + photo.getOriginalFormat());
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
}
Use this method for a single-photo inputstream.
InputStream inputStream = flickr.getPhotosInterface().getImageAsStream(flickr.getPhotosInterface().getPhoto(PHOTO_ID), Size.ORIGINAL);
I'm not very familiar with Java and that framework but will try to help.
I found next method name in that framework:
public class PeopleInterface {
public static final String METHOD_GET_PHOTOS = "flickr.people.getPhotos";
/**
* Returns photos from the given user's photostream. Only photos visible the
* calling user will be returned. this method must be authenticated.
*
* #param userId
* #param extras
* #param perpage
* #param page
* #return
* #throws IOException
* #throws FlickrException
* #throws JSONException
*/
public PhotoList getPhotos(String userId, Set<String> extras, int perPage,
int page)
From Flick API docs I found next:
flickr.people.getPhotos Return photos from the given user's photostream. Only photos visible to the calling user will be returned.
This method must be authenticated; to return public photos for a user,
use flickr.people.getPublicPhotos.
So, it mean that you must be authenticated with 'read' permissions to get your private pohotos (your account).
You can also get private photos of some users only in case if you are contact/friend of that user.
I'm developing an app with google drive and I can see my files with these app. I want to download the files, but I can't.
This is my function, is equal to google documentation:
Thanks un advance!!
/* Download a file's content.
*
* #param service Drive API service instance.
* #param file Drive File instance.
*
* #return InputStream containing the file's content if successful, {#code null} otherwise.
*/
public static InputStream downloadFile(Drive service, File file) throws IOException
{
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0)
{
try
{
HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
return resp.getContent();
}
catch (IOException e)
{
// An error occurred.
e.printStackTrace();
return null;
}
}
else
{
// The file doesn't have any content stored on Drive.
return null;
}
}
No errors in Logcat, but I don't see any file in downloads, sd-card, etc
If there isn't error, I have to see very carefull in sd-card, system etc?
it's necessarely anything else??
You are getting the file content and returning an InputStream however your code doesn't show what you are doing with this InputStream. You need to use it to save the content of the file to Disk or database etc... Please have a look at the link that FaddishWorm sent you in comments which writes the file to the SD Card: Download a file with Android, and showing the progress in a ProgressDialog
I have read many questions about Android, J2ME and RecordStore, but I still can't find the answer that could satisfy me.
I need to implement low-level part of my Java app that should work on different platforms, right now this is Android and J2ME, and in future it should work on PC too. I need to store simple data sets, that is almost similar to RecordStore in J2ME:
App should own several record stores with records, each record has:
the id (but it should be "my" id, not auto-returned one as it is in RecordStore),
the data (just a byte array).
I think I should write an Interface with needed methods, and each platform should have its own implementation of this Interface.
But this task seems to be very common (at least, for Android + J2ME), so, maybe there already is some lightweight implementation? I'm asking just because I don't like to re-invent the wheel.
And maybe some suggestions?
So, I wrote interface that does satisfy my requirements, with two implementations: for Android and J2ME.
Here is how does Interface look:
public interface ISDataStore {
/**
* Get number of records in data store.
*/
public int getNumRecords() throws SDataStoreException;
/**
* Get size of one record with specified id in bytes.
*
* #param record_id id of the record
*/
public int getRecordSize(int record_id) throws SDataStoreException;
/**
* Get record.
*
* #param record_id id of the record to read
* #param data byte array where to put the data
* #param offset offset in 'data' array from which should start to copy
*/
public void getRecord(int record_id, byte[] data, int offset) throws SDataStoreException;
/**
* Get record.
*
* #param record_id id of the record to read
*/
public byte[] getRecord(int record_id) throws SDataStoreException;
/**
* Resolves is record with specified id exists or not.
*
* #param record_id id of the record
* #return true if record exists, otherwise false
*/
public boolean isRecordExists(int record_id) throws SDataStoreException;
/**
* Put new record or update existing one.
*
* #param record_id id of the record
* #param data byte array of data
* #param offset offset in the data byte array
* #param length number of bytes to store
*
* #return true if operation was successful, otherwise false
*
*/
public boolean setRecord(int record_id, byte[] data, int offset, int length) throws SDataStoreException;
/**
* Delete the record.
*
* #param record_id id of the record
*
* #return true if operation was successful, otherwise false
*/
public boolean deleteRecord(int record_id) throws SDataStoreException;
/**
* Clear all the records.
*/
public void deleteAll() throws SDataStoreException;
/**
* Close the data store.
*/
public void close() throws SDataStoreException;
}
There is also a factory for data stores:
public interface ISDataStoreFactory {
/**
* #param dataStoreId id of the data store
* #return ISDataStore with given id. Type of this id depends on target platform
*/
public ISDataStore getDataStore(Object dataStoreId) throws SDataStoreException;
/**
* Destroys data store with given id.
* #param dataStoreId id of the data store. Type of this id depends on target platform
*/
public void destroyDataStore(Object dataStoreId) throws SDataStoreException;
}
Docs auto-generated by Doxygen can be found here.
Mercurial repository with Interface and all the implementations can be found here.
How do I use it:
As I already said in my question, I have app for Android and app for J2ME, both these apps does the similar thing. (if anyone interested, they does communication via bluetooth with remote embedded device)
Both apps have common low-level part that does the main job.
I have interface IMainApp, something like that:
public interface IMainApp {
public ISDataStoreFactory getDataStoreFactory();
/*
* ... some other methods
*/
}
Both apps (for Android and for J2ME) have its own implementations of this interface, and they pass its reference to the low-level part. When low-level part wants to open some data store, it uses ISDataStoreFactory returned by IMainApp.getDataStoreFactory. It works just like I want it to work.
Hope it is useful for anyone.
Am shou you what i did
create profiles .. that are values i want to store in the database
Sample profile
public class NewsProfile {
public String uniqid = "", category = "", title = "" ;
public NewsProfile(String uniqid) {
this.uniqid = uniqid;
}
}
Create a News store that accept New Profile
public void saveProfile(int id, NewsProfile profile) {
try {
if (rs != null) {
profile.id = id;
byte[] bytes = toByteArray(profile);
setRecord(profile.id, bytes);
System.err.println("Exists = " + profile.catKey + String.valueOf(profile.status));
}
} catch (Exception e) {
System.err.println("ERROR: saveUpdateProfile" + e.getMessage());
}
}
public NewsProfile getProfileint id) throws RecordStoreException, IOException {
byte[] bytes = rs.getRecord(id);
DataInputStream is = new DataInputStream(new ByteArrayInputStream(bytes));
String uniqid = is.readUTF();
OptionsProfile profile = new NewsProfile (uniqid);
profile.id = id;
profile.catKey = uniqid;
profile.category = is.readUTF();
profile.title = is.readUTF();
return profile;
}
private byte[] toByteArray(NewsProfile profile) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream os = new DataOutputStream(baos);
os.writeUTF(profile.uniqid);
os.writeUTF(profile.category);
os.writeUTF(profile.title);
return baos.toByteArray();
}
What this means is that anytime i want to save data to a database .... what am saving at any point in time is NewsProfile .... You can not implement for different storage you want .. SQLite , RMS , even Web Service
Thanks
:)