OSMdroid change Tiles cache in storage - android

Sorry for my bad English, i have a question. I'm new in android and don't know how to do this.
How can i modify OSMdroid 4.2 jar file codes in my project?
I added these jar files as library to my project. My app in 3 languages. I have tile source for every language. When I select language, program selects a tile source with the same language. But when i zoom map, automatically language changes in map. I don't know why it do this. I think it depends on tiles cach in storage.
Is there any way to change tile cache in storage for every language individually?
Thanks! :)

See: https://github.com/osmdroid/osmdroid/issues/78
This is the same issue (OSMDROID_PATH and TILE_PATH_BASE hardcoded and final).
Using this patch (potentially old version below), you could change the tile cache path as needed.
package org.osmdroid.tileprovider.constants;
import java.io.File;
import android.os.Environment;
/**
* This class contains key settings related to the osmdroid cache, and methods to change default values.
*/
public class TilesCacheSettings {
/** Base path for osmdroid files. Zip files are in this folder. */
public static File OSMDROID_PATH = new File(Environment.getExternalStorageDirectory(),
"osmdroid");
/** Base path for tiles. */
public static File TILE_PATH_BASE = new File(OSMDROID_PATH, "tiles");
/** 600 Mb */
public static long TILE_MAX_CACHE_SIZE_BYTES = 600L * 1024 * 1024;
/** 500 Mb */
public static long TILE_TRIM_CACHE_SIZE_BYTES = 500L * 1024 * 1024;
/** Change the root path of the osmdroid cache.
* By default, it is defined in SD card, osmdroid directory.
* #param newFullPath
*/
public static void setCachePath(String newFullPath){
OSMDROID_PATH = new File(newFullPath);
TILE_PATH_BASE = new File(OSMDROID_PATH, "tiles");
}
/** Change the osmdroid tiles cache sizes
* #param maxCacheSize in Mb. Default is 600 Mb.
* #param trimCacheSize When the cache size exceeds maxCacheSize, tiles will be automatically removed to reach this target. In Mb. Default is 500 Mb.
*/
public static void setCacheSizes(long maxCacheSize, long trimCacheSize){
TILE_MAX_CACHE_SIZE_BYTES = maxCacheSize * 1024 * 1024;
TILE_TRIM_CACHE_SIZE_BYTES = trimCacheSize * 1024 * 1024;
}
}

Only add the following code in your
OpenStreetMapTileProviderConstants.setCachePath(this.getFilesDir().getAbsolutePath());
or
OpenStreetMapTileProviderConstants.setCachePath("other path");

Related

Azure blob storage - Copy Block blobs in the SAME container

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 */);
}

Android issue creating direcory under data directoy

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;

Using muPDF with curl/flip effect

I'm using muPDF for reading PDFs in my application. I don't like its default animation (Switching horizontally). In other side i found this brilliant library for curl effect on images, and this project for flip-flap effect on layouts.
In curl sample project, in CurlActivity, all of data are images and set in PageProvider like this:
private class PageProvider implements CurlView.PageProvider {
// Bitmap resources.
private int[] mBitmapIds = { R.drawable.image1, R.drawable.image2,
R.drawable.image3, R.drawable.image4};
And use it like this:
private CurlView mCurlView;
mCurlView = (CurlView) findViewById(R.id.curl);
mCurlView.setPageProvider(new PageProvider());
And CurlView extends from GLSurfaceView and implements View.OnTouchListener, CurlRenderer.Observer
But in muPDF if i'm not mistaken, data are in core object. core is instance of MuPDFCore. And using it like this:
MuPDFReaderView mDocView;
MuPDFView pageView = (MuPDFView) mDocView.getDisplayedView();
mDocView.setAdapter(new MuPDFPageAdapter(this, this, core));
MuPDFReaderView extends ReaderView and ReaderView extends AdapterView<Adapter> and implements GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener, Runnable.
My question is where how can I using curl effect in muPDF? Where should I get pages one by one and converting them to bitmaps? and then changing aspects of the Adapter in muPDF to CurlView.
In flip-flap sample project, in FlipHorizontalLayoutActivity (I like this effect too), we have these:
private FlipViewController flipView;
flipView = new FlipViewController(this, FlipViewController.HORIZONTAL);
flipView.setAdapter(new TravelAdapter(this));
setContentView(flipView);
And FlipViewController extends AdapterView<Adapter>, and data set in TravelAdapter that extends BaseAdapter.
No one has done this before? Or can help me to do that?!
EDIT:
I found another good open source PDF reader with curl effect called fbreaderJ. its developer says "An additional module that allows to open PDF files in FBReader. Based on radaee pdf library."
I got confused! cause radaeepdf is closed source and downloadable project is just for demo and inserted username and password is for this package.
People want to change whole fbreader project such as package name.
Another issue for make me confused is where is this additional module source code?!
Anyway, if someone wants to help me, fbreader has done it very well.
EDIT:
I talked to Robin Watts, who developed muPDF (or one of developers), and he said:
Have you read platform/android/ClassStructure.txt ? MuPDF is
primarily a C library. The standard api is therefore a C one. Rather
than exposing that api exactly as is to Java (which would be the
nicest solution, and something that I've done some work on, but have
not completed due to lack of time), we've implemented MuPDFCore to
wrap up just the bits we needed. MuPDFCore handles opening a PDF file,
and getting bitmaps from it to be used in views. or rather, MuPDFCore
returns 'views', not 'bitmaps'. If you need bitmaps, then you're going
to need to make changes in MuPDFCore.
There are too many errors when changing a little part of MuPDFReaderView class. I get confused! These are related to each other.
Please answer more precisely.
EDIT:
And bounty has expired.
If the muPDF does not support rendering to a bitmap, you have no other choice than rendering to a regular view and take a screen dump to a bitmap like this:
View content = findViewById(R.id.yourPdfView);
Bitmap bitmap = content.getDrawingCache();
Then use this bitmap as input to your other library.
Where should i get pages one by one and converting them to bitmaps?
In our application (newspaper app) we use MuPDF to render PDFs.
The workflow goes like this:
Download PDF file (we have one PDF per newspaper page)
Render it with MuPDF
Save the bitmap to the filesystem
Load the Bitmap from filesystem as background image to a view
So, finally, what we use is MuPDFCore.java and its methods drawPage(...) and onDestroy()
Is this what you want to know or do i miss the point?
EDIT
1.) I think it is not necessary to post code how to download a file. But after downloading i add a RenderTask (extends from Runnable) to a Renderqueue and trigger that queue. The RenderTask needs some information for rendering:
/**
* constructs a new RenderTask instance
* #param context: you need Context for MuPdfCore instance
* #param pageNumber
* #param pathToPdf
* #param renderCallback: callback to set bitmap to the view after
* rendering
* #param heightOfRenderedBitmap: this is the target height
* #param widthOfRenderedBitmap: this is the target width
*/
public RenderTask (Context context, Integer pageNumber, String pathToPdf, IRenderCallback,
renderCallback, int heightOfRenderedBitmap,
int widthOfRenderedBitmap) {
//store things in fields
}
2.) + 3.) The Renderqueue wraps the RenderTask in a new Thread and starts it. So the run-method of the RenderTask will be invoked:
#Override
public void run () {
//do not render it if file exists
if (exists () == true) {
finish();
return;
}
Bitmap bitmap = render();
//if something went wrong, we can't store the bitmap
if (bitmap == null) {
finish();
return;
}
//now save the bitmap
// in my case i save the destination path in a String field
imagePath = save(bitmap, new File("path/to/your/destination/folder/" + pageNumber + ".jpg"));
bitmap.recycle();
finish();
}
/**
* let's trigger the callback
*/
private void finish () {
if (renderCallback != null) {
// i send the whole Rendertask to callback
// maybe in your case it is enough to send the pageNumber or path to
// renderend bitmap
renderCallback.finished(this);
}
}
/**
* renders a bitmap
* #return
*/
private Bitmap render() {
MuPDFCore core = null;
try {
core = new MuPDFCore(context, pathToPdf);
} catch (Exception e) {
return null;
}
Bitmap bm = Bitmap.createBitmap(widthOfRenderedBitmap, heightOfRenderedBitmap, Config.ARGB_8888);
// here you render the WHOLE pdf cause patch-x/-y == 0
core.drawPage(bm, 0, widthOfRenderedBitmap, heightOfRenderedBitmap, 0, 0, widthOfRenderedBitmap, heightOfRenderedBitmap, core.new Cookie());
core.onDestroy();
core = null;
return bm;
}
/**
* saves bitmap to filesystem
* #param bitmap
* #param image
* #return
*/
private String save(Bitmap bitmap, File image) {
FileOutputStream out = null;
try {
out = new FileOutputStream(image.getAbsolutePath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
return image.getAbsolutePath();
} catch (Exception e) {
return null;
}
finally {
try {
if (out != null) {
out.close();
}
} catch(Throwable ignore) {}
}
}
}
4.) I think it is not necessary to post code how to set a bitmap as background of a view

java.lang.NoClassDefFoundError on API level 11

I am facing an error whilst using API level 11.
My app crashes with the following: java.lang.NoClassDefFoundError: com.question.question.BitmapCache only when I use my app with a device running api level 11:
I have Google'd this ofcourse and have tried every solution I have came across but still no luck.
Here is the line where it says there's a problem with in Logcat:
public GoogleCardsAdapter(final Context context) {
mContext = context;
mMemoryCache = new BitmapCache(); //<---- This line here
}
Here's the bitmap cache class:
public class BitmapCache extends LruCache<Integer, Bitmap> {
private static final int KILO = 1024;
private static final int MEMORY_FACTOR = 2 * KILO;
public BitmapCache() {
super((int) (Runtime.getRuntime().maxMemory() / MEMORY_FACTOR));
}
#Override
protected int sizeOf(final Integer key, final Bitmap value) {
return value.getRowBytes() * value.getHeight() / KILO;
}
}
I am using a few libs as well:
If anyone knows what is going wrong here, that would be much appreciated.
Presumably, you are trying to use android.util.LruCache, which only exists in API Level 12 and above.
Consider switching to android.support.v4.util.LruCache from the Android Support package, which will work going back to API Level 4.
Also, please undo your manual modifications of your build path, and copy the Picasso and ListViewAnimations JARs into your project's libs/ directory, so the JARs are on both your build path and packaged into the APK for distribution.

Common simple data storage interface for Android, J2ME and PC

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
:)

Categories

Resources