I am using many sample codes to make a simple new marker in mapsforge.
For example i have tried these samples:
https://www.programcreek.com/java-api-examples/?api=org.mapsforge.map.layer.overlay.Marker
or this one:
https://stackoverflow.com/a/27499732/5720180
But did not created.
Can anyone help me to create a marker on mapsforge offline map?
This is my using code:
createPositionMarker(35.6505667,51.4465217);
private void createPositionMarker(double paramDouble1, double paramDouble2){
final LatLong localLatLong = new LatLong(paramDouble1, paramDouble2);
org.mapsforge.core.graphics.Bitmap bmp = AndroidGraphicFactory.convertToBitmap(getResources().getDrawable(R.drawable.alerton150));
MarkerMapsForge positionmarker = new MarkerMapsForge(localLatLong,bmp,0,0 );
this.mapView.getLayerManager().getLayers().add(positionmarker);
}
public class MainActivity extends Activity {
private MyLocationNewOverlay mLocationOverlay;
private CompassOverlay mCompassOverlay;
// name of the map file in the external storage
private static final String MAP_FILE = "iran.map";
private MapView mapView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidGraphicFactory.createInstance(this.getApplication());
this.mapView = new MapView(this);
setContentView(this.mapView);
this.mapView.setClickable(true);
this.mapView.getMapScaleBar().setVisible(true);
this.mapView.setBuiltInZoomControls(true);
this.mapView.setZoomLevelMin((byte) 6);
this.mapView.setZoomLevelMax((byte) 20);
// create a tile cache of suitable size
TileCache tileCache = AndroidUtil.createTileCache(this, "mapcache",
mapView.getModel().displayModel.getTileSize(), 1f,
this.mapView.getModel().frameBufferModel.getOverdrawFactor());
Log.i("LOGO", Environment.getExternalStorageDirectory().toString());
//ask for the permission in android M
int permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission to record denied");
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Permission to access the SD-CARD is required for this app to Download PDF.")
.setTitle("Permission required");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.i(TAG, "Clicked");
makeRequest();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
makeRequest();
}
}
File test = new File(Environment.getExternalStorageDirectory(), "payam_directory");
if (!test.exists()) {
try {
if (test.mkdir()) {
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
}
// tile renderer layer using internal render theme
Configuration.getInstance().setUserAgentValue(getPackageName());
MapDataStore mapDataStore = new MapFile(new File(Environment.getExternalStorageDirectory() + "/payam_directory/" + MAP_FILE));
TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, mapDataStore,
this.mapView.getModel().mapViewPosition, AndroidGraphicFactory.INSTANCE);
tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.OSMARENDER);
// only once a layer is associated with a mapView the rendering starts
this.mapView.getLayerManager().getLayers().add(tileRendererLayer);
this.mapView.setCenter(new LatLong(37.519101, 45.062364));
this.mapView.setZoomLevel((byte) 2);
Bitmap bitmap = AndroidGraphicFactory.convertToBitmap(getResources().getDrawable(R.drawable.m));
bitmap.incrementRefCount();
Marker marker = new Marker(new LatLong(37.519101, 45.062364), bitmap, 0, -bitmap.getHeight() / 2) {
#Override public boolean onTap(LatLong geoPoint, Point viewPosition, Point tapPoint) {
if (contains(viewPosition, tapPoint)) {
Toast.makeText(MainActivity.this, "Urmia, payamasli", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
};
mapView.getLayerManager().getLayers().add(marker);
}
protected void makeRequest() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
}
}
Related
Im working on a augmented reality app which displays 3d models on the users face.I made a class which extends ArFragment in which i set the front camera to be opened once a model is selected.I made a custom button for capturing the image,but i dont know how to implement the capture of the image itself with the 3d model displayed and store it in the phone(preferably without the custom made buttons being shown in the picture).Tried some code found on internet for programatical screenshoting but it screenshots only the buttons(the arrow and the circle).Here is how the activity looks like:
Here is the class that extends ArFragment:
public class CustomArFragment extends ArFragment {
#Override
protected Config getSessionConfiguration(Session session) {
Config config = new Config(session);
config.setAugmentedFaceMode(Config.AugmentedFaceMode.MESH3D);
this.getArSceneView().setupSession(session);
return config;
}
#Override
protected Set<Session.Feature> getSessionFeatures() {
return EnumSet.of(Session.Feature.FRONT_CAMERA);
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
FrameLayout frameLayout = (FrameLayout) super.onCreateView(inflater, container, savedInstanceState);
getPlaneDiscoveryController().hide();
getPlaneDiscoveryController().setInstructionView(null);
return frameLayout;
}
}
Here is the activity in which i set the 3d model:
public class ArActivity extends AppCompatActivity {
int pos;
private int[] images = {R.raw.glasses1, R.raw.glasses3, R.raw.glasses4, R.raw.glasses5,
R.raw.glasses6, R.raw.glasses7, R.raw.glasses8, R.raw.glasses9, R.raw.glasses10};
private ModelRenderable modelRenderable;
private boolean isAdded = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
Bundle extras = getIntent().getExtras();
if (extras != null) {
pos = extras.getInt("pos");
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ar);
CustomArFragment customArFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.arFragment);
ModelRenderable
.builder().setSource(this, images[pos])
.build()
.thenAccept(renderable -> {
modelRenderable = renderable;
modelRenderable.setShadowCaster(false);
modelRenderable.setShadowReceiver(false);
});
customArFragment.getArSceneView().setCameraStreamRenderPriority(Renderable.RENDER_PRIORITY_FIRST);
customArFragment.getArSceneView().getScene().addOnUpdateListener(frameTime -> {
if (modelRenderable == null)
return;
Frame frame = customArFragment.getArSceneView().getArFrame();
Collection<AugmentedFace> augmentedFaces = frame.getUpdatedTrackables(AugmentedFace.class);
for (AugmentedFace augmentedFace : augmentedFaces) {
if (isAdded)
return;
AugmentedFaceNode augmentedFaceNode = new AugmentedFaceNode(augmentedFace);
augmentedFaceNode.setParent(customArFragment.getArSceneView().getScene());
augmentedFaceNode.setFaceRegionsRenderable(modelRenderable);
isAdded = true;
}
});
}
}
I had a similar problem before.
Capturing the Camera image with placed 3d models.
i solved it with PixelCopy.
I'm adding my code of that part below.
I'm sorry that it's not going to be the straight-answer to your problem but i hope you get some ideas
ImageButton btn3 = (ImageButton)findViewById(R.id.camera_btn);
btn3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePhoto();
}
});
private String generateFilename() {
//현재시간을 기준으로 파일 이름 생성
String date =
new SimpleDateFormat("yyyyMMddHHmmss", java.util.Locale.getDefault()).format(new Date());
return Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES) + File.separator + "IM/" + date + "_screenshot.jpg";
}
private void saveBitmapToDisk(Bitmap bitmap, String filename) throws IOException {
//사용자의 갤러리에 IM 디렉토리 생성 및 Bitmap 을 JPEG 형식으로 갤러리에 저장
File out = new File(filename);
if (!out.getParentFile().exists()) {
out.getParentFile().mkdirs();
}
try (FileOutputStream outputStream = new FileOutputStream(filename);
ByteArrayOutputStream outputData = new ByteArrayOutputStream()) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputData);
outputData.writeTo(outputStream);
outputStream.flush();
outputStream.close();
} catch (IOException ex) {
throw new IOException("Failed to save bitmap to disk", ex);
}
}
private void takePhoto(){
//PixelCopy 를 사용하여 카메라 화면과 object 를 bitmap 으로 생성
final String filename = generateFilename();
ArSceneView view = arFragment.getArSceneView();
final Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(),
Bitmap.Config.ARGB_8888);
final HandlerThread handlerThread = new HandlerThread("PixelCopier");
handlerThread.start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
PixelCopy.request(view, bitmap, (copyResult) -> {
if (copyResult == PixelCopy.SUCCESS) {
try {
saveBitmapToDisk(bitmap, filename);
//Media Scanning 실시
Uri uri = Uri.parse("file://" + filename);
Intent i = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
i.setData(uri);
sendBroadcast(i);
} catch (IOException e) {
Toast toast = Toast.makeText(AR_Activity.this, e.toString(),
Toast.LENGTH_LONG);
toast.show();
return;
}
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content),
"스크린샷이 저장되었습니다.", Snackbar.LENGTH_LONG);
snackbar.setAction("갤러리에서 보기", v -> {
//어플 내에서 저장한 스크린샷을 확인 가능
File photoFile = new File(filename);
Uri photoURI = FileProvider.getUriForFile(AR_Activity.this,
AR_Activity.this.getPackageName() + ".ar.codelab.name.provider",
photoFile);
Intent intent = new Intent(Intent.ACTION_VIEW, photoURI);
intent.setDataAndType(photoURI, "image/*");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
});
snackbar.show();
} else {
Toast toast = Toast.makeText(AR_Activity.this,
"스크린샷 저장 실패!: " + copyResult, Toast.LENGTH_LONG);
toast.show();
}
handlerThread.quitSafely();
}, new Handler(handlerThread.getLooper()));
}
}
I have a strange problem. I'm developing an Android app which has 3 independent Async Tasks. When I try to run the app on a quad core phone there is no problem. But if I try to run the app on a dual core phone app crashes. How can I modify my tasks for dual core phones ?
Here is my code
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
This is the first async task. The second one is the Parse.com file upload async saveInBackground method.
public void startUpload(String fileName) {
try {
photoFile = new ParseFile(fileName, scaledData);
if (isTac) {
pictures.setPhotoFileTac(photoFile);
} else if (isCanak) {
pictures.setPhotoFileCanak(photoFile);
} else if (isYaprak) {
pictures.setPhotoFileYaprak(photoFile);
}
// pictures.save();// Telefon çekirdeğine göre 2 asenkron methodu desteklemiyor o yüzden sadece save yazılabilir fakat başarılı kontolü SaveCallback' te yakalanamaz.
pictures.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e == null){
Toast.makeText(getApplicationContext(),"Buluta yükleme başarılı. " , Toast.LENGTH_LONG).show();
if(pdialog != null)
{
pdialog.dismiss();//Eğer işlem başarılı ise asenkron sınıfta yaratılan progressbar ı kapat.
}
}
else{
Toast.makeText(getApplicationContext(),"Hata" +e.toString(),Toast.LENGTH_LONG).show();
}
}
});
}
catch (Exception ex)
{
Toast.makeText(getApplicationContext(),"Bağlantı Hatası !",Toast.LENGTH_LONG).show();
}
}
And the third one is the progress bar of upload process.
public class AsyncUpload extends AsyncTask<String,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pdialog = new ProgressDialog(TakePictureActivity.this);
pdialog.setMessage("Yükleniyor...");
pdialog.setIndeterminate(false);
pdialog.setCancelable(false);
pdialog.show();
}
#Override
protected String doInBackground(String... fileNames) {
return fileNames[0];
}
#Override
protected void onPostExecute(String name) {
startUpload(name);
super.onPostExecute(name);
}
}
And there is the code where I initialize upload session. (In if - else condition states the line new AsyncUpload().execute(fileName);
private void saveScaledPhoto(byte[] data) {
// Resize photo from camera byte array
pictureWidth = camera.getParameters().getPictureSize().width;
pictureHeight = camera.getParameters().getPictureSize().height;
Bitmap plantImage = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap plantImageScaled = Bitmap.createScaledBitmap(plantImage, pictureWidth, pictureHeight, false);
pictureCache = new PictureCache();
// Override Android default landscape orientation and save portrait
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedScaledPlantImage = Bitmap.createBitmap(plantImageScaled, 0,
0, plantImageScaled.getWidth(), plantImageScaled.getHeight(),
matrix, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
rotatedScaledPlantImage.compress(Bitmap.CompressFormat.PNG, 100, bos);
scaledData = bos.toByteArray();
AlertDialog.Builder aDB = new AlertDialog.Builder(this);
aDB.setCancelable(false);
aDB.setTitle("Emin misiniz ?");
aDB.setMessage("Çektiğiniz resim analizde kullanılacaktır. Devam etmek istiyor musunuz ?.. ");
aDB.setPositiveButton("Evet", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (isTac) {
pictureCache.setByteArrayTac(scaledData);
isTac = false;
isCanak = true;
Toast.makeText(getApplicationContext(), "Taç yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "TacYaprak";
new AsyncUpload().execute(fileName);
} else if (isCanak) {
pictureCache.setByteArrayCanak(scaledData);
isCanak = false;
isYaprak = true;
Toast.makeText(getApplicationContext(), "Çanak yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "CanakYaprak";
new AsyncUpload().execute(fileName);
} else if (isYaprak) {
String plantTag = "A_Y";
pictureCache.setByteArrayYaprak(scaledData);
isYaprak = false;
Toast.makeText(getApplicationContext(), "Ağaç yaprağı görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "AgacYapragi";
new AsyncUpload().execute(fileName);
}
if (!isTac && !isCanak && !isYaprak) {
finish();
}
}
});
aDB.setNegativeButton("Hayır", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = aDB.create();
alertDialog.show();
}
Here is the logcat output..
java.lang.NullPointerException
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:482)
at com.altygtsoft.biomatch.TakePictureActivity.saveScaledPhoto(TakePictureActivity.java:202)
at com.altygtsoft.biomatch.TakePictureActivity.access$000(TakePictureActivity.java:45)
at com.altygtsoft.biomatch.TakePictureActivity$2$1$2.onPictureTaken(TakePictureActivity.java:147)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:855)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Just realized my idea is too big for a comment so->
What happens if you do the following?
//Beware pseudo-code
new AsyncTask<>({
onPreExecute(){
//keep your code from before
...
}
doInBackground(Params... params){
startUpload(params[0], params[1]); //minus the done() function, plus pictures?
}
onPostExecute(){
//As I'm not sure where it fits in, if possible execute done() here.
}
}).execute(fileName, pictures); //couldn't find the decleration of pictures, so I stole the decleration of independence instead. Also maybe you need to put pictures in there, depending on where it is and how public/static.
My app downloads files from the internet and I need the user to select where to save them. How to make a choice directory on the Android Java? Please give example code
You just need to override onCreateDialog in an activity like this:
//In an Activity
private String[] mFileList;
private File mPath = new File(Environment.getExternalStorageDirectory() + "//yourdir//");
private String mChosenFile;
private static final String FTYPE = ".txt";
private static final int DIALOG_LOAD_FILE = 1000;
private void loadFileList() {
try {
mPath.mkdirs();
}
catch(SecurityException e) {
Log.e(TAG, "unable to write on the sd card " + e.toString());
}
if(mPath.exists()) {
FilenameFilter filter = new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
File sel = new File(dir, filename);
return filename.contains(FTYPE) || sel.isDirectory();
}
};
mFileList = mPath.list(filter);
}
else {
mFileList= new String[0];
}
}
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
AlertDialog.Builder builder = new Builder(this);
switch(id) {
case DIALOG_LOAD_FILE:
builder.setTitle("Choose your file");
if(mFileList == null) {
Log.e(TAG, "Showing file picker before loading the file list");
dialog = builder.create();
return dialog;
}
builder.setItems(mFileList, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mChosenFile = mFileList[which];
//you can do stuff with the file here too
}
});
break;
}
dialog = builder.show();
return dialog;
}
Check this out :
small open source Android Library Project that streamlines this process, while also providing a built-in file explorer (in case the user does not have one present). It's extremely simple to use, requiring only a few lines of code.
You can find it at GitHub: https://github.com/iPaulPro/aFileChooser
For More Details:
Android file chooser
This is a strange one and I hope that someone can at least give me a direction to look in.
My Android application uses GoogleMap API v2. In the app, I run an activity off OnClickInfoWindowListener on one of the markers. In detail, when I click on the particular marker, an InfoWindow of that marker appears. Next when I click on the InfoWindow, it launches another activity.
The problem is that when I return to GoogleMap from that activity, the particular marker which launched the activity, is not responsive. By responsive, I mean when I click on it, I do not get an InfoWindow. There is no such problem with the other markers. To fix the problem, I either move or zoom on the map or click on another marker to show its InfoWindow, then the original marker works normally. I cannot see any red stuff on the LogCat.
I also run the map off a ListView and there is no problem (that I can see).
Any suggestions on what to look at are very welcome!
Edit 1 :
This part is the InfoWindowClickListener setup ...
// Set up info Window Click Listener
googleMap
.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker mkr) {
// Default open file
// menu option : edit file information
// menu option : delete
Log.d(TAG, "InfoWindow Click detected.");
final GeoFileData gfd = getFromHashMap(mkr);
if (editGeoFile) {
editGeoFile = false;
editFileInfo(gfd);
} else if (deleteGeoFile) {
deleteGeoFile = false;
deleteFile(gfd, mkr);
} else {
openFile(gfd);
}
}
});
The openFile routine which launches the Activity
// Public and Routines used by the main loop
private void openFile (GeoFileData gfd) {
int typeIndex = gfd.getTypeIndex();
switch(typeIndex) {
case 0 :
case 1 :
case 2 :
case 3 :
// Spen file by default
Intent notePadIntent = new Intent(getBaseContext(), NotePad.class);
Bundle b = new Bundle();
b.putParcelable(MAIN_NOTEPAD_GFD, gfd);
notePadIntent.putExtras(b);
startActivityForResult(notePadIntent, SPEN_NOTEPAD_CODE);
break;
default :
Log.w(TAG, "Unknown file.");
Toast.makeText(this, getString(R.string.toast_unknown_file), Toast.LENGTH_LONG).show();
break;
}
}
The starting part of the launched activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spen_notepad);
Bundle extras = getIntent().getExtras();
if (extras != null) {
inputGfd = extras.getParcelable(PreznsActivity.MAIN_NOTEPAD_GFD);
}
extras.clear();
mContext = this;
// Spen
boolean isSpenFeatureEnabled = false;
Spen spenPackage = new Spen();
try {
spenPackage.initialize(this);
isSpenFeatureEnabled = spenPackage.isFeatureEnabled(Spen.DEVICE_PEN);
} catch (SsdkUnsupportedException e) {
if( SDKUtils.processUnsupportedException(this, e) == true) {
return;
}
} catch (Exception e1) {
Toast.makeText(mContext, "Cannot initialize Spen.",
Toast.LENGTH_SHORT).show();
e1.printStackTrace();
finish();
}
FrameLayout spenViewContainer =
(FrameLayout) findViewById(R.id.spenViewContainer);
RelativeLayout spenViewLayout =
(RelativeLayout) findViewById(R.id.spenViewLayout);
// PenSettingView
mPenSettingView =
new SpenSettingPenLayout(mContext, new String(),
spenViewLayout);
if (mPenSettingView == null) {
Toast.makeText(mContext, "Cannot create new PenSettingView.",
Toast.LENGTH_SHORT).show();
finish();
}
// EraserSettingView
mEraserSettingView =
new SpenSettingEraserLayout(mContext, new String(),
spenViewLayout);
if (mEraserSettingView == null) {
Toast.makeText(mContext, "Cannot create new EraserSettingView.",
Toast.LENGTH_SHORT).show();
finish();
}
// TextSettingView
mTextSettingView = new SpenSettingTextLayout(mContext, new String(), new HashMap<String, String>(), spenViewLayout);
if (mTextSettingView == null) {
Toast.makeText(mContext, "Cannot craeate new TextSettingView.", Toast.LENGTH_SHORT).show();
finish();
}
spenViewContainer.addView(mPenSettingView);
spenViewContainer.addView(mEraserSettingView);
spenViewContainer.addView(mTextSettingView);
// SpenSurfaceView
mSpenSurfaceView = new SpenSurfaceView(mContext);
if (mSpenSurfaceView == null) {
Toast.makeText(mContext, "Cannot create new SpenSurfaceView.",
Toast.LENGTH_SHORT).show();
finish();
}
spenViewLayout.addView(mSpenSurfaceView);
mPenSettingView.setCanvasView(mSpenSurfaceView);
mEraserSettingView.setCanvasView(mSpenSurfaceView);
mTextSettingView.setCanvasView(mSpenSurfaceView);
//
Display display = getWindowManager().getDefaultDisplay();
mScreenRect = new Rect();
display.getRectSize(mScreenRect);
// SpenNoteDoc
try {
mSpenNoteDoc =
new SpenNoteDoc(mContext, mScreenRect.width(), mScreenRect.height());
} catch (IOException e) {
Toast.makeText(mContext, "Cannot create new NoteDoc",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
finish();
} catch (Exception e) {
e.printStackTrace();
finish();
}
// NoteDoc
mSpenPageDoc = mSpenNoteDoc.appendPage();
mSpenPageDoc.setBackgroundColor(0xFFD6E6F5);
mSpenPageDoc.clearHistory();
// PageDoc
mSpenSurfaceView.setPageDoc(mSpenPageDoc, true);
initSettingInfo();
// Listener
mSpenSurfaceView.setTouchListener(mPenTouchListener);
mSpenSurfaceView.setColorPickerListener(mColorPickerListener);
mSpenSurfaceView.setTextChangeListener(mTextChangeListener);
mSpenSurfaceView.setReplayListener(mReplayListener);
mSpenPageDoc.setHistoryListener(mHistoryListener);
mEraserSettingView.setEraserListener(mEraserListener);
mSpenSurfaceView.setFlickListener(mFlickListener);
// Button
mTextObjBtn = (ImageView) findViewById(R.id.textObjBtn);
mTextObjBtn.setOnClickListener(mTextObjBtnClickListener);
mPenBtn = (ImageView) findViewById(R.id.penBtn);
mPenBtn.setOnClickListener(mPenBtnClickListener);
mEraserBtn = (ImageView) findViewById(R.id.eraserBtn);
mEraserBtn.setOnClickListener(mEraserBtnClickListener);
mUndoBtn = (ImageView) findViewById(R.id.undoBtn);
mUndoBtn.setOnClickListener(undoNredoBtnClickListener);
mUndoBtn.setEnabled(mSpenPageDoc.isUndoable());
mRedoBtn = (ImageView) findViewById(R.id.redoBtn);
mRedoBtn.setOnClickListener(undoNredoBtnClickListener);
mRedoBtn.setEnabled(mSpenPageDoc.isRedoable());
mImgObjBtn = (ImageView) findViewById(R.id.imgObjBtn);
mImgObjBtn.setOnClickListener(mImgObjBtnClickListener);
mAddPageBtn = (ImageView) findViewById(R.id.addPageBtn);
mAddPageBtn.setOnClickListener(mAddPageBtnClickListener);
mTxtView = (TextView) findViewById(R.id.spen_page);
mTxtView.setText("Page" + mSpenNoteDoc.getPageIndexById(mSpenPageDoc.getId()));
selectButton(mPenBtn);
String filePath = inputGfd.getFileDirectory();
mFilePath = new File(filePath);
if (!mFilePath.exists()) {
if (!mFilePath.mkdirs()) {
Toast.makeText(mContext, "Save Path Creation Error", Toast.LENGTH_SHORT).show();
return;
}
}
mSpenPageDoc.startRecord();
File loadFile = new File(inputGfd.getFileDirectory(), inputGfd.getFileName());
if (loadFile.exists()) {
loadNoteFile();
} else {
Log.w(TAG, "File does not exist!");
}
if(isSpenFeatureEnabled == false) {
mToolType = SpenSurfaceView.TOOL_FINGER;
mSpenSurfaceView.setToolTypeAction(mToolType,
SpenSurfaceView.ACTION_STROKE);
Toast.makeText(mContext,
"Device does not support Spen. \n You can draw stroke by finger",
Toast.LENGTH_SHORT).show();
}
}
One of the returns for the activity
private boolean saveNoteFile(final boolean isClose) {
// file save
// note file
String saveFilePath = inputGfd.getFileDirectory() + File.separator;
String fileName = inputGfd.getFileName();
if (!fileName.equals("")) {
saveFilePath += fileName;
saveNoteFile(saveFilePath);
if (isClose)
finish();
} else {
Toast
.makeText(mContext, "Invalid filename !!!", Toast.LENGTH_LONG)
.show();
}
return true;
}
and finally the destroy routine,
#Override
protected void onDestroy() {
Log.d(TAG, "NotePad onDestroy()");
super.onDestroy();
if (mSpenNoteDoc != null && mSpenPageDoc.isRecording()) {
mSpenPageDoc.stopRecord();
}
if (mPenSettingView != null) {
mPenSettingView.close();
}
if (mEraserSettingView != null) {
mEraserSettingView.close();
}
if (mTextSettingView != null) {
mTextSettingView.close();
}
if(mSpenSurfaceView != null) {
if (mSpenSurfaceView.getReplayState() == SpenSurfaceView.REPLAY_STATE_PLAYING) {
mSpenSurfaceView.stopReplay();
}
mSpenSurfaceView.closeControl();
mSpenSurfaceView.close();
mSpenSurfaceView = null;
}
if(mSpenNoteDoc != null) {
try {
if (isDiscard)
mSpenNoteDoc.discard();
else
mSpenNoteDoc.close();
} catch (Exception e) {
e.printStackTrace();
}
mSpenNoteDoc = null;
}
};
Thanks!
This is likely a bug in Google Maps Android API v2 itself.
I encounter it in my app. When you open "Declusterification" demo, click on yellow marker with 10 in the center and a new marker (red default) appears in the same spot, this new marker cannot be interacted with to show info window without moving the map.
If you happen to figure out SSCCE for it, I suggest posting it on gmaps-api-issues. I'll support it. If I do find simple example to show this issue, I'll also post an update here.
To close up this question.
GoogleMap markers exhibit the anomalies mentioned in this thread and currently the issue has been fed back to Google. There are two apparent "workarounds" to the problem but how effective they are is not clear:
1st workaround : work within the limitations of .clear(). An activated marker cannot be deactivated with .clear().
2nd workaround : after returning from the activity, perform a camera update. This apparently resets the activation of the marker.
i have to solve this with the new "snapshot maker" which is implemented in the google maps release august but i dont' know how to do this.
Can somone give me a simple example?
here is my code:
public class MainActivity extends Activity {
static LatLng HAMBURG = new LatLng(47.524749, 21.632745);
GoogleMap map;
File dbFile;
private File imageFile;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PolylineOptions line = new PolylineOptions();
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
/*
* Adatbázis
*/
try {
dbFile = getDatabasePath("/mnt/sdcard/Download/TeleSensors.db");
} catch (Exception e) {
}
SQLiteDatabase myDataBase = SQLiteDatabase.openDatabase(
dbFile.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
Cursor curTAB = myDataBase.rawQuery("SELECT * FROM GPS_Values;", null);
Integer count = 0;
while (curTAB.moveToNext()) {
String s_latitude = curTAB.getString(1);
String s_longitude = curTAB.getString(2);
count++;
double latitude = Double.parseDouble(s_latitude);
double longitude = Double.parseDouble(s_longitude);
line.add(new LatLng(latitude, longitude));
Log.i("Coordinates",
s_latitude.toString() + " --- " + s_longitude.toString());
}
curTAB.close();
myDataBase.close();
// adatbázis vége
map.addPolyline(line);
// map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
// map.setMapType(GoogleMap.MAP_TYPE_NONE);
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
// map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
}
}
Thank you very mouch!
You have to call the Google maps snapshot method in a button listener because if you should take it too early, it will give you error bitmap width has to be larger than 0 or something like this.
Here is the code
private void button_listener() {
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SnapshotReadyCallback callback = new SnapshotReadyCallback() {
Bitmap bitmap;
#Override
public void onSnapshotReady(Bitmap snapshot) {
bitmap = snapshot;
try {
FileOutputStream out = new FileOutputStream("/mnt/sdcard/Download/TeleSensors.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}
};
map.snapshot(callback);
}
});
}
This one is better, it waits for your Map to be fully rendered, before taking the snapshot.
It was updated on 31-Oct-2013.
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
public void onMapLoaded() {
mMap.snapshot(new GoogleMap.SnapshotReadyCallback() {
public void onSnapshotReady(Bitmap bitmap) {
// Write image to disk
FileOutputStream out = new FileOutputStream("/mnt/sdcard/map.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
}
});
}
});
Extracted from http://googlegeodevelopers.blogspot.sg/2013/10/ghost-markers-in-your-neighborhood-new.html
Try for Kotlin Android like this when click on button to take google map snapshot:
val snapshotReadyCallback : GoogleMap.SnapshotReadyCallback = GoogleMap.SnapshotReadyCallback { selectedScreenShot ->
ivMapPreview.setImageBitmap(selectedScreenShot);
}
val onMapLoadedCallback : GoogleMap.OnMapLoadedCallback = GoogleMap.OnMapLoadedCallback {
mMap!!.snapshot(snapshotReadyCallback)
}
mMap!!.setOnMapLoadedCallback(onMapLoadedCallback)
Be successful.
I' ve tried the accepted answer but it didn't work then tried another approach that worked for me.
private void CaptureScreen() {
if(initMap()){
SnapshotReadyCallback callback = new SnapshotReadyCallback() {
Bitmap bitmap=null;
#Override
public void onSnapshotReady(Bitmap snapshot) {
// TODO Auto-generated method stub
bitmap = snapshot;
try {
saveImage(bitmap);
Toast.makeText(getApplicationContext(), "Image Saved", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveImage(Bitmap bitmap) throws IOException{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 40, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "test.png");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
}
};
mMap.snapshot(callback);
}
else{
Toast.makeText(this, "Map is not Initialized yet", Toast.LENGTH_LONG).show();
return ;
}
}
https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/GoogleMap#snapshot(com.google.android.gms.maps.GoogleMap.SnapshotReadyCallback, android.graphics.Bitmap)
public final void snapshot (GoogleMap.SnapshotReadyCallback callback)
Takes a snapshot of the map. You can use snapshots within your application when an interactive map would be difficult, or impossible,
to use. For example, images produced with the snapshot() method can be
used to display a thumbnail of the map in your app, or a snapshot in
the notification center.