Does android OS log system events to a log file somewhere? If so, where/how can I read this?
Background: After leaving my SEMC X10 Mini Pro on charge last night, I wake up to find it was off. I'd like to look in a log file to try and work out when and why the phone switched itself off.
Found this older post, this might be interesting for you, too.
Use this class: This will wite log to file on sd
public class Logger {
public static final String APP_ID = "Android APP";
public static String logDir = "/androidapp";
public static String logFileName = "/log.txt";
public static boolean writeLogsToFile = false;
public static final int LOG_LEVEL_VERBOSE = 4;
public static final int LOG_LEVEL_DEBUG = 3;
public static final int LOG_LEVEL_INFO = 2;
public static final int LOG_LEVEL_ERROR = 1;
public static final int LOG_LEVEL_OFF = 0;
public static final int CURRENT_LOG_LEVEL = LOG_LEVEL_DEBUG;
public static void log(String message, int logLevel) {
if (logLevel > CURRENT_LOG_LEVEL) {
return;
} else {
Log.v(APP_ID, message);
if (writeLogsToFile) {
writeToFile(message);
}
}
}
private static void writeToFile(String message) {
try {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + logDir);
dir.mkdirs();
File file = new File(dir, logFileName);
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file, true), 8 * 1024));
writer.println(APP_ID + " " + new Date().toString() + " : " + message);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void verbose(String message) {
log(message, LOG_LEVEL_VERBOSE);
}
public static void debug(String message) {
log(message, LOG_LEVEL_DEBUG);
}
public static void error(String message) {
log(message, LOG_LEVEL_ERROR);
}
public static void info(String message) {
log(message, LOG_LEVEL_INFO);
}
}
Related
I am trying to upload multiple image to ASW using rxJava. I have found a kotlin example.
Upload multiple images(nearly 100) from Android to Amazon S3?.
I tried to implement it using Java. but couldn't find any proper method. can anyone help me with that?
public void processImageFiles(){
uploadedImageInfo = new ArrayList<>();
List<Single<Boolean>> uploadList = new ArrayList<>();
for(File file : selectedImageList){
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(file.toString());
String fileName = Calendar.getInstance().getTimeInMillis() + sharedPref.getSharedPrefData(SharedPref.USER_ID) + "." + fileExtension;
String uploadedFileLink = "https://" + ApiClient.BUCKET_NAME + "." + ApiClient.AWS_END_POINT + "/" + fileName;
RecordData recordData = new RecordData();
recordData.setUrl(uploadedFileLink);
recordData.setFileType(fileExtension);
recordData.setFileName(fileName);
uploadedImageInfo.add(recordData);
uploadList.add(uploadToAWS(file, recordData));
}
}
public Single<Boolean> uploadToAWS(File imageFile, RecordData data) {
return Single.create(emitter -> {
AmazonS3 s3Client = new AmazonS3Client(new BasicAWSCredentials(ApiClient.ACCESS_KEY, ApiClient.SECRET_KEY));
String uploadLink = ApiClient.BUCKET_NAME;
s3Client.setEndpoint(ApiClient.AWS_END_POINT);
s3Client.setRegion(Region.getRegion(Regions.US_EAST_1));
TransferUtility transferUtility = new TransferUtility(s3Client, mContext);
TransferObserver transferObserver = transferUtility.upload(uploadLink, data.getFileName(), imageFile, CannedAccessControlList.PublicRead);
mContext.registerReceiver(TransferNetworkLossHandler.getInstance(mContext), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
transferObserver.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
Log.e("onStateChanged", state.name() + "");
if (state.name().equals(TransferState.COMPLETED.name())) {
emitter.onSuccess(true);
} else {
emitter.onError(null);
}
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
//Implement the code to handle the file uploaded progress.
Log.e("e", bytesCurrent + "");
}
#Override
public void onError(int id, Exception exception) {
emitter.onError(exception);
}
});
});
}
I've already reply to similar questions for running multiple requests in parallel. you can find them here
I can suggest you this implementation :
public final class RecordData {
private final String url;
private final String fileType;
private final String fileName;
public RecordData(String url, String fileType, String fileName) {
this.url = url;
this.fileType = fileType;
this.fileName = fileName;
}
public String getUrl() {
return url;
}
public String getFileType() {
return fileType;
}
public String getFileName() {
return fileName;
}
}
public RecordData toRecord(File file) {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(file.toString());
String fileName = Calendar.getInstance().getTimeInMillis() + sharedPref.getSharedPrefData(SharedPref.USER_ID) + "." + fileExtension;
String uploadedFileLink = "https://" + ApiClient.BUCKET_NAME + "." + ApiClient.AWS_END_POINT + "/" + fileName;
return new RecordData(uploadedFileLink, fileExtension, fileName);
}
public void processImageFiles(List<File> selectedImageList) {
Observable.fromIterable(selectedImageList)
.flatMapSingle(file -> uploadToAWS(file, toRecord(file)).subscribeOn(Schedulers.io()))
.subscribe();
}
I would like to use something like log4j to log on files. I can see the logback project but I can't understand how to use a FileAppender programmatically.
Is There a simple way to log on files?
To write Logs on SD Card i am using below class.
You can try or modify as per your need ,
public class Log {
/** you can use application storage just change below line to your like getFile or package name etc.. **/
private static String enable_path=Environment.getExternalStorageDirectory().toString() + "/your foder name";
private static File logFolderPath = new File(enable_path);
private static boolean isLogEnabled(){
return logFolderPath.exists();
}
public static void e(String tag, String msg) {
if(isLogEnabled()){
android.util.Log.e(tag, msg);
put('E', tag, msg, null);
}
}
public static void e(String tag, String msg, Throwable thr) {
if(isLogEnabled()){
android.util.Log.e(tag, msg, thr);
put('E', tag, msg + ": " + thr.getMessage(), thr);
}
}
private static final File LOG_FILE = new File(logFolderPath, "Logs.txt");
private static FileWriter fw;
private static final SimpleDateFormat sdf = new SimpleDateFormat(" yyyy-MM-dd HH:mm:ss.SSS ", Locale.US);
private static long lastMs, lastNs;
private synchronized static void put(char level, String tag, String msg,Throwable thr) {
try {
if(!LOG_FILE.exists())
LOG_FILE.createNewFile();
/* if (fw == null)*/ {
fw = new FileWriter(LOG_FILE, true); // true: append
}
Date d = new Date();
long nowMs = d.getTime();
long nowNs = System.nanoTime();
if (lastMs == 0)
lastMs = nowMs;
if (lastNs == 0)
lastNs = nowNs;
fw.write(level);
fw.write(sdf.format(d));
fw.write(Long.toString(nowMs - lastMs));
fw.write(' ');
fw.write(Long.toString(nowNs));
fw.write(' ');
fw.write(Double.toString((nowNs - lastNs) / 1e6));
fw.write(' ');
fw.write(tag);
fw.write(' ');
fw.write(msg);
fw.write('\n');
if (thr != null)
thr.printStackTrace(new PrintWriter(fw));
fw.flush();
lastMs = nowMs;
lastNs = nowNs;
}
catch (IOException ex) {
android.util.Log.e(tag, "IOException", ex);
}
}
}
To programmatically create a FileAppender in logback-android, use the following code:
//import org.slf4j.LoggerFactory;
//import org.slf4j.Logger;
//import ch.qos.logback.core.FileAppender;
//import ch.qos.logback.core.util.StatusPrinter;
//import ch.qos.logback.classic.LoggerContext;
//import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
//import ch.qos.logback.classic.Level;
//import ch.qos.logback.classic.spi.ILoggingEvent;
private void configureFileAppender() {
// reset the default context (which may already have been initialized)
// since we want to reconfigure it
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
context.reset();
final String LOG_DIR = getApplicationInfo().dataDir + "/logs";
FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
fileAppender.setAppend(true);
fileAppender.setContext(context);
fileAppender.setFile(LOG_DIR + "/log.txt");
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setPattern("%logger{35} - %msg%n");
encoder.setContext(context);
encoder.start();
fileAppender.setEncoder(encoder);
fileAppender.start();
// add the newly created appender to the root logger;
// qualify Logger to disambiguate from org.slf4j.Logger
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.setLevel(Level.TRACE);
root.addAppender(fileAppender);
// DEBUG: print any status messages (warnings, etc) encountered in logback config
//StatusPrinter.print(context);
}
You might want to consider using a RollingFileAppender instead to avoid filling up your disk. See example from the logback-android Wiki.
It is already asked but i didn't find any solution. For bluetooth application i am using the bluetoothShare.class .
My source code for sending the file to the target device
MainActvity.class:
Set<BluetoothDevice> devices = btAdapter
.getBondedDevices();
final String btDeviceName = selected_deviceName;
BluetoothDevice device = null;
for (BluetoothDevice itDevice : devices) {
if (btDeviceName.equals(itDevice.getName())) {
device = itDevice;
}
}
if (device != null) {
ContentValues values = new ContentValues();
values.put(BluetoothShare.URI, uri.toString());
values.put(BluetoothShare.MIMETYPE, "image/jpeg");
values.put(BluetoothShare.DESTINATION,
device.getAddress());
values.put(BluetoothShare.DIRECTION,
BluetoothShare.DIRECTION_OUTBOUND);
Long ts = System.currentTimeMillis();
values.put(BluetoothShare.TIMESTAMP, ts);
final Uri contentUri = getApplicationContext()
.getContentResolver().insert(
BluetoothShare.CONTENT_URI, values);
Log.v(TAG, "Insert contentUri: " + contentUri
+ " to device: " + device.getName());
Toast.makeText(getApplicationContext(), "Success",
Toast.LENGTH_LONG).show();
} else {
textStatus
.setText("Bluetooth remote device not found");
}
} else {
textStatus.setText("Bluetooth not activated");
}
}
else {
Toast.makeText(getApplicationContext(), "No devices found",
Toast.LENGTH_LONG).show();
}
and the blueToothShare.class:
package process.bluetooth.sendfile.opp;
import android.net.Uri;
import android.provider.BaseColumns;
public final class BluetoothShare implements BaseColumns {
private BluetoothShare() {
}
public static final String PERMISSION_ACCESS = "android.permission.ACCESS_BLUETOOTH_SHARE";
public static final Uri CONTENT_URI = Uri
.parse("content://com.android.bluetooth.opp/btopp");
public static final String TRANSFER_COMPLETED_ACTION = "android.btopp.intent.action.TRANSFER_COMPLETE";
public static final String INCOMING_FILE_CONFIRMATION_REQUEST_ACTION = "android.btopp.intent.action.INCOMING_FILE_NOTIFICATION";
public static final String USER_CONFIRMATION_TIMEOUT_ACTION = "android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT";
public static final String URI = "uri";
public static final String FILENAME_HINT = "hint";
public static final String _DATA = "_data";
public static final String MIMETYPE = "mimetype";
public static final String DIRECTION = "direction";
public static final String DESTINATION = "destination";
public static final String VISIBILITY = "visibility";
public static final String USER_CONFIRMATION = "confirm";
public static final String STATUS = "status";
public static final String TOTAL_BYTES = "total_bytes";
public static final String CURRENT_BYTES = "current_bytes";
public static final String TIMESTAMP = "timestamp";
public static final int DIRECTION_OUTBOUND = 0;
public static final int DIRECTION_INBOUND = 1;
public static final int USER_CONFIRMATION_PENDING = 0;
public static final int USER_CONFIRMATION_CONFIRMED = 1;
public static final int USER_CONFIRMATION_AUTO_CONFIRMED = 2;
public static final int USER_CONFIRMATION_DENIED = 3;
public static final int USER_CONFIRMATION_TIMEOUT = 4;
public static final int VISIBILITY_VISIBLE = 0;
public static final int VISIBILITY_HIDDEN = 1;
public static boolean isStatusInformational(int status) {
return (status >= 100 && status < 200);
}
public static boolean isStatusSuspended(int status) {
return (status == STATUS_PENDING);
}
public static boolean isStatusSuccess(int status) {
return (status >= 200 && status < 300);
}
public static boolean isStatusError(int status) {
return (status >= 400 && status < 600);
}
public static boolean isStatusClientError(int status) {
return (status >= 400 && status < 500);
}
public static boolean isStatusServerError(int status) {
return (status >= 500 && status < 600);
}
public static boolean isStatusCompleted(int status) {
return (status >= 200 && status < 300)
|| (status >= 400 && status < 600);
}
public static final int STATUS_PENDING = 190;
public static final int STATUS_RUNNING = 192;
public static final int STATUS_SUCCESS = 200;
public static final int STATUS_BAD_REQUEST = 400;
public static final int STATUS_FORBIDDEN = 403;
public static final int STATUS_NOT_ACCEPTABLE = 406;
public static final int STATUS_LENGTH_REQUIRED = 411;
public static final int STATUS_PRECONDITION_FAILED = 412;
public static final int STATUS_CANCELED = 490;
public static final int STATUS_UNKNOWN_ERROR = 491;
public static final int STATUS_FILE_ERROR = 492;
public static final int STATUS_ERROR_NO_SDCARD = 493;
public static final int STATUS_ERROR_SDCARD_FULL = 494;
public static final int STATUS_UNHANDLED_OBEX_CODE = 495;
public static final int STATUS_OBEX_DATA_ERROR = 496;
public static final int STATUS_CONNECTION_ERROR = 497;
}
BluetoothShare class not supported android 4.1 and above. you can use the following intent coding to send file in android version 4.1 and above
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setComponent(new ComponentName(
"com.android.bluetooth",
"com.android.bluetooth.opp.BluetoothOppLauncherActivity"));
intent.setType("image/jpeg");
file = new File(filepath);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
startActivity(intent);
and also some devices in Android v 2.2/2.3 not send the file via bluetoothShare class.
Maybe you can try another solution with BufferedWriter and BufferedReader.
Here is a snipped code:
BluetoothDevice mmDevice;
Set<BluetoothDevice> mBluetoothAdapter;
BluetoothAdapter bAdapter = BluetoothAdapter
.getDefaultAdapter();
mBluetoothAdapter = bAdapter.getBondedDevices();
for (BluetoothDevice bc : mBluetoothAdapter) {
if (bc.getName().indexOf("name_of_bluetoothdevide") != -1) {
UUID uuid = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB"); // Standard
// SerialPortService
// ID
mmDevice = bc;
BluetoothSocket mmSocket = mmDevice
.createInsecureRfcommSocketToServiceRecord(uuid);
bAdapter.cancelDiscovery();
mmSocket.connect();
BufferedWriter Writer = new BufferedWriter(
new OutputStreamWriter(
mmSocket.getOutputStream()));
Writer.write("Bluetooth connected!");
Writer.flush();
app.setmSocket(mmSocket);
break;
}
}
And for reading:
BufferedReader Reader = new BufferedReader(
new InputStreamReader(mmSocket.getInputStream()));
receivedMsg = Reader.readLine();
Hope it can help you.
This code works with firmware from MediaTek. Tested on Android 4.0.4. Sends the file, without asking anything from the user
public boolean SendFileViaBluetoothOPP(String file_path, String destinationMAC){
BluetoothAdapter btadapter = BluetoothAdapter.getDefaultAdapter();
if(btadapter == null)
return false;
BluetoothDevice btdev = btadapter.getRemoteDevice(destinationMAC);
if(btdev == null)
return false;
Uri uri = Uri.fromFile(new File(file_path));
Intent shareIntent = new Intent(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_STREAM, uri)
.setType("application/zip");
List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(shareIntent, 0);
boolean found = false;
for(ResolveInfo actInfo: resolvedActivities){
if(actInfo.activityInfo.packageName.equals("com.mediatek.bluetooth"))
{
shareIntent.setComponent( new ComponentName(actInfo.activityInfo.packageName, actInfo.activityInfo.name ) );
shareIntent.putExtra("com.mediatek.bluetooth.sharegateway.extra.DEVICE_ADDRESS", btdev);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
found = true;
break;
}
}
if(found){
startActivity(shareIntent);
return true;
}
return false;
}
On older phone from MediaTek with Android 2.2.1 this code launches BluetoothDevicePicker to complete the operation.
Maybe this could help you in some way…
private void sendData(String message) {
byte[] msgBuffer = message.getBytes();
Log.d(TAG, "...Sending data: " + message + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
if (address.equals("00:00:00:00:00:00"))
msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on java code";
msg = msg + ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";
errorExit("Fatal Error", msg);
}
}
I was wondering whether it was possible to do such a thing. I know that one would need to modify some of the existing code to pull this off but I was wondering if anyone had any direction on where to look and how to do this.
I am placing a few custom tiles on a specific area on the map as a replacement for OSM tiles providers but need them to be stored in the /assets/ folder. Any ideas?
I use the nexts classes to do that.
import java.io.InputStream;
import org.osmdroid.ResourceProxy.string;
import org.osmdroid.tileprovider.util.StreamUtils;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
public class AssetsTileSource extends CustomBitmapTileSourceBase {
private final AssetManager mAssetManager;
public AssetsTileSource(final AssetManager assetManager, final String aName, final string aResourceId,
final int aZoomMinLevel, final int aZoomMaxLevel, final int aTileSizePixels,
final String aImageFilenameEnding) {
super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding);
mAssetManager = assetManager;
}
#Override
public Drawable getDrawable(final String aFilePath) {
InputStream inputStream = null;
try {
inputStream = mAssetManager.open(aFilePath);
if (inputStream != null) {
final Drawable drawable = getDrawable(inputStream);
return drawable;
}
} catch (final Throwable e) {
// Tile does not exist in assets folder.
// Ignore silently
} finally {
if (inputStream != null) {
StreamUtils.closeStream(inputStream);
}
}
return null;
}
}
MapTileFileAssetsProvider.java
public class MapTileFileAssetsProvider extends MapTileModuleProviderBase {
protected ITileSource mTileSource;
public MapTileFileAssetsProvider(final ITileSource pTileSource) {
super(OpenStreetMapTileProviderConstants.NUMBER_OF_TILE_FILESYSTEM_THREADS, OpenStreetMapTileProviderConstants.TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE);
mTileSource = pTileSource;
}
#Override
public boolean getUsesDataConnection() {
return false;
}
#Override
protected String getName() {
return "Assets Folder Provider";
}
#Override
protected String getThreadGroupName() {
return "assetsfolder";
}
#Override
protected Runnable getTileLoader() {
return new TileLoader();
}
#Override
public int getMinimumZoomLevel() {
return mTileSource != null ? mTileSource.getMinimumZoomLevel() : MAXIMUM_ZOOMLEVEL;
}
#Override
public int getMaximumZoomLevel() {
return mTileSource != null ? mTileSource.getMaximumZoomLevel() : MINIMUM_ZOOMLEVEL;
}
#Override
public void setTileSource(final ITileSource pTileSource) {
mTileSource = pTileSource;
}
private class TileLoader extends MapTileModuleProviderBase.TileLoader {
#Override
public Drawable loadTile(final MapTileRequestState pState) throws CantContinueException {
if (mTileSource == null) {
return null;
}
final MapTile pTile = pState.getMapTile();
String path = mTileSource.getTileRelativeFilenameString(pTile);
Drawable drawable;
try {
drawable = mTileSource.getDrawable(path);
} catch (final LowMemoryException e) {
// low memory so empty the queue
throw new CantContinueException(e);
}
return drawable;
}
}
}
And
import java.io.File;
import java.io.InputStream;
import java.util.Random;
import org.osmdroid.ResourceProxy;
import org.osmdroid.ResourceProxy.string;
import org.osmdroid.tileprovider.ExpirableBitmapDrawable;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
public abstract class CustomBitmapTileSourceBase implements ITileSource,
OpenStreetMapTileProviderConstants {
private static final Logger logger = LoggerFactory.getLogger(CustomBitmapTileSourceBase.class);
private static int globalOrdinal = 0;
private final int mMinimumZoomLevel;
private final int mMaximumZoomLevel;
private final int mOrdinal;
protected final String mName;
protected final String mImageFilenameEnding;
protected final Random random = new Random();
private final int mTileSizePixels;
private final string mResourceId;
public CustomBitmapTileSourceBase(final String aName, final string aResourceId,
final int aZoomMinLevel, final int aZoomMaxLevel, final int aTileSizePixels,
final String aImageFilenameEnding) {
mResourceId = aResourceId;
mOrdinal = globalOrdinal++;
mName = aName;
mMinimumZoomLevel = aZoomMinLevel;
mMaximumZoomLevel = aZoomMaxLevel;
mTileSizePixels = aTileSizePixels;
mImageFilenameEnding = aImageFilenameEnding;
}
#Override
public int ordinal() {
return mOrdinal;
}
#Override
public String name() {
return mName;
}
public String pathBase() {
return mName;
}
public String imageFilenameEnding() {
return mImageFilenameEnding;
}
#Override
public int getMinimumZoomLevel() {
return mMinimumZoomLevel;
}
#Override
public int getMaximumZoomLevel() {
return mMaximumZoomLevel;
}
#Override
public int getTileSizePixels() {
return mTileSizePixels;
}
#Override
public String localizedName(final ResourceProxy proxy) {
return proxy.getString(mResourceId);
}
#Override
public Drawable getDrawable(final String aFilePath) {
try {
// default implementation will load the file as a bitmap and create
// a BitmapDrawable from it
final Bitmap bitmap = BitmapFactory.decodeFile(aFilePath);
if (bitmap != null) {
return new ExpirableBitmapDrawable(bitmap);
} else {
// if we couldn't load it then it's invalid - delete it
try {
new File(aFilePath).delete();
} catch (final Throwable e) {
logger.error("Error deleting invalid file: " + aFilePath, e);
}
}
} catch (final OutOfMemoryError e) {
logger.error("OutOfMemoryError loading bitmap: " + aFilePath);
System.gc();
}
return null;
}
#Override
public String getTileRelativeFilenameString(final MapTile tile) {
final StringBuilder sb = new StringBuilder();
sb.append(pathBase());
sb.append('/');
sb.append(tile.getX());
sb.append('_');
sb.append(tile.getY());
sb.append('_');
sb.append(tile.getZoomLevel());
sb.append(imageFilenameEnding());
return sb.toString();
}
#Override
public Drawable getDrawable(final InputStream aFileInputStream) {
try {
// default implementation will load the file as a bitmap and create
// a BitmapDrawable from it
final Bitmap bitmap = BitmapFactory.decodeStream(aFileInputStream);
if (bitmap != null) {
return new ExpirableBitmapDrawable(bitmap);
}
System.gc();
} catch (final OutOfMemoryError e) {
logger.error("OutOfMemoryError loading bitmap");
System.gc();
//throw new LowMemoryException(e);
}
return null;
}
public final class LowMemoryException extends Exception {
private static final long serialVersionUID = 146526524087765134L;
public LowMemoryException(final String pDetailMessage) {
super(pDetailMessage);
}
public LowMemoryException(final Throwable pThrowable) {
super(pThrowable);
}
}
}
Modify method getTileRelativeFilenameString() to get yout tiles (i use the next format: x_y_zoom.png)
Example:
mapView = new MapView(getApplicationContext(), 256);
mapView.setClickable(true);
mapView.setTag("Mapa");
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapView.setMultiTouchControls(true);
mapView.setUseDataConnection(true);
MapTileModuleProviderBase moduleProvider =
new MapTileFileAssetsProvider(ASSETS_TILE_SOURCE);
SimpleRegisterReceiver simpleReceiver =
new SimpleRegisterReceiver(getApplicationContext());
MapTileProviderArray tileProviderArray =
new MapTileProviderArray(ASSETS_TILE_SOURCE, simpleReceiver,
new MapTileModuleProviderBase[] { moduleProvider });
TilesOverlay tilesOverlay =
new TilesOverlay(tileProviderArray, getApplicationContext());
mapView.getOverlays().add(tilesOverlay);
Instead to read directly from assets I copy/deploy the maptiles zipped (following osmdroid map tiles directory structure format) into osmdroid maptiles directory and then declare 3 tile providers, archive, cache and online provider.
public class MapTileProviderAssets extends MapTileProviderArray
implements IMapTileProviderCallback {
private static final String LOG_TAG = "MapTileProviderAssets";
private static final String ASSETS_MAP_DIRECTORY = "map";
private static final String SDCARD_PATH = Environment.getExternalStorageDirectory().getPath();
private static final String OSMDROID_MAP_FILE_SOURCE_DIRECTORY = "osmdroid";
private static final String OSMDROID_MAP_FILE_SOURCE_DIRECTORY_PATH =
SDCARD_PATH + "/" + OSMDROID_MAP_FILE_SOURCE_DIRECTORY;
public MapTileProviderAssets(final Context pContext) {
this(pContext, TileSourceFactory.DEFAULT_TILE_SOURCE);
}
public MapTileProviderAssets(final Context pContext, final ITileSource pTileSource) {
this(pContext, new SimpleRegisterReceiver(pContext),
new NetworkAvailabliltyCheck(pContext), pTileSource);
}
public MapTileProviderAssets(final Context pContext, final IRegisterReceiver pRegisterReceiver,
final INetworkAvailablityCheck aNetworkAvailablityCheck,
final ITileSource pTileSource) {
super(pTileSource, pRegisterReceiver);
final TileWriter tileWriter = new TileWriter();
// copy assets delivered in apk into osmdroid map source dir
// load zip archive first, then cache, then online
final List<String> zipArchivesRelativePathInAssets =
listArchives(pContext.getAssets(), ASSETS_MAP_DIRECTORY);
for (final String zipFileRelativePathInAssets : zipArchivesRelativePathInAssets) {
final String copiedFilePath = copyAssetFile(
pContext.getAssets(), zipFileRelativePathInAssets,
OSMDROID_MAP_FILE_SOURCE_DIRECTORY);
Log.d(LOG_TAG, String.format(
"Archive zip file copied into map source directory %s", copiedFilePath));
}
// list zip files in map archive directory
final Set<String> setZipFileArchivesPath = new HashSet<String>();
FileTools.listFiles(setZipFileArchivesPath, new File(
OSMDROID_MAP_FILE_SOURCE_DIRECTORY_PATH), ".zip", true);
final Set<IArchiveFile> setZipFileArchives = new HashSet<IArchiveFile>();
for (final String zipFileArchivesPath : setZipFileArchivesPath) {
final File zipfile = new File(zipFileArchivesPath);
final IArchiveFile archiveFile = ArchiveFileFactory.getArchiveFile(zipfile);
if (archiveFile != null) {
setZipFileArchives.add(archiveFile);
}
setZipFileArchives.add(archiveFile);
Log.d(LOG_TAG, String.format(
"Archive zip file %s added to map source ", zipFileArchivesPath));
}
final MapTileFileArchiveProvider archiveProvider;
Log.d(LOG_TAG, String.format(
"%s archive zip files will be used as source", setZipFileArchives.size()));
if (setZipFileArchives.size() > 0) {
final IArchiveFile[] pArchives =
setZipFileArchives.toArray(new IArchiveFile[setZipFileArchives.size()]);
archiveProvider = new MapTileFileArchiveProvider(
pRegisterReceiver, pTileSource, pArchives);
} else {
archiveProvider = new MapTileFileArchiveProvider(
pRegisterReceiver, pTileSource);
}
mTileProviderList.add(archiveProvider);
// cache
final MapTileFilesystemProvider fileSystemProvider =
new MapTileFilesystemProvider(pRegisterReceiver, pTileSource);
mTileProviderList.add(fileSystemProvider);
// online tiles
final MapTileDownloader downloaderProvider =
new MapTileDownloader(pTileSource, tileWriter, aNetworkAvailablityCheck);
mTileProviderList.add(downloaderProvider);
}
public static List<String> listArchives(final AssetManager assetManager,
final String subDirectory) {
final List<String> listArchives = new ArrayList<String>();
try {
final String[] lstFiles = assetManager.list(subDirectory);
if (lstFiles != null && lstFiles.length > 0) {
for (final String file : lstFiles) {
if (isZip(file)) {
listArchives.add(subDirectory + "/" + file);
}
// filter files (xxxxx.xxx format) and parse only directories,
// with out this all files are parsed and
// the process is VERY slow
// WARNNING: we could have directories with dot for versioning
else if (isDirectory(file)) {// (file.lastIndexOf(".") != (file.length() - 4)) {
listArchives(assetManager, subDirectory + "/" + file);
}
}
}
} catch (final IOException e) {
Log.w(LOG_TAG, String.format("List error: can't list %s, exception %s",
subDirectory, Log.getStackTraceString(e)));
} catch (final Exception e) {
Log.w(LOG_TAG, String.format("List error: can't list %s, exception %s",
subDirectory, Log.getStackTraceString(e)));
}
return listArchives;
}
private static boolean isZip(final String file) {
return file.endsWith(".zip");
}
private static boolean isDirectory(final String file) {
return file.lastIndexOf(".") != (file.length() - 4);
}
private static String copyAssetFile(final AssetManager assetManager,
final String assetRelativePath,
final String destinationDirectoryOnSdcard) {
InputStream in = null;
OutputStream out = null;
final String newfilePath = SDCARD_PATH + "/" +
destinationDirectoryOnSdcard + "/" + assetRelativePath;
final File newFile = new File(newfilePath);
// copy file only if it doesn't exist yet
if (!newFile.exists()) {
Log.d(LOG_TAG, String.format(
"Copy %s map archive in assets into %s", assetRelativePath, newfilePath));
try {
final File directory = newFile.getParentFile();
if (!directory.exists()) {
if (directory.mkdirs()) {
// Log.d(LOG_TAG, "Directory created: " + directory.getAbsolutePath());
}
}
in = assetManager.open(assetRelativePath);
out = new FileOutputStream(newfilePath);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (final Exception e) {
Log.e(LOG_TAG, "Exception during copyAssetFile: " + Log.getStackTraceString(e));
}
}
return newfilePath;
}
private static void copyFile(final InputStream in, final OutputStream out) throws IOException {
final byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
}
I need to upload a file from the sdcard to a server(using FTP), but I've encountered some problems when trying to save the file. The file seems to exist at first, but when I choose to play it... well, it just won't (like it crashes during upload rendering it invalid). Any ideas regarding what might going wrong? I've set the extension .mp3, and here's the code:
holder.upload.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String str_useid = Recording.str_getValue;
if (upload_or_not == true) {
FTPClient con = new FTPClient();
try {
con.connect("FTP URL");
if (con.login("USERNAME", "PASSWORD")) {
Handler progressHandler = new Handler();
con.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
BufferedInputStream buffIn = new BufferedInputStream(
new FileInputStream(
"/sdcard/audiometer/shanesh" +
RequestId[position] + "-"
str_useid + ".mp3"
)
);
con.enterLocalPassiveMode(); // important!
ProgressInputStream progressInput = new ProgressInputStream(
buffIn,
progressHandler
);
boolean status = con.storeFile(
"/Rangam/shanesh" +
RequestId[position] + "-" +
str_useid +
".mp3",
progressInput
);
String filename = "/shanesh" + RequestId[position] +
"-" + str_useid + ".mp3";
buffIn.close();
con.logout();
con.disconnect();
String MachineName = "DOT-NET-SERVER";
sendFlagToServer(RequestId[position], filename, MachineName);
Toast.makeText(
context,
" :: sucessfully upload :: " + status,
Toast.LENGTH_LONG
).show();
Toast.makeText(
context,
" :: RequestId is :: " +
RequestId[position],
Toast.LENGTH_LONG
).show();
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(
context,
" :: File not Found :: ",
Toast.LENGTH_LONG
).show();
}
}
ProgressInputStream.java
package com.RecordingApp;
import java.io.IOException;
import java.io.InputStream;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class ProgressInputStream extends InputStream {
/* Key to retrieve progress value from message bundle passed to handler */
public static final String PROGRESS_UPDATE = "progress_update";
private static final int TEN_KILOBYTES = 1024 * 10;
private InputStream inputStream;
private Handler handler;
private long progress;
private long lastUpdate;
private boolean closed;
public ProgressInputStream(InputStream inputStream, Handler handler) {
this.inputStream = inputStream;
this.handler = handler;
this.progress = 0;
this.lastUpdate = 0;
this.closed = false;
}
#Override
public int read() throws IOException {
int count = inputStream.read();
return incrementCounterAndUpdateDisplay(count);
}
#Override
public int read(byte[] b, int off, int len) throws IOException {
int count = inputStream.read(b, off, len);
return incrementCounterAndUpdateDisplay(count);
}
#Override
public void close() throws IOException {
super.close();
if (closed)
throw new IOException("already closed");
closed = true;
}
private int incrementCounterAndUpdateDisplay(int count) {
if (count > 0)
progress += count;
lastUpdate = maybeUpdateDisplay(progress, lastUpdate);
return count;
}
private long maybeUpdateDisplay(long progress, long lastUpdate) {
if (progress - lastUpdate > TEN_KILOBYTES) {
lastUpdate = progress;
sendLong(PROGRESS_UPDATE, progress);
}
return lastUpdate;
}
public void sendLong(String key, long value) {
Bundle data = new Bundle();
data.putLong(key, value);
Message message = Message.obtain();
message.setData(data);
handler.sendMessage(message);
}
}