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;
Related
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 */);
}
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");
Can someone provide an example of how to use the new AlwaysOnHotwordDetector class in Android?
I'd like to build an app, that when the app is running in the background, can detect a hotword like "next", or "back", or "pause".
Unless I have a huge blind spot, I don't think third-party applications can make use of this API. Its strange that AlwaysOnHotwordDetector (and related classes VoiceInteractionService etc.) have been granted public access.
If you are building a privileged app, look through these test projects from AOSP:
Voice Interaction - Basic AlwaysOnHotwordDetector usage/implementation
http://androidxref.com/5.0.0_r2/xref/frameworks/base/tests/VoiceInteraction/
Voice Enrollment - http://androidxref.com/5.0.0_r2/xref/frameworks/base/tests/VoiceEnrollment/
While trying to make this work, I came upon this:
AlwaysOnHotwordDetector's constructor:
/**
* #param text The keyphrase text to get the detector for.
* #param locale The java locale for the detector.
* #param callback A non-null Callback for receiving the recognition events.
* #param voiceInteractionService The current voice interaction service.
* #param modelManagementService A service that allows management of sound models.
*
* #hide
*/
public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
IVoiceInteractionService voiceInteractionService,
IVoiceInteractionManagerService modelManagementService) {
mText = text;
mLocale = locale;
mKeyphraseEnrollmentInfo = keyphraseEnrollmentInfo;
mKeyphraseMetadata = mKeyphraseEnrollmentInfo.getKeyphraseMetadata(text, locale);
mExternalCallback = callback;
mHandler = new MyHandler();
mInternalCallback = new SoundTriggerListener(mHandler);
mVoiceInteractionService = voiceInteractionService;
mModelManagementService = modelManagementService;
new RefreshAvailabiltyTask().execute();
}
The statement of interest here is:
mKeyphraseMetadata = mKeyphraseEnrollmentInfo.getKeyphraseMetadata(text, locale);
What does KeyphraseEnrollmentInfo#getKeyphraseMetadata(String, Locale) do?
/**
* Gets the {#link KeyphraseMetadata} for the given keyphrase and locale, null if any metadata
* isn't available for the given combination.
*
* #param keyphrase The keyphrase that the user needs to be enrolled to.
* #param locale The locale for which the enrollment needs to be performed.
* This is a Java locale, for example "en_US".
* #return The metadata, if the enrollment client supports the given keyphrase
* and locale, null otherwise.
*/
public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, Locale locale) {
if (mKeyphrases == null || mKeyphrases.length == 0) {
Slog.w(TAG, "Enrollment application doesn't support keyphrases");
return null;
}
for (KeyphraseMetadata keyphraseMetadata : mKeyphrases) {
// Check if the given keyphrase is supported in the locale provided by
// the enrollment application.
if (keyphraseMetadata.supportsPhrase(keyphrase)
&& keyphraseMetadata.supportsLocale(locale)) {
return keyphraseMetadata;
}
}
Slog.w(TAG, "Enrollment application doesn't support the given keyphrase/locale");
return null;
}
At this point, my example project kept telling me: Enrollment application doesn't support keyphrases. So, digging a bit further - to support keyphrases, we need to provide additional meta-data:
// Taken from class KeyphraseEnrollmentInfo
/**
* Name under which a Hotword enrollment component publishes information about itself.
* This meta-data should reference an XML resource containing a
* <code><{#link
* android.R.styleable#VoiceEnrollmentApplication
* voice-enrollment-application}></code> tag.
*/
private static final String VOICE_KEYPHRASE_META_DATA = "android.voice_enrollment";
Additionally, we will need the android.permission.MANAGE_VOICE_KEYPHRASES permission. This is where the example project gets stuck:
<!-- Must be required by hotword enrollment application,
to ensure that only the system can interact with it.
#hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES"
android:label="#string/permlab_manageVoiceKeyphrases"
android:description="#string/permdesc_manageVoiceKeyphrases"
android:protectionLevel="signature|system" />
The permission required to support hotword detection is not available to third-party applications. I still can't figure out why package android.service.voice package has public access. Perhaps I am missing something here.
I got several UIDs like this:
10022, 10011, 1000
Actually I know the user names of them are u0_a22, u0_a11, system.
But the question is, how can I get the user name using UIDs? There is no /etc/passwd file at all.
I wrote a utility class to get the UID/GID name by hardcoding values from android_filesystem_config.h.
Usage:
String uid = AndroidFilesystemConfig.getNameForId(1000);
AndroidFilesystemConfig.java
import android.os.Build;
import android.util.SparseArray;
import java.util.Locale;
/**
* <p>System Users and Groups for the Android platform as specified in
* android_filesystem_config.h.</p>
*
* <p>Last updated: April 20th, 2016</p>
*
* <p><b>Note:</b> Some OEMs may have specific UIDs for other system users not in this class.</p>
*/
public class AndroidFilesystemConfig {
/* first app user */
private static final int AID_APP = 10000;
/* offset for uid ranges for each user */
private static final int AID_USER = 100000;
/* start of gids for apps in each user to share */
private static final int AID_SHARED_GID_START = 50000;
/* end of gids for apps in each user to share */
private static final int AID_SHARED_GID_END = 59999;
private static final SparseArray<String> SYSTEM_IDS = new SparseArray<>();
static {
putSystemId(0, "root"); /* traditional unix root user */
putSystemId(1000, "system"); /* system server */
putSystemId(1001, "radio"); /* telephony subsystem, RIL */
putSystemId(1002, "bluetooth"); /* bluetooth subsystem */
putSystemId(1003, "graphics"); /* graphics devices */
putSystemId(1004, "input"); /* input devices */
putSystemId(1005, "audio"); /* audio devices */
putSystemId(1006, "camera"); /* camera devices */
putSystemId(1007, "log"); /* log devices */
putSystemId(1008, "compass"); /* compass device */
putSystemId(1009, "mount"); /* mountd socket */
putSystemId(1010, "wifi"); /* wifi subsystem */
putSystemId(1011, "adb"); /* android debug bridge (adbd) */
putSystemId(1012, "install"); /* group for installing packages */
putSystemId(1013, "media"); /* mediaserver process */
putSystemId(1014, "dhcp"); /* dhcp client */
putSystemId(1015, "sdcard_rw"); /* external storage write access */
putSystemId(1016, "vpn"); /* vpn system */
putSystemId(1017, "keystore"); /* keystore subsystem */
putSystemId(1018, "usb"); /* USB devices */
putSystemId(1019, "drm"); /* DRM server */
putSystemId(1020, "mdnsr"); /* MulticastDNSResponder (service discovery) */
putSystemId(1021, "gps"); /* GPS daemon */
// 1022 is deprecated and not used.
putSystemId(1023, "media_rw"); /* internal media storage write access */
putSystemId(1024, "mtp"); /* MTP USB driver access */
// 1025 is deprecated and not used.
putSystemId(1026, "drmrpc"); /* group for drm rpc */
putSystemId(1027, "nfc"); /* nfc subsystem */
putSystemId(1028, "sdcard_r"); /* external storage read access */
putSystemId(1029, "clat"); /* clat part of nat464 */
putSystemId(1030, "loop_radio"); /* loop radio devices */
putSystemId(1031, "mediadrm"); /* MediaDrm plugins */
putSystemId(1032, "package_info"); /* access to installed package details */
putSystemId(1033, "sdcard_pics"); /* external storage photos access */
putSystemId(1034, "sdcard_av"); /* external storage audio/video access */
putSystemId(1035, "sdcard_all"); /* access all users external storage */
putSystemId(1036, "logd"); /* log daemon */
putSystemId(1037, "shared_relro"); /* creator of shared GNU RELRO files */
putSystemId(1038, "dbus"); /* dbus-daemon IPC broker process */
putSystemId(1039, "tlsdate"); /* tlsdate unprivileged user */
putSystemId(1040, "mediaex"); /* mediaextractor process */
putSystemId(1041, "audioserver"); /* audioserver process */
putSystemId(1042, "metrics_coll"); /* metrics_collector process */
putSystemId(1043, "metricsd"); /* metricsd process */
putSystemId(1044, "webserv"); /* webservd process */
putSystemId(1045, "debuggerd"); /* debuggerd unprivileged user */
putSystemId(1046, "mediacodec"); /* mediacodec process */
putSystemId(1047, "cameraserver"); /* cameraserver process */
putSystemId(1048, "firewall"); /* firewalld process */
putSystemId(1049, "trunks"); /* trunksd process (TPM daemon) */
putSystemId(1050, "nvram"); /* Access-controlled NVRAM */
putSystemId(1051, "dns"); /* DNS resolution daemon (system: netd) */
putSystemId(1052, "dns_tether"); /* DNS resolution daemon (tether: dnsmasq) */
putSystemId(1053, "webview_zygote"); /* WebView zygote process */
putSystemId(1054, "vehicle_network"); /* Vehicle network service */
putSystemId(1055, "media_audio"); /* GID for audio files on internal media storage */
putSystemId(1056, "media_video"); /* GID for video files on internal media storage */
putSystemId(1057, "media_image"); /* GID for image files on internal media storage */
putSystemId(2000, "shell"); /* adb and debug shell user */
putSystemId(2001, "cache"); /* cache access */
putSystemId(2002, "diag"); /* access to diagnostic resources */
/* The range 2900-2999 is reserved for OEMs */
// The 3000 series are intended for use as supplemental group id's only. They indicate
// special Android capabilities that the kernel is aware of.
putSystemId(3001, "net_bt_admin"); /* bluetooth: get any socket */
putSystemId(3002, "net_bt"); /* bluetooth: get sco, rfcomm or l2cap sockets */
putSystemId(3003, "inet"); /* can get AF_INET and AF_INET6 sockets */
putSystemId(3004, "net_raw"); /* can get raw INET sockets */
putSystemId(3005, "net_admin"); /* can configure interfaces and routing tables. */
putSystemId(3006, "net_bw_stats"); /* read bandwidth statistics */
putSystemId(3007, "net_bw_acct"); /* change bandwidth statistics accounting */
putSystemId(3008, "net_bt_stack"); /* bluetooth: access config files */
putSystemId(3009, "readproc"); /* Allow /proc read access */
putSystemId(3010, "wakelock"); /* Allow system wakelock read/write access */
/* The range 5000-5999 is also reserved for OEMs. */
putSystemId(9997, "everybody"); /* shared between all apps in the same profile */
putSystemId(9998, "misc"); /* access to misc storage */
putSystemId(9999, "nobody");
}
private static void putSystemId(int id, String name) {
// Check if the uid exists before adding it so we don't add unsupported ids.
if (android.os.Process.getUidForName(name) != id) {
// Not valid on this system. Most likely due to a lower API.
return;
}
SYSTEM_IDS.put(id, name);
}
/**
* #return An array of system UIDs
*/
public static SparseArray<String> getSystemIds() {
return SYSTEM_IDS;
}
/**
* Returns the UID/GID name assigned to a particular id, or {#code null} if there is none.
*
* #param id
* The UID/GID of a process or file
* #return the name of the UID/GID or {#code null} if the id is unrecognized.
*/
public static String getNameForId(int id) {
String name = SYSTEM_IDS.get(id);
if (name == null) {
if (id >= AID_SHARED_GID_START && id <= AID_SHARED_GID_END) {
name = String.format(Locale.ENGLISH, "all_a%d", id - AID_SHARED_GID_START);
} else {
int appId = id - AID_APP;
int userId = 0;
// loop until we get the correct user id.
// 100000 is the offset for each user.
while (appId > AID_USER) {
appId -= AID_USER;
userId++;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
// u{user_id}_a{app_id} is used on API 17+ for multiple user account support.
name = String.format(Locale.ENGLISH, "u%d_a%d", userId, appId);
} else {
// app_{app_id} is used below API 17.
name = String.format(Locale.ENGLISH, "app_%d", appId);
}
}
}
return name;
}
private AndroidFilesystemConfig() {
throw new AssertionError("no instances");
}
}
Using Reflection:
Inspired by odexide's answer, here is some really ugly reflection I wouldn't advise using that will get the UID/GID name from getpwuid(uid_t):
public static String getNameForUid(int id) {
try {
Class<?> clazz = Class.forName("libcore.io.Libcore");
Field field = clazz.getDeclaredField("os");
if (!field.isAccessible()) {
field.setAccessible(true);
}
Object os = field.get(null);
if (os != null) {
Method getpwuid = os.getClass().getMethod("getpwuid", int.class);
if (getpwuid != null) {
if (!getpwuid.isAccessible()) {
getpwuid.setAccessible(true);
}
Object passwd = getpwuid.invoke(os, id);
if (passwd != null) {
Field pw_name = passwd.getClass().getDeclaredField("pw_name");
if (!pw_name.isAccessible()) {
pw_name.setAccessible(true);
}
return (String) pw_name.get(passwd);
}
}
}
} catch (Exception ignored) {
}
return null;
}
The UIDs are hardcoded for the android implemention of libc (bionic) and also are provided in ranges for apps. android_filesystem_config.h explains the mapping.
You should be able to use the bionic stubs (c++) for getpwuid(uid_t).
For more info on the stubs, see this AOSP documentation.
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
:)