Android Google Maps V2 User Location - java

The blue dot/arrow isnt showing on my map. Everything else works fine. Am i missing some permissions?
Included the Java Class, Manifest and layout XML.
private void setUpMap(int satelliteMode, LatLng startPoint, float zoomLevel) {
mapView.getUiSettings().setZoomControlsEnabled(false);
//mapView.getUiSettings().setMyLocationButtonEnabled(false);
mapView.setMapType(satelliteMode);
mapView.setMyLocationEnabled(true);
mapView.moveCamera(CameraUpdateFactory.newLatLngZoom(startPoint, zoomLevel));
}
xml:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
manifest:
<permission
android:name="com.example.project.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.example.project.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="API_KEY"/>

You'd see that clicking the 'my location' button creates the blue dot at your current location. Using the location manager to track location updates and moving the camera accordingly allows you to track the user too, without clicking the button. See a snippet below.
LocationListener ll = new LocationListener() {
#Override
public void onLocationChanged(Location arg0) {
Toast.makeText(getBaseContext(), "Moved to "+arg0.toString(), Toast.LENGTH_LONG).show();
CameraPosition cp = new CameraPosition.Builder()
.target(new LatLng(arg0.getLatitude(),arg0.getLongitude()))
.zoom(12)
.build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cp));
}
}

For some reason it just worked. Went away for lunch and left the app on. When i returned the blue arrow was drawn on the map. Not on the right location though but it was on the map. So the posted code of mine works. It only needs an update from the location manager.

FWIW, i have the exact same problem as the original post on a Samsung Galaxy Tab 2.
However, i do NOT have the issue on an Archos 101G9.
If I reboot, load my app with Google Maps v2 and click the 'go to my location' button in the top right, the Archos goes directly to my current location but the SGT2 does nothing.
If I manually get my current location using location manager and animate the map to it then it navigates. However clicking the 'go to my location' button still does nothing.
Getting a location fix using GPS seems to fix the issue.
EDIT:
On the SGT2 the blue location dot appears only with a GPS fix, however the Archos displays the blue dot with a mobile data/wifi fix.

Hi in you FragmentActivity add implements LocationListener
private LocationManager locationManager;
In onCreate(Bundle savedInstanceState).... add
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria locationCriteria = new Criteria();
locationCriteria.setAccuracy(Criteria.ACCURACY_FINE); locationManager.requestLocationUpdates(locationManager.getBestProvider(locationCriteria, true), 1L, 2F, this);
and implemented methos to LocationListener ;)

Related

Get current location with network provider on osmdroid

In my android app I am using the osmdroid framework. In the framework I am using the MyLocationNewOverlay() which contains a method to show the current location on the map.
My problem
The LocationListener in the framework seems not to use the network provider and only wants to locate me with GPS (which works fine, but only if I am outside).
Is there a standard way to use a LocationProvider that also works with the network provider if gps is not available?
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Pretty standard to init my location overlay:
private void initMyLocationNewOverlay() {
myLocationNewOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(context), mapView);
myLocationNewOverlay.enableMyLocation();
mapView.getOverlays().add(myLocationNewOverlay);
}
Thanks in advance!
The problem is that the GpsMyLocationProvider only adds the GPS_Provider to its sources (you can see that in the constructor). To add the network provider use the addLocationSource as following.
private void initMyLocationNewOverlay() {
GpsMyLocationProvider provider = new GpsMyLocationProvider(context);
provider.addLocationSource(LocationManager.NETWORK_PROVIDER);
myLocationNewOverlay = new MyLocationNewOverlay(provider, mapView);
myLocationNewOverlay.enableMyLocation();
mapView.getOverlays().add(myLocationNewOverlay);
}

define my location on google maps on setMyLocationEnabled eclipse

I'm developing an app for android with google maps. The problem is that when I activate "setMyLocationEnabled" on the google map, it sets my location to Hong Kong but I'm in Portugal. But the location given by the locationManager gives me my correct location. Is there a way to define that my location is the location of the locationManager on the "setMyLocationEnabled"?
This gives me my correct location:
Criteria criteria = new Criteria();
Location myLocation = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
Lat = myLocation.getLatitude();
Long = myLocation.getLongitude();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 20000, 1, this);
But this:
googleMap.setMyLocationEnabled(true);
says that I'm in Hong Kong when I actualy am in Portugal.
How can I define that the "setMyLocationEnabled" has to start on the same position as the locationManager and put the blue dot on that position?
In using My Location layer, please note as stated,
Before enabling the My Location layer, you must ensure that you have the required runtime location permission.
Either the coarse location permission:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp" >
...
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
...
</manifest>
Or the fine location permission:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp" >
...
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
...
</manifest>
However, as discussed in Making Your App Location-Aware
The Google Play services location APIs are preferred over the Android framework location APIs (android.location) as a way of adding location awareness to your app. If you are currently using the Android framework location APIs, you are strongly encouraged to switch to the Google Play services location APIs as soon as possible.

ActivityCompat.requestPermissions not showing dialog box

if (ContextCompat.checkSelfPermission(RegisterActivity.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED){
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE_PERMISSION);
i'm trying to use this function on nexus 5 api 23 and its just not showing me the dialog box like its supposed to do, it's just not doing anything.
what could cause the problem? (this code is in the java activity)
i tried changing my minimum api to 23 and use the requestPermissions() without the ActivityCompat but still not working.
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.example.idanayzen.photomap"
minSdkVersion 23
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:design:23.1.1'
}
and the Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.idanayzen.photomap">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SMS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps" />
<activity android:name=".RegisterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".WrongPhoneNum"></activity>
</application>
</manifest>
Here's an example of using requestPermissions():
First, define the permission (as you did in your post) in the manifest, otherwise, your request will automatically be denied:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Next, define a value to handle the permission callback, in onRequestPermissionsResult():
private final int REQUEST_PERMISSION_PHONE_STATE=1;
Here's the code to call requestPermissions():
private void showPhoneStatePermission() {
int permissionCheck = ContextCompat.checkSelfPermission(
this, Manifest.permission.READ_PHONE_STATE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_PHONE_STATE)) {
showExplanation("Permission Needed", "Rationale", Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
} else {
requestPermission(Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
}
} else {
Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
}
}
First, you check if you already have permission (remember, even after being granted permission, the user can later revoke the permission in the App Settings.)
And finally, this is how you check if you received permission or not:
#Override
public void onRequestPermissionsResult(
int requestCode,
String permissions[],
int[] grantResults) {
switch (requestCode) {
case REQUEST_PERMISSION_PHONE_STATE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
private void showExplanation(String title,
String message,
final String permission,
final int permissionRequestCode) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(title)
.setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
requestPermission(permission, permissionRequestCode);
}
});
builder.create().show();
}
private void requestPermission(String permissionName, int permissionRequestCode) {
ActivityCompat.requestPermissions(this,
new String[]{permissionName}, permissionRequestCode);
}
I had the same issue and it turned out to be due to the manifest merger tool pulling in an android:maxSdkVersion attribute from a dependency.
To view the actual permissions you're requesting in your APK you can use the aapt tool, like this:
/path/to/android-sdk/build-tools/version/aapt d permissions /path/to/your-apk.apk
in my case, it printed:
uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='18'
even though I hadn't specified a maxSdkVersion in my manifest. I fixed this issue by changing <uses-permission> in my manifest to:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
(where the tools namespace is http://schemas.android.com/tools)
I had a need to request permission for WRITE_EXTERNAL_STORAGE but was not getting a pop-up despite trying all of the different suggestions mentioned.
The culprit in the end was HockeyApp. It uses manifest merging to include its own permission for WRITE_EXTERNAL_STORAGE except it applies a max sdk version onto it.
The way to get around this problem is to include it in your Manifest file but with a replace against it, to override the HockeyApp's version and success!
4.7.2 Other dependencies requesting the external storage permission (SDK version 5.0.0 and later) To be ready for Android O,
HockeySDK-Android 5.0.0 and later limit the WRITE_EXTERNAL_STORAGE
permission with the maxSdkVersion filter. In some use cases, e.g.
where an app contains a dependency that requires this permission,
maxSdkVersion makes it impossible for those dependencies to grant or
request the permission. The solution for those cases is as follows:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>
It will cause that other attributes from low
priority manifests will be replaced instead of being merged.
https://support.hockeyapp.net/kb/client-integration-android/hockeyapp-for-android-sdk#permissions-advanced
Replace:
ActivityCompat.requestPermissions(this, new String[]{"Manifest.permission.READ_PHONE_STATE"}, 225);
with:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 225);
The actual string for that permission is not "Manifest.permission.READ_PHONE_STATE". Use the symbol Manifest.permission.READ_PHONE_STATE.
It could be not a problem with a single line of your code.
On some devices (I don't recall if it is in stock Android) the Permission dialog includes a check box labeled "Never ask again". If you click Deny with the box checked then you won't be prompted again for that permission, it will automatically be denied to the app. To revert this, you have to go into Settings -> App -> Permissions and re--enable that perm for the app. Then turn it off to deny it again. You may have to open the app before turning it off again, not sure.
I don't know if your Nexus has it. Maybe worth a try.
Here is another experience I'd like to share with you guys. The problem showed up after I implemented the following code to check for BLE access permission:
final String requiredPermission = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) ?
android.Manifest.permission.ACCESS_FINE_LOCATION :
android.Manifest.permission.ACCESS_COARSE_LOCATION;
I meant to distinguish between FINE and COARSE location permission requests, both had been defined in the manifest. When checking for ACCESS_COARSE_LOCATION permission, the "Request permission" dialog never poped up but onRequestPermissionsResult was always called with PERMISSION_DENIED (in case permission was not enabled in app settings). So I removed the check for BUILD.SDK and checked only for ACCESS_FINE_LOCATION and voilla the missing dialog showed up.
final String requiredPermission = android.Manifest.permission.ACCESS_FINE_LOCATION;
did the trick.
The Manifest source contains:
<uses-permission android:name="android.permission.COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
but the apk contained android.permission.ACCESS_FINE_LOCATION only. Sometime during build, the COARSE_LOCATION had been removed.
I hope this might help somebody having the same issue.
I updated my target SDK version from 22 to 23 and it worked perfectly.
Don't forget to write the permissions without extra spaces in the manifest. In my case, I had:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE " />
But look, at the end, there's an extra space. Just write it the right way:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And it's working now.
No matter what you do, Check if you declare Permission you need in the Manifest file.
<!--Declaring the required permissions-->
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.CAMERA" />
Then go to next steps..
I followed the top answer, but still didn't work. This simple issue wasted me many days. For my case, I'm trying to get access for MANAGE_EXTERNAL_STORAGE. At the end, I found for this particular permission, we can't use ActivityCompat.requestPermissions(), instead I have to use Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION. And to check if the permission is there, we also need to use a different API: Environment.isExternalStorageManager() instead of ContextCompat.checkSelfPermission(), not sure why they design in such an inconsistent way cause so much confusions.
I get my issue resolved following: How to obtain MANAGE_EXTERNAL_STORAGE permission
And also this is mentioned in SDK document of: manage-all-files.
For me the issue was requesting a group mistakenly instead of the actual permissions.
The above information is good, but setting targetSdkVersion to 23 (or higher) is critical for Android to interpret the <uses-permission> tag in the manifest as "I will ask in code" instead of "I demand upon installation." Lots of sources will tell you that you need the <uses-permission> tag, but no one says why and if you don't have that value set, you're going to be as confused as I was for hours on end.
I came across this problem in Samsung S8 and N8 (havent found in any other)
so the problem is in the manifest file uses-permission
<uses-permission android:name="android.permission.CAMERA"
android:requiredFeature="true" />
For some reason, the attribute android:requiredFeature is the culprit. and I haven't found the explanation on why.
to solve simply remove it,
<uses-permission android:name="android.permission.CAMERA" />
In my case, target sdk 33 to 32 solves it
For me, this was related to them getting more granular with permissions in 33, related to requesting read_external_storage.
This is the kotlin code I'm using to check and request access in Jan 2023.
private fun checkPermissions():Boolean{
// version 33 gets more granular
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this, arrayOf(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO // why isn't this plural too
),
1
)
return false
}
}else{
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this, arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE
),
1
)
return false
}
}
return true
}
I also had to add all 3 of these to my manifest, to support apis 31-33.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
I had this same issue.I updated to buildToolsVersion "23.0.3" It all of a sudden worked. Hope this helps anyone having this issue.
I was having the same problem, and solved it by replacing Manifest.permission.READ_PHONE_STATE with android.Manifest.permission.READ_PHONE_STATE.
For me the issue was I had an invalid request code. I choose 0xDEADBEEF as a request code and it was silently failing (maybe it's cast to something smaller than 32-bit somewhere internally?) If I choose 255 everything worked fine as NightSkyDev described above.
This just happened to me. It turned out I was requesting ALL permissions, when I needed to filter to just DANGEROUS permissions, and it suddenly started working.
fun requestPermissions() {
val missingDangerPermissions = PERMISSIONS
.filter { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }
.filter { this.getPackageManager().getPermissionInfo(it, PackageManager.GET_META_DATA).protectionLevel == PermissionInfo.PROTECTION_DANGEROUS } // THIS FILTER HERE!
if (missingDangerPermissions.isNotEmpty()) {
Log.i(TAG, "Requesting dangerous permission to $missingDangerPermissions.")
ActivityCompat.requestPermissions(this,
missingDangerPermissions.toTypedArray(),
REQUEST_CODE_REQUIRED_PERMISSIONS);
return
} else {
Log.i(TAG, "We had all the permissions we needed (yay!)")
}
}
For me the error was in the manifest: the permission was in uppercase. Android Studio suggest me the permissions in uppercase. I don't care about that and it took me two hours to fixe this problem.
The right syntaxe for permission is
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
For me the problem was that right after making the request, my main activity launched another activity. That superseded the dialog so it was never seen.
TL;DR:
Add the following to your Manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion" />
Check this article, it fixed it for me:
https://nphau.medium.com/android-request-permissions-not-showing-a-dialog-box-b7f2067d7b09
it happen to me i was running it on API 23 and i had to use the code to request permission like this code below put it on on create method. note that MY_PERMISSIONS_REQUEST_READ_LOCATION is an integer that is equal to 1 example int MY_PERMISSIONS_REQUEST_READ_LOCATION = 1:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION},MY_PERMISSIONS_REQUEST_READ_LOCATION);
}
Maybe this solution could help anyone
rather than:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
use :
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
so we add android. to Manifest.permission.WRITE_EXTERNAL_STORAGE

SetShareIntent from the mainactivity is never used locally.. What does it mean?

I have developed simple image app that is suppose to swipe the images from left to right .After reading this link http://developer.android.com/training/sharing/shareaction.html#set-share-intent. I implemented the codes in my mainActivity.java. This code is suppose to show sharing option at the top along the actionbar. However, I am getting little yellow lamp near this code ..private void setShareIntent(Intent shareIntent) {...What does it mean.. Following is my mainActivity.java code..
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ShareActionProvider;
public class MainActivity extends Activity {
MediaPlayer oursong;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
oursong = MediaPlayer.create(MainActivity.this, R.raw.a);
oursong.start ();
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
ImageAdapter adapter = new ImageAdapter(this);
viewPager.setAdapter(adapter);
}
private ShareActionProvider mShareActionProvider;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate menu resource file.
getMenuInflater().inflate(R.menu.activity_main, menu);
// Locate MenuItem with ShareActionProvider
MenuItem item = menu.findItem(R.id.menu_item_share);
// Fetch and store ShareActionProvider
mShareActionProvider = (ShareActionProvider) item.getActionProvider();
// Return true to display menu
return true;
}
#Override
protected void onPause(){
super.onPause();
oursong.release();
}
}
Error problems
Description Resource Path Location Type
[Accessibility] Missing contentDescription attribute on image fullimage.xml /Grid View/res/layout line 6 Android Lint Problem
Description Resource Path Location Type
<uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion="?" AndroidManifest.xml /Copy of galleryDemo line 7 Android Lint Problem
Description Resource Path Location Type
Not targeting the latest versions of Android; compatibility modes apply. Consider testing and updating this version. Consult the android.os.Build.VERSION_CODES javadoc for details. AndroidManifest.xml /DailySounds line 8 Android Lint Problem
Description Resource Path Location Type
Should explicitly set android:allowBackup to true or false (it's true by default, and that can have some security implications for the application's data) AndroidManifest.xml /Copy of galleryDemo line 10 Android Lint Problem
Description Resource Path Location Type
The value of the field MainActivity.mShareActionProvider is not used MainActivity.java /Copy of ViewpagerImageGallery/src/com/manishkpr/viewpagerimagegallery line 29 Java Problem
Description Resource Path Location Type
This method has a constructor name MainActivity.java /SecondActivityApp/src/com/secondactivityapp line 28 Java Problem
Description Resource Path Location Type
Use a layout_height of 0dp instead of wrap_content for better performance fullimage.xml /Grid View/res/layout line 9 Android Lint Problem
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.manishkpr.viewpagerimagegallery"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.manishkpr.viewpagerimagegallery.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
If there is only a "yellow lamp" icon beside that line, then it's just a warning. Your program will run smoothly regardless, but it simply states that the intent is not used anywhere in your program (it's placed there unnecessarily) so you should try removing that line. If your program still runs smoothly, you are done.

How to create map tiles from OpenStreetMap offline, display it on Android?

What I want is to display a simple offline map using OpenStreetMap. I cannot find in the web the right tools to create map tiles and use it to display a map in Android. I have downloaded different resources but it seems that I don't have any idea where to start. I want to integrate images from OpenStreetMap using JOSM but i don't know if I can use it on Android.
Can I use Mapnik? Your help will a great thank you.
I'm currently developing (my first) Android application using the OpenStreetMap (OSM) API, so while I can't help you with the JSOM, I can try to help with the OSM part:
Assuming that you want to create a new activity in your android application that simply displays a OSM map, you might start with something like this:
package example.stackoverflow.osmdroid;
import android.app.Activity;
import android.os.Bundle;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
public class YourMap extends Activity {
// The MapView variable:
private MapView m_mapView;
// Default map zoom level:
private int MAP_DEFAULT_ZOOM = 15;
// Default map Latitude:
private double MAP_DEFAULT_LATITUDE = 38.535350;
// Default map Longitude:
private double MAP_DEFAULT_LONGITUDE = -121.753807;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Specify the XML layout to use:
setContentView(R.layout.osm_map);
// Find the MapView controller in that layout:
m_mapView = (MapView) findViewById(R.id.mapview);
// Setup the mapView controller:
m_mapView.setBuiltInZoomControls(true);
m_mapView.setMultiTouchControls(true);
m_mapView.setClickable(true);
m_mapView.setUseDataConnection(false);
m_mapView.getController().setZoom(MAP_DEFAULT_ZOOM);
m_mapView.getController().setCenter(
new GeoPoint(MAP_DEFAULT_LATITUDE, MAP_DEFAULT_LONGITUDE));
m_mapView.setTileSource(TileSourceFactory.MAPNIK);
} // end onCreate()
} // end class YourMap
Where your osm_map.xml layout may look something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.osmdroid.views.MapView
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:enabled="true"
android:clickable="true"
/>
</RelativeLayout>
As for the actual map tiles, there is a really cool program called Mobile Atlas Creator, which allows you to generate the necessary map tiles for the offline Android map implemented above.
Once you have the application installed, and you want to create a new atlas, you'll be asked to select your "desired altas format." When this pops up, select "Osmdroid zip."
Once everything loads, select a region on the map that you would like to create tiles for, select the zoom levels you want tiles for, and hit the "Add Selection" button in the column on the left, followed by "Create Atlas."
Oh, and depending on the source, you may need to check the "Create/Adjust Map tiles" checkbox to force the tiles to be exported as PNGs -- does anyone know if it's possible to use JPG with OSM?
Once the ZIP has been generated, I renamed it to "Mapnik.zip" and moved it to a newly created folder called "tiles" in my Eclipse Android project workspace. In order to get it working, I also had to open the zip file, and rename the top level folder from something like "Google Earth" (depending on the map source you used), to "Mapnik," in order for the tile to display in my Android application.
In order to actually load the tiles onto your phone, however, you'll need to use the ADB tool from the terminal. In your ADB tool directory, you'll want to run something like this (each line is a new command):
./adb shell rm -r /sdcard/osmdroid/
./adb shell mkdir /sdcard/osmdroi/
./adb push ~/path/to/your/mapnik.zip /sdcard/osmdroid
Depending on the size of the map and the speed of the phone's memory bus, this last step may take a several minutes to an hour to complete. Once done, your map should work -- I hope!
As I mentioned, this is the first time I've used the OSM API, so I'm by no means an expert on it, and I can only comment on what worked for me.
Hope this will help you get started!
EDIT:
I didn't have a chance to actually run the code that I wrote up yesterday, so I didn't catch a few of the errors. I just created a new project in Eclipse, dumped my code in there, fixed a few things and got it up and running. All changes that I made are reflected in the code above! I forgot several of the basic import statements, and I forgot to add permissions to the manifest.xml file.
The last few lines of my manifest.xml now look like this:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
And you also might want to add this to the manifest, although certainly not critical:
<supports-screens
android:anyDensity="true"
android:resizeable="false"
android:largeScreens="true"
android:normalScreens="true"
/>
Add this right after the <uses-sdk ... /> part.
Furthermore, be sure to import the following two JAR libraries:
osmdroid-android-3.0.3.jar // Or whatever version you're using...
and
slf4j-android-1.5.8.jar // Or whatever the latest version is...
Without this last JAR, my code kept crashing until I remembered to include it.
Make sure to modify the default coordinates so that they point to a location that you actually have map tiles for, otherwise you're not going to see much of anything, aside from a white canvas.
Sorry for not running the code on my end first!
Here is a step by step solution:
In brief:
1- You must download map tiles using Mobile Atlas Creator. I have explained the steps HERE
2- Move the resulting zip-file to /mnt/sdcard/osmdroid/ on your device.
3- Adding osmdroid-android-XXX.jar and slf4j-android-1.5.8.jar into build path your project
4- Adding MapView: You can add a MapView to your xml layout
<org.osmdroid.views.MapView
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tilesource="Mapnik"
/>
Or create a MapView programmatically:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mResourceProxy = new ResourceProxyImpl(inflater.getContext().getApplicationContext());
mMapView = new MapView(inflater.getContext(), 256, mResourceProxy);
return mMapView;
}
Don't forget to add these permissions to your Manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This is a good Sample Project.
Hope it Helps ;)
Important
As #Scai mentioned: recently Open Street Map announced that this tool is not good and had some problems:
This tool results in heavy traffic for the OSM tile servers and is likely to be blocked.
Please don't use it.
Alternatively to map tiles you can also use vector data for your offline map, for example mapsforge or the Mapbox Android SDK. For more information consult the OSM wiki about offline OSM and Android libraries.

Categories