I've follow tutorial to create simple android map, here's my source code (MainActivity.java) :
package com.tugas.akhir;
import java.util.List;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.CancelableCallback;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.tugas.akhir.R;
import com.tugas.akhir.googlemaps.GMapV2Direction;
import com.tugas.akhir.googlemaps.GetRotueListTask;
import com.tugas.akhir.googlemaps.GMapV2Direction.DirecitonReceivedListener;
import android.support.v4.app.FragmentActivity;
/**
*
* #author Omer F. KAPLAN
*
*/
public class MapActivity extends FragmentActivity
implements OnClickListener, OnInfoWindowClickListener,
DirecitonReceivedListener {
private GoogleMap mMap;
private Button btnDirection;
LatLng startPosition;
String startPositionTitle;
String startPositionSnippet;
LatLng destinationPosition;
String destinationPositionTitle;
String destinationPositionSnippet;
ToggleButton tbMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startPosition = new LatLng(41.036896, 28.985490);
startPositionTitle = "Taksim Square";
startPositionSnippet = "Istanbul / Turkey";
destinationPosition = new LatLng(41.005921, 28.977737);
destinationPositionTitle = "Sultanahmet Mosque, Istanbul";
destinationPositionSnippet = "Istanbul / Turkey";
btnDirection = (Button) findViewById(R.id.btnDirection);
btnDirection.setOnClickListener(this);
tbMode = (ToggleButton) findViewById(R.id.tbMode);
tbMode.setChecked(true);
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the
// map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.setMyLocationEnabled(true);
mMap.setIndoorEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.getUiSettings().setCompassEnabled(true);
mMap.getUiSettings().setAllGesturesEnabled(true);
mMap.setOnInfoWindowClickListener(this);
}
public void clearMap() {
mMap.clear();
}
#Override
public void onClick(View v) {
if (v == btnDirection) {
clearMap();
MarkerOptions mDestination = new MarkerOptions()
.position(destinationPosition)
.title(destinationPositionTitle)
.snippet(destinationPositionSnippet)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin1));
MarkerOptions mStart = new MarkerOptions()
.position(startPosition)
.title(startPositionTitle)
.snippet(startPositionSnippet)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin2));
mMap.addMarker(mDestination);
mMap.addMarker(mStart);
if (tbMode.isChecked()) {
new GetRotueListTask(MapActivity.this, startPosition,
destinationPosition, GMapV2Direction.MODE_DRIVING, this)
.execute();
} else {
new GetRotueListTask(MapActivity.this, startPosition,
destinationPosition, GMapV2Direction.MODE_WALKING, this)
.execute();
}
}
}
#Override
public void OnDirectionListReceived(List<LatLng> mPointList) {
if (mPointList != null) {
PolylineOptions rectLine = new PolylineOptions().width(10).color(
Color.RED);
for (int i = 0; i < mPointList.size(); i++) {
rectLine.add(mPointList.get(i));
}
mMap.addPolyline(rectLine);
CameraPosition mCPFrom = new CameraPosition.Builder()
.target(startPosition).zoom(15.5f).bearing(0).tilt(25)
.build();
final CameraPosition mCPTo = new CameraPosition.Builder()
.target(destinationPosition).zoom(15.5f).bearing(0)
.tilt(50).build();
changeCamera(CameraUpdateFactory.newCameraPosition(mCPFrom),
new CancelableCallback() {
#Override
public void onFinish() {
changeCamera(CameraUpdateFactory
.newCameraPosition(mCPTo),
new CancelableCallback() {
#Override
public void onFinish() {
LatLngBounds bounds = new LatLngBounds.Builder()
.include(startPosition)
.include(
destinationPosition)
.build();
changeCamera(
CameraUpdateFactory
.newLatLngBounds(
bounds, 50),
null, false);
}
#Override
public void onCancel() {
}
}, false);
}
#Override
public void onCancel() {
}
}, true);
}
}
/**
* Change the camera position by moving or animating the camera depending on
* input parameter.
*/
private void changeCamera(CameraUpdate update, CancelableCallback callback,
boolean instant) {
if (instant) {
mMap.animateCamera(update, 1, callback);
} else {
mMap.animateCamera(update, 4000, callback);
}
}
#Override
public void onInfoWindowClick(Marker selectedMarker) {
if (selectedMarker.getTitle().equals(startPositionTitle)) {
Toast.makeText(this, "Marker Clicked: " + startPositionTitle,
Toast.LENGTH_LONG).show();
} else if (selectedMarker.getTitle().equals(destinationPositionTitle)) {
Toast.makeText(this, "Marker Clicked: " + destinationPositionTitle,
Toast.LENGTH_LONG).show();
}
selectedMarker.hideInfoWindow();
}
#Override
protected void onResume() {
super.onResume();
}
}
Beside MainActivity.java, i write down GetRotueListTask.java, here's source code :
package com.tugas.akhir.googlemaps;
import java.util.List;
import android.app.ProgressDialog;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.widget.Toast;
import com.google.android.gms.maps.model.LatLng;
import com.tugas.akhir.googlemaps.GMapV2Direction.DirecitonReceivedListener;
public class GetRotueListTask extends AsyncTask<Void, Void, Void> {
private final Context mContext;
GMapV2Direction mGMDirection = new GMapV2Direction();
LatLng fromPosition;
LatLng toPosition;
List<LatLng> mPointList;
private ProgressDialog dialog;
private int mDirectionMode;
DirecitonReceivedListener mListener;
public GetRotueListTask(Context context, LatLng fromPosition,
LatLng toPosition, int mDirectionMode,
DirecitonReceivedListener mListener) {
this.mContext = context;
this.fromPosition = fromPosition;
this.toPosition = toPosition;
this.mDirectionMode = mDirectionMode;
this.mListener = mListener;
}
#Override
protected Void doInBackground(Void... params) {
mGMDirection.setParams(fromPosition, toPosition, mDirectionMode);
mPointList = mGMDirection.getPointList(this.mContext);
return null;
}
#Override
protected void onPostExecute(Void result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (mPointList != null) {
mListener.OnDirectionListReceived(mPointList);
} else {
Toast.makeText(this.mContext, "Error downloading direction!",
Toast.LENGTH_LONG).show();
}
}
#Override
protected void onPreExecute() {
ConnectivityManager conMgr = (ConnectivityManager) mContext
.getApplicationContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
if (conMgr.getActiveNetworkInfo() != null
&& conMgr.getActiveNetworkInfo().isAvailable()
&& conMgr.getActiveNetworkInfo().isConnectedOrConnecting()) {
// Background: Connected to internet
dialog = new ProgressDialog(mContext);
dialog.setMessage("Downloading directions...");
dialog.show();
} else {
this.cancel(true);
Toast.makeText(mContext, "Not connected to internet!",
Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCancelled() {
super.onCancelled();
}
}
After that i according tutorial, i write GMapV2Direction.java :
package com.tugas.akhir.googlemaps;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;
/**
* #author KAPLANDROID
*/
public class GMapV2Direction {
LatLng src, dest;
public List<LatLng> pointToDraw;
public static final int MODE_DRIVING = 1;
public static final int MODE_WALKING = 2;
public int mDirectionMode;
public void setParams(LatLng src, LatLng dest, int mMode) {
this.src = src;
this.dest = dest;
this.mDirectionMode = mMode;
}
public List<LatLng> getPointList(Context mContext) {
if (src != null || dest != null) {
// connect to map web service
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(makeUrl(src, dest));
HttpResponse response;
try {
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = null;
is = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
reader.close();
String result = sb.toString();
JSONObject jsonObject = new JSONObject(result);
JSONArray routeArray = jsonObject.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
pointToDraw = decodePoly(encodedString);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return pointToDraw;
} else {
throw new NullPointerException(
"Source or Destination coordinate is null. You must call \"setParams(LatLng,LatLng)\" method first!");
}
}
private List<LatLng> decodePoly(String poly) {
int len = poly.length();
int index = 0;
List<LatLng> decoded = new LinkedList<LatLng>();
int lat = 0;
int lng = 0;
while (index < len) {
int b;
int shift = 0;
int result = 0;
do {
b = poly.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = poly.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
decoded.add(new LatLng((lat / 1E5), (lng / 1E5)));
}
return decoded;
}
private String makeUrl(LatLng src, LatLng dest) {
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
// from
urlString.append("?origin=");
urlString.append(Double.toString((double) src.latitude));
urlString.append(",");
urlString.append(Double.toString((double) src.longitude));
// to
urlString.append("&destination=");
urlString.append(Double.toString((double) dest.latitude));
urlString.append(",");
urlString.append(Double.toString((double) dest.longitude));
urlString.append("&sensor=false&units=metric");
if (mDirectionMode == MODE_DRIVING) {
urlString.append("&mode=driving");
} else if (mDirectionMode == MODE_WALKING) {
urlString.append("&mode=walking");
}
Log.d("Request URL", "URL=" + urlString.toString());
return urlString.toString();
}
public interface DirecitonReceivedListener {
public void OnDirectionListReceived(List<LatLng> mPointList);
}
}
Then i write a layout like this :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<fragment
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="5dp"
class="com.google.android.gms.maps.SupportMapFragment"
/>
<ToggleButton
android:id="#+id/tbMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/map"
android:layout_toRightOf="#+id/btnDirection"
android:textOff="Walking"
android:textOn="Driving" />
<Button
android:id="#+id/btnDirection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/map"
android:layout_alignTop="#+id/map"
android:layout_marginLeft="62dp"
android:text="#string/getdirection" />
</RelativeLayout>
Finally, i add some code to AndroidManifest as shown bellow :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tugas.akhir"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Requaired Permissions for Google Maps V2 - Start - Kaplandroid -->
<permission
android:name="com.tugas.akhir.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<!-- External storage for caching. -->
<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="com.tugas.akhir.permission.MAPS_RECEIVE" />
<!-- Maps API needs OpenGL ES 2.0. -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<!-- Requaired Permissions for Google Maps V2 - End - Kaplandroid -->
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- API KEY for Google Maps V2 - Start - Kaplandroid -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="-------- MY GOOGLE API KEY -------------" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<!-- API KEY for Google Maps V2 - End - Kaplandroid -->
<activity
android:name="com.tugas.akhir.MapActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Later i export it to .apk file, then install it to my device. But,... when i open it, it didnt show any maps, it only show plus & minus button, there is nothing except those button. I've search to internet, it said that my problem is put this code to my AndroidManifest :
<uses-permission android:name="android.permission.INTERNET" />
I've put that code, but it still doesnt show any maps, the some article said that the problem is reference to google play library. I've successfull reference my project to google-play-service library, but it's still failed. Anyone can help to fix my problem, please ??? thank you very much
It looks like your sha1 hash of your certificates or packageId you use is incorrectly set up in google api console for your maps. It's important to use proper sha1 hash and right package id. Also note you may also want to add your debug certificate as well.
It may problem with your API key mentioned in your Android Manifest file. Make sure that it was generated with correct SHA-1 key + your package name mentioned in the android manifest file..
And also check whether Google Maps Android API V2 is turned on in Google APIs Console located in services tab.
Note: After generating new API key uninstall your old app in the device and try again with new installation.
You must change APIKEY value with your own APIKEY as mentioned on Manifest file
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="-------- MY GOOGLE API KEY -------------" />
Related
I want to show directions in google map (android studio , java)
package com.example.travel;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.directions.route.AbstractRouting;
import com.directions.route.Route;
import com.directions.route.RouteException;
import com.directions.route.Routing;
import com.directions.route.RoutingListener;
import com.example.travel.items.SavePathInput;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.maps.DirectionsApiRequest;
import com.google.maps.GeoApiContext;
import com.google.maps.PendingResult;
import com.google.maps.internal.PolylineEncoding;
import com.google.maps.model.DirectionsResult;
import com.google.maps.model.DirectionsRoute;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import static androidx.constraintlayout.motion.utils.Oscillator.TAG;
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback,RoutingListener,GoogleApiClient.OnConnectionFailedListener {
private FragmentManager fragmentManager;
private MapFragment mapFragment;
private String email = MainActivity.useremail;
private GoogleMap mMap;
private Geocoder geocoder;
private Button button , bt_searchpath , bt_savepath;
private EditText editText;
Polyline polyline = null;
List<LatLng> latLngList = new ArrayList<>();
private ArrayList<UserLocation> clickedPath = new ArrayList<>();
private List<Polyline> polylines = null;
private String place;
private Retrofit retrofit;
private RetrofitInterface retrofitInterface;
public static String BASE_URL ;
private GeoApiContext mGeoApiContext = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
editText = (EditText) findViewById(R.id.editText);
button=(Button)findViewById(R.id.button);
bt_searchpath = (Button)findViewById(R.id.bt_pathsearch);
bt_savepath = (Button)findViewById(R.id.bt_pathsave);
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofitInterface = retrofit.create(RetrofitInterface.class);
Intent intent = getIntent();
place = intent.getStringExtra("place");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if(mGeoApiContext == null){
mGeoApiContext = new GeoApiContext.Builder()
.apiKey(GoogleApikey)
.build();
}
bt_searchpath.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(latLngList.size() >= 3) {
for (int i = 0; i < latLngList.size() - 2; i++) {
//calculateDirections(latLngList.get(i) , latLngList.get(i+1));
}
}else if(latLngList.size() == 2){
calculateDirections(latLngList.get(0) , latLngList.get(1));
}else if(latLngList.size() == 1){
Toast.makeText(MapActivity.this, "click at least two places", Toast.LENGTH_SHORT).show();
}
}
});
}
private void calculateDirections(LatLng start , LatLng end){
Log.d(TAG, "calculateDirections: calculating directions.");
com.google.maps.model.LatLng destination = new com.google.maps.model.LatLng(
end.latitude,
end.longitude
);
DirectionsApiRequest directions = new DirectionsApiRequest(mGeoApiContext);
directions.alternatives(true);
directions.origin(
new com.google.maps.model.LatLng(
start.latitude,
start.longitude
)
);
Log.d(TAG, "calculateDirections: destination: " + destination.toString());
directions.destination(destination).setCallback(new PendingResult.Callback<DirectionsResult>() {
#Override
public void onResult(DirectionsResult result) {
Log.d(TAG, "onResult: routes: " + result.routes[0].toString());
Log.d(TAG, "onResult: duration :" + result.routes[0].legs[0].duration);
Log.d(TAG, "onResult: distance :" +result.routes[0].legs[0].distance);
Log.d(TAG, "onResult: geocodedWayPoints: " + result.geocodedWaypoints[0].toString());
addPolylinesToMap(result);
}
#Override
public void onFailure(Throwable e) {
Log.e(TAG, "onFailure: " + e.getMessage() );
}
});
}
private void addPolylinesToMap(final DirectionsResult result){
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Log.d(TAG, "run: result routes: " + result.routes.length);
for(DirectionsRoute route: result.routes){
Log.d(TAG, "run: leg: " + route.legs[0].toString());
List<com.google.maps.model.LatLng> decodedPath = PolylineEncoding.decode(route.overviewPolyline.getEncodedPath());
List<LatLng> newDecodedPath = new ArrayList<>();
for(com.google.maps.model.LatLng latLng: decodedPath){
newDecodedPath.add(new LatLng(
latLng.lat,
latLng.lng
));
}
Polyline polyline = mMap.addPolyline(new PolylineOptions().addAll(newDecodedPath));
polyline.setColor(R.color.colorPrimaryDark);
polyline.setClickable(true);
}
}
});
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
geocoder = new Geocoder(this);
button.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v){
String str = editText.getText().toString();
List<Address> addressList = null;
try {
addressList = geocoder.getFromLocationName(
str,
10);
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println(addressList.get(0).toString());
String []splitStr = addressList.get(0).toString().split(",");
String address = splitStr[0].substring(splitStr[0].indexOf("\"") + 1,splitStr[0].length() - 2);
System.out.println(address);
String latitude = splitStr[10].substring(splitStr[10].indexOf("=") + 1);
String longitude = splitStr[12].substring(splitStr[12].indexOf("=") + 1);
System.out.println(latitude);
System.out.println(longitude);
LatLng point = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude));
MarkerOptions mOptions2 = new MarkerOptions();
mOptions2.title(str);
mOptions2.snippet(address);
mOptions2.position(point);
mMap.addMarker(mOptions2);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(point,15));
UserLocation location = new UserLocation(str , latitude , longitude);
clickedPath.add(location);
LatLng latLng = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude));
latLngList.add(latLng);
}
});
List<Address> addressList = null;
try {
addressList = geocoder.getFromLocationName(
place,
10);
}
catch (IOException e) {
e.printStackTrace();
}
String []splitStr = addressList.get(0).toString().split(",");
String latitude = splitStr[10].substring(splitStr[10].indexOf("=") + 1);
String longitude = splitStr[12].substring(splitStr[12].indexOf("=") + 1);
LatLng startCity = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(startCity,13));
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.travel">
<uses-permission android:name="android:permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/travel"
android:label="#string/app_name"
android:roundIcon="#drawable/travel"
android:supportsRtl="true"
android:theme="#style/Theme.Travel"
android:usesCleartextTraffic="true">
<activity android:name=".SplashActivity">
</activity>
<activity android:name=".OtherPathActivity" />
<activity android:name=".MapActivity" />
<activity android:name=".UserPathActivity" />
<activity android:name=".UserPlaceActivity" />
<activity android:name=".MainActivity" />
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="my api key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.example.travel"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'com.github.jd-alexander:library:1.1.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.gms:play-services-maps:17.0.1'
implementation 'com.google.android.libraries.places:places:2.4.0'
implementation 'com.google.maps.android:android-maps-utils:2.2.5'
implementation 'com.google.android.gms:play-services-location:18.0.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//google directions
implementation 'com.google.maps:google-maps-services:0.18.2'
implementation 'org.slf4j:slf4j-simple:1.7.25'
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.6.2' //
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.google.code.gson:gson:2.8.5' //GSON
implementation 'com.github.john990:WaveView:v0.9'
implementation 'com.github.bumptech.glide:glide:4.11.0'
}
In this activity , user pick more than two places, and these places are added to List latLngList .
When click the 'bt_searchpath', 'calculateDirections(LatLng start, LatLng end)' is called.
But I can't see the Logs which are in directions.destination(destination).setCallback(new PendingResult.Callback() , and of course when I run app, direction does not appear.
How to solve this problem?
I appreciate your answers.
Have you generated and connected with the google api key for Directions? and had paid for it?
However, I try only when my app has a launcher property will the activity detect the NFC intent. Even if I have a intent filter in another application. Here is my manifest and both the activities. I even have foreground dispatch managed.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.melin.vustudentattendence">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".AddStudentsActivity"></activity>
<activity android:name=".AddClassesActivity" />
<activity android:name=".AddTeachersActivity" />
<activity android:name=".TestActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
<activity android:name=".ClassAttendenceActivity">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
<activity
android:name=".LecutererClassesListActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity android:name=".InstituteDashboardActivity" />
<activity android:name=".TodaysClassesActivity" />
<activity
android:name=".LecturerDashboardActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".LoginActivity"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This is my TestActivity.java
package com.melin.vustudentattendence;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ClipDescription;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class TestActivity extends AppCompatActivity {
public static final String TAG="NFCDemo";
private TextView mTextView;
private NfcAdapter mNfcAdapter;
public class NdefReaderTask extends AsyncTask<Tag,Void,String> {
#Override
protected String doInBackground(Tag... params) {
Tag tag = params[0];
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
// NDEF is not supported by this Tag.
return null;
}
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
NdefRecord[] records = ndefMessage.getRecords();
for (NdefRecord ndefRecord : records) {
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
try {
return readText(ndefRecord);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported Encoding", e);
}
}
}
return null;
}
private String readText(NdefRecord record) throws UnsupportedEncodingException {
/*
* See NFC forum specification for "Text Record Type Definition" at 3.2.1
*
* http://www.nfc-forum.org/specs/
*
* bit_7 defines encoding
* bit_6 reserved for future use, must be 0
* bit_5..0 length of IANA language code
*/
byte[] payload = record.getPayload();
// Get the Text Encoding
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
// Get the Language Code
int languageCodeLength = payload[0] & 0063;
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
// e.g. "en"
// Get the Text
return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
mTextView.setText("Read content: " + result);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mTextView=(TextView)findViewById(R.id.textView_explanation);
mNfcAdapter= NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter==null){
Toast.makeText(this,"This device doesn't support NFC",Toast.LENGTH_LONG).show();
finish();
return;
}
if(!mNfcAdapter.isEnabled()){
mTextView.setText("Nfc is disabled");
}else{
mTextView.setText(R.string.explanation);
}
handleIntent(getIntent());
}
#Override
protected void onResume() {
super.onResume();
setupForegroundDispatch(this, mNfcAdapter);
}
#Override
protected void onPause() {
stopForegroundDispatch(this,mNfcAdapter);
super.onPause();
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
// Notice that this is the same filter as in our manifest.
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
try {
filters[0].addDataType(ClipDescription.MIMETYPE_TEXT_PLAIN);
} catch (IntentFilter.MalformedMimeTypeException e) {
throw new RuntimeException("Check your mime type.");
}
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
private void handleIntent(Intent intent){
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (ClipDescription.MIMETYPE_TEXT_PLAIN.equals(type)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
new NdefReaderTask().execute(tag);
} else {
Log.d(TAG, "Wrong mime type: " + type);
}
} else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
// In case we would still use the Tech Discovered Intent
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
String searchedTech = Ndef.class.getName();
for (String tech : techList) {
if (searchedTech.equals(tech)) {
new NdefReaderTask().execute(tag);
break;
}
}
}
}
}
and this is my ClassesAttendenceActivity
package com.melin.vustudentattendence;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ClipDescription;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class ClassAttendenceActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ClassAttendenceRowAdapter adapter;
private List<Student> students=new ArrayList<>();
private FirebaseFirestore fs;
private String incomingIntentData;
private NfcAdapter mNfcAdapter;
private static String TAG="Attendence Activity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_class_attendence);
//check nfc first
mNfcAdapter=NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter==null){
Toast.makeText(this,"This device doesn't support NFC",Toast.LENGTH_LONG).show();
finish();
return;
}
if(!mNfcAdapter.isEnabled()){
Toast.makeText(this,"NFC is disabled.Please enable it",Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "NFC is in reader mode", Toast.LENGTH_SHORT).show();
}
//incomingIntentData=getIntent().getExtras().getString("document");
//fs=FirebaseFirestore.getInstance();
//Toast.makeText(this,incomingIntentData,Toast.LENGTH_LONG).show();
//recyclerView=(RecyclerView)findViewById(R.id.attendenceListRecyclerView);
// LinearLayoutManager layoutManager=new LinearLayoutManager(ClassAttendenceActivity.this);
// recyclerView.setLayoutManager(layoutManager);
// populateStudentList(incomingIntentData);
handleIntent(getIntent());
}
private void populateStudentList(String url){
fs.collection(url+"/students")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Map<String,Object> data=document.getData();
Student student=new Student();
student.setStatus("ABSENT");
for (Map.Entry<String,Object> entry : data.entrySet()){
if(entry.getKey().equals("name")){
student.setName(entry.getValue().toString());
}
if(entry.getKey().equals("student_id")){
student.setStudent_id(entry.getValue().toString());
}
}
students.add(student);
Log.d("List", document.getId() + " => " + document.getData());
}
} else {
Log.d("List", "Error getting documents: ", task.getException());
}
adapter=new ClassAttendenceRowAdapter(students);
recyclerView.setAdapter(adapter);
}
});
}
public void simulatingAnIntent(){
String student_id="101";
for(Student student:students){
if(student.getStudent_id().equals(student_id)){
student.setStatus("PRESENT");
Toast.makeText(ClassAttendenceActivity.this,"Student ID"+student.getStudent_id()+"Detected",Toast.LENGTH_LONG).show();
}
}
adapter=new ClassAttendenceRowAdapter(students);
recyclerView.setAdapter(adapter);
}
#Override
protected void onResume() {
super.onResume();
setupForegroundDispatch(this, mNfcAdapter);
}
#Override
protected void onPause() {
stopForegroundDispatch(this,mNfcAdapter);
super.onPause();
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
// Notice that this is the same filter as in our manifest.
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
try {
filters[0].addDataType(ClipDescription.MIMETYPE_TEXT_PLAIN);
} catch (IntentFilter.MalformedMimeTypeException e) {
throw new RuntimeException("Check your mime type.");
}
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
private void handleIntent(Intent intent){
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (ClipDescription.MIMETYPE_TEXT_PLAIN.equals(type)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
new NdefReaderTask().execute(tag);
} else {
Log.d(TAG, "Wrong mime type: " + type);
}
} else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
// In case we would still use the Tech Discovered Intent
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
String searchedTech = Ndef.class.getName();
for (String tech : techList) {
if (searchedTech.equals(tech)) {
new NdefReaderTask().execute(tag);
break;
}
}
}
}
public class NdefReaderTask extends AsyncTask<Tag,Void,String> {
#Override
protected String doInBackground(Tag... params) {
Tag tag = params[0];
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
// NDEF is not supported by this Tag.
return null;
}
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
NdefRecord[] records = ndefMessage.getRecords();
for (NdefRecord ndefRecord : records) {
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
try {
return readText(ndefRecord);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported Encoding", e);
}
}
}
return null;
}
private String readText(NdefRecord record) throws UnsupportedEncodingException {
/*
* See NFC forum specification for "Text Record Type Definition" at 3.2.1
*
* http://www.nfc-forum.org/specs/
*
* bit_7 defines encoding
* bit_6 reserved for future use, must be 0
* bit_5..0 length of IANA language code
*/
byte[] payload = record.getPayload();
// Get the Text Encoding
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
// Get the Language Code
int languageCodeLength = payload[0] & 0063;
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
// e.g. "en"
// Get the Text
return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
Toast.makeText(ClassAttendenceActivity.this,"Student ID"+result+"Detected",Toast.LENGTH_LONG).show();
// for(Student student:students){
// if(student.getStudent_id().equals(result)){
// student.setStatus("PRESENT");
// Toast.makeText(ClassAttendenceActivity.this,"Student ID"+student.getStudent_id()+"Detected",Toast.LENGTH_LONG).show();
// }
// }
//
// adapter=new ClassAttendenceRowAdapter(students);
// recyclerView.setAdapter(adapter);
}
}
}
}
As you can see both the activities are almost identical
while one reads the data another doesn't
It turns out that using emulated nfc tag was the error.Using real nfc tag worked well.Though no one answered the question I am answering my own question so that when someone encounters this problem they can see this answer.Thank you.
I've tried to replicate/migrade, the AndAR sample code Mr. Nobuyuki Matsui uploaded on GitHub, the "nmatsui / AR_Speeker", which can be downloaded from here, and I get a strange behaviour on Android Studio (0.4.0). The provided code works O.K. in Eclipse (Juno).
The problem is that I can compile without errors in Android Studio, but when I debug to my device, I get a black screen and no functionality at all - no camera preview - no model loading.
What is more, I get no fatal errors in logcat, as long I can interpret those error to my limited knowledge of java/android.
I am asking for someones help here, cause I need to make this code working on Android Studio, so I can build upon it an exercise app within a ~2 weeks deadline.
Does anyone has successfully tried to replicate/migrate the "nmatsui / AR_Speeker" for Android Studio, and can provide me with a GitHub link, maybe?
Thank you all in advance.
Here is the Project (structure):
Here is my Android Manifest (I got an error with the #drawable/icon, which I temporally fix by tools:ignore="MissingApplicationIcon"):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="jp.co.tis.stc"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:maxSdkVersion="10"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<application
android:allowBackup="true"
android:label="AR_Speaker"
tools:ignore="MissingApplicationIcon">
<activity android:name=".AR_SpeakerActivity"
android:clearTaskOnLaunch="true"
android:noHistory="true"
android:screenOrientation="landscape"
android:label="AR_Speaker">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Here is the build.gradle.xml:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.7.+'
}
}
apply plugin: 'android'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile files('libs/AndAR.jar')}
android {
compileSdkVersion 19
buildToolsVersion "19.0.2"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
instrumentTest.setRoot('tests')
}
}
Where I get a warning that "Cannot assign ArrayList<String> to "HashSet<Iterable<?>>' on line 23 and 24.
Here is the main activity AR_SpeakerActivity (all comments are in Japanese, that I cannot interpret!), where shows a warning that 'getWidth()' and 'getHeight()' is deprecated on line 123, 125. What should I do with that?
EDITED as Raghav Sood suggested in lines 123-124 (now 125-133). Still get black screen. Should I still use "Ratio" with this code snippet? How should I edit that?
package jp.co.tis.stc;
import android.app.ProgressDialog;
import android.hardware.Camera.Size;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.WindowManager;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import edu.dhbw.andar.ARToolkit;
import edu.dhbw.andar.AndARActivity;
import edu.dhbw.andobjviewer.graphics.LightingRenderer;
import jp.co.tis.stc.player.Elaine;
import jp.co.tis.stc.player.Porl;
import util.MarkerInfo;
public class AR_SpeakerActivity extends AndARActivity {
private static final float THRESHOLD = 50.0f;
// タップ位置とマーカー中心のズレの許容範囲 ピ ク セル)
private ARToolkit arToolkit;
private GestureDetector gd;
private SoundPool sp;
private float xRatio;
private float yRatio;
private List<PlayerBase> players = new ArrayList<PlayerBase>();
#SuppressWarnings("unchecked")
// AsyncTaskへplayersを可変引数として渡す際に、型パラメータが落ちるという警告を抑制
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gd = new GestureDetector(this, onGestureListener); // タップを検出するDetector
super.setNonARRenderer(new LightingRenderer());
arToolkit = super.getArtoolkit();
players.add(new Porl());
// マーカー・3Dモデル・音声・動作を定義したPlayer "Porl" を追加
players.add(new Elaine());
// マーカー・3Dモデル・音声・動作を定義したPlayer "Elaine" を追加
new ModelLoader().execute(players); // 非同期処理でPlayerを読み込み
}
#Override
protected void onResume() {
super.onResume();
// Activityが前面になったら音声再生用にSoundPoolを作成
sp = new SoundPool(players.size(), AudioManager.STREAM_MUSIC, 0);
sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
// SoundPoolの初期化が完了した際に呼ばれるコールバック関数を定義
#Override
public void onLoadComplete(SoundPool sp, int soundId, int status) {
Log.d("AR_Speaker", String.format("load complete soundId=%d:status=%d", soundId, status));
for (PlayerBase player : players) {
player.notifyLoadComplete(soundId);
// Playerに「このsoundIdの初期化が完了したよ」と通知
}
}
});
for (PlayerBase player : players) {
player.loadSound(this, sp); // すべてのPlayerの音声を読み込む
}
}
#Override
protected void onPause() {
sp.release(); // Activityが背面にまわったらSoundPoolを解放
super.onPause();
}
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e("AR_Speaker", ex.getMessage());
finish();
}
// 非同期処理でPlayerを読み込み
private class ModelLoader extends AsyncTask<List<PlayerBase>, Void, Void> {
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
// 非同期処理開始前にプログレスダイアログを表示
progressDialog = new ProgressDialog(AR_SpeakerActivity.this);
progressDialog.setMessage(AR_SpeakerActivity.this.getString(R.string.loading));
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
}
#Override
protected Void doInBackground(List<PlayerBase>... args) {
try {
for (PlayerBase player : args[0]) {
// Playerの3DモデルをARObjectとしてARToolkitへ登録する
arToolkit.registerARObject(player.getModel3d(getResources()));
}
} catch (Exception e) {
Log.e("AR_Speaker", e.getMessage());
finish();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// ARToolkitによって初期化されたcameraインスタンスから、カメラ座標系のパラメータを取得
Size cameraSize = camera.getParameters().getPreviewSize();
// WindowManagerから、スクリーン座標系のパラメータを取得
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
// スクリーン座標系もカメラ座標系も左上隅が原点位置
// カメラ座標系のX座標をスクリーン座標系のX座標へ変換する係数を計算
// Edit code as Raghav Sood suggested/
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
/**xRatio = (float) display.getWidth() / (float) cameraSize.width;
// カメラ座標系のY座標をスクリーン座標系のY座標へ変換する係数を計算
yRatio = (float) display.getHeight() / (float) cameraSize.height;
// 非同期処理が終了したので、プログレスダイアログを消去*/
progressDialog.dismiss();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);
}
// タップ処理
private final SimpleOnGestureListener onGestureListener = new SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
// タップされた位置をスクリーン座標系として取得
float touchX = e.getX();
float touchY = e.getY();
// 認識しているすべてのマーカーの位置情報を取得
Map<Integer, MarkerInfo> markerInfos = arToolkit.getMarkerInfos();
for (MarkerInfo markerInfo : markerInfos.values()) {
// カメラ座標系でのマーカー位置(マーカーの中心点)を取得
float markerX = markerInfo.getPos()[0];
float markerY = markerInfo.getPos()[1];
// 認識しているマーカーの中心点をカメラ座標系からスクリーン座標系に変換し、
// |マーカーの中心 - タップ位置| < THRESHOLD
// であるかチェック
if (Math.abs(markerX * xRatio - touchX) < THRESHOLD
&& Math.abs(markerY * yRatio - touchY) < THRESHOLD) {
Log.d("AR_Speaker", String.format("marker %s is touched", markerInfo.getFileName()));
for (PlayerBase player : players) {
// すべてのPlayerに、「XXという名前のマーカーがタップされた」と通知
player.notifyTouch(new File(markerInfo.getFileName()).getName(), sp);
}
}
}
return true;
}
};}
And here is the other activity PlayerBase:
package jp.co.tis.stc;
import java.io.BufferedReader;
import java.io.IOException;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.content.res.Resources;
import android.media.SoundPool;
import edu.dhbw.andobjviewer.graphics.Model3D;
import edu.dhbw.andobjviewer.models.Model;
import edu.dhbw.andobjviewer.parser.ObjParser;
import edu.dhbw.andobjviewer.parser.ParseException;
import edu.dhbw.andobjviewer.util.AssetsFileUtil;
import edu.dhbw.andobjviewer.util.BaseFileUtil;
public abstract class PlayerBase {
private static final double MARKER_WIDTH = 80.0;
private static final double[] MARKER_CENTER = new double[] { 0, 0 };
private final String modelFile;
private final String markerFile;
private final int voiceR;
private int soundId;
private boolean loaded = false;
protected boolean doAnimate = false;
public PlayerBase(String modelFile, String markerFile, int voiceR) {
this.modelFile = modelFile;
this.markerFile = markerFile;
this.voiceR = voiceR;
}
// WaveFront形式の3Dモデルファイルを読み込み、ARToolkitが認識できる3Dモデルを構築して返す
public Model3D getModel3d(Resources resource) throws IOException, ParseException {
BaseFileUtil fileUtil = new AssetsFileUtil(resource.getAssets());
Model3D model3D = null;
if (modelFile.endsWith(".obj")) {
ObjParser parser = new ObjParser(fileUtil);
if (fileUtil != null) {
BufferedReader fileReader = fileUtil.getReaderFromName(modelFile);
if (fileReader != null) {
// Wavefront形式の3Dモデルファイルから3Dモデルを構築
Model model = parser.parse("Model", fileReader);
// 3Dモデルファイルとマーカーを指定して、ARToolkitへ登録するためのModel3Dオブジェクトを作成する
model3D = new Model3D(model, markerFile, MARKER_WIDTH, MARKER_CENTER) {
private static final long serialVersionUID = 1L;
// Model3Dに仕掛けたフックの中身を定義
// 実際のanimate処理は、PlayerBaseを継承した具象クラスのanimateメソッドに実装することになる
#Override
protected void animate(GL10 gl) {
PlayerBase.this.animate(gl);
}
};
}
}
}
return model3D;
}
// animate処理の抽象メソッド
protected abstract void animate(GL10 gl);
// SoundPoolへ音声をロードするメソッド
public void loadSound(Context context, SoundPool sp) {
// res/rawに格納した音声ファイルを指定してロードすると、その音声のsoundIdが得られる
// このメソッドは実際のロードが完成する前にリターンする
soundId = sp.load(context, voiceR, 1);
}
// SoundPoolへの音声ロードが完成すると呼ばれるメソッド
public void notifyLoadComplete(int soundId) {
// 自分のsoundIdのロードが完了したのならば、loadedをtrueにする
if (this.soundId == soundId) loaded = true;
}
// マーカーがタップされた際に呼ばれるメソッド
public void notifyTouch(String fileName, SoundPool sp) {
// 自分のマーカーがタップされたのならば、自分のsoundIdを指定して音声を再生し、doAnimateをtrueにする
if (this.markerFile.equals(fileName) && loaded) {
sp.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f);
if (!this.doAnimate) this.doAnimate = true;
}
} }
Application is missing
This is a lint error, and happens because you don't seem to have any Java class extending Application, which is mentioned in your manifest. You can ignore this error as you have done, since this is not a mandatory part of the application.
build.gradle error
This is a known issue with Android Studio. Workarounds can be found in this question.
Deprecated methods
This is because getHeight() and getWidth() were deprecated in API 13. You can use DisplayMetrics:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
I'm developing a app at the moment wich displayes a Map, your gps postition and a marker on this postition. Next Step is to recieve Data from a XML file. The XML I'm trying to use is http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=899d70a29e983f4b&lat=33.58724&lng=130.3986&range=5&order=4
But poorly after launching the app (on a real device, newest version) the app terminates and displays nothing.
LogCat says FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.xmlparser/com.example.xmlparser.MainActivitz}: java.lang.nullPointerException
MainActivity.java
package com.example.xmlparser;
import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends Activity implements LocationListener {
private TextView latituteField;
private TextView longitudeField;
private LocationManager locationManager;
private String provider;
public String url = "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=899d70a29e983f4b&lat=33.58724&lng=130.3986&range=5&order=4";
public EditText feldname, id;
public HandleXml obj;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latituteField = (TextView) findViewById(R.id.TextView02);
longitudeField = (TextView) findViewById(R.id.TextView04);
feldname = (EditText)findViewById(R.id.editText1);
id = (EditText)findViewById(R.id.editText2);
// Get the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the location provider -> use
// default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null)
{
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
}
else
{
latituteField.setText("Location not available");
longitudeField.setText("Location not available");
}
float lat1 = (float) (location.getLatitude()); //Getting the position
float lng1 = (float) (location.getLongitude());
GoogleMap mMap;
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.fragment1)).getMap();
mMap.addMarker(new MarkerOptions()
.position(new LatLng(lat1, lng1))
.title("Your Position"));
LatLng bounds = new LatLng(lat1, lng1);
CameraUpdate cu = CameraUpdateFactory.newLatLng(bounds);
mMap.moveCamera(cu);
}
//Request updates at startup */
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
/* Remove the locationlistener updates when Activity is paused */
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
float lat = (float) (location.getLatitude()); //Getting the ' ''
float lng = (float) (location.getLongitude());
latituteField.setText(String.valueOf(lat));
longitudeField.setText(String.valueOf(lng));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
public void open(View view)
{
feldname.setText(url);
obj = new HandleXml(url);
obj.fetchXML();
while(obj.parsingComplete);
feldname.setText(obj.getFeldName());
id.setText(obj.getId());
}
}
HandleXml.java
package com.example.xmlparser;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class HandleXml {
private String feldname = "name";
private String id = "id";
private String urlString = null;
private XmlPullParserFactory xmlFactoryObject;
public volatile boolean parsingComplete = true;
public HandleXml(String url)
{
this.urlString = url;
}
public String getFeldName()
{
return feldname;
}
public String getId()
{
return id;
}
public void parseXMLAndStoreIt(XmlPullParser myParser)
{
int event;
String text=null;
try
{
event = myParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT)
{
String name=myParser.getName();
switch (event)
{
case XmlPullParser.START_TAG:
break;
case XmlPullParser.TEXT:
text = myParser.getText();
break;
case XmlPullParser.END_TAG:
if(name.equals("name_kana"))
{
feldname = text;
}
else if(name.equals("id"))
{
id =text;// myParser.getAttributeValue(null,"value");
}
else
{}
break;
}
event = myParser.next();
}
parsingComplete = false;
} catch (Exception e) {
e.printStackTrace();
}
}
public void fetchXML()
{
Thread thread = new Thread(new Runnable()
{
#Override
public void run()
{
try
{
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
InputStream stream = conn.getInputStream();
xmlFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlFactoryObject.newPullParser();
myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
, false);
myparser.setInput(stream, null);
parseXMLAndStoreIt(myparser);
stream.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
});
thread.start();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xmlparser"
android:versionCode="1"
android:versionName="1.0" >
<permission
android:name="com.example.map.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-sdk
android:minSdkVersion="12"
android:targetSdkVersion="18" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-permission android:name="com.vogella.android.locationapi.maps.permission.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-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" android:debuggable="true">
<uses-library android:name="com.google.android.maps" />
<activity
android:name="com.example.xmlparser.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>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyC3DipaFNo1EC44rZ8N1AJKVAiUCNOtqZw"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
I really hope one of you can tell me whats wrong with this code as it was working perfectly fine with only the map on it's own and the parser as an own program.
I'm trying to run a my project on the android emulator, the project doesn't have errors, the reference to Facebook SDK was added. But, when i run the application it shows a "onerror" message ..
please anyone can execute my code and tell me the problems (or) give me the solutions
MainActivity.java
package com.example.simplelogin1;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Util;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
public class MainActivity extends Activity implements OnClickListener
{
ImageView button,userImage;
TextView textName;
Button btnShowAccessTokens;
ListView listv;
String FILENAME = "AndroidSSO_data";
String imageURL = "";
String name = "";
String userName = "";
String gender = "";
String _error;
String access_token;
private AsyncFacebookRunner mAsyncRunner=null;
private SharedPreferences mPrefs;
Facebook fb=null;
ArrayList<String> friends_list;
Boolean Connectiontimeout = false;
Bitmap profilePic;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String APP_ID="650535718332424"; //****************************APP_ID************************************
fb=new Facebook(APP_ID);
mAsyncRunner = new AsyncFacebookRunner(fb);
friends_list = new ArrayList<String>();
btnShowAccessTokens = (Button) findViewById(R.id.btn_show_access_tokens);
button=(ImageView) findViewById(R.id.login);
listv=(ListView) findViewById(R.id.listView1);
userImage = (ImageView) findViewById(R.id.imageView1);
textName = (TextView) findViewById(R.id.textView1);
button.setOnClickListener(this);
updateButtonImage();
//***************************Access Token Button*****************************************
btnShowAccessTokens.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
showAccessTokens();
}
});
}
public void showAccessTokens()
{
String access_token = fb.getAccessToken();
Toast.makeText(getApplicationContext(),"Access Token: " + access_token, Toast.LENGTH_LONG).show();
}
//***********************************************************************************
//*****************************Login and Logout Image Button*****************************
private void updateButtonImage()
{
if(fb.isSessionValid())
{
button.setImageResource(R.drawable.logout_button);
}else
{
button.setImageResource(R.drawable.login_button);
}
}
//***************************************************************************************
//**************************Login Onclick Method*****************************************
#Override
public void onClick(View v)
{
if(fb.isSessionValid())
{
//*****************Logout********************
try{
fb.logout(getApplicationContext());
updateButtonImage();
userImage.setVisibility(View.INVISIBLE);
textName.setVisibility(View.INVISIBLE);
btnShowAccessTokens.setVisibility(View.INVISIBLE);
listv.setVisibility(View.INVISIBLE);
}catch (MalformedURLException e)
{
e.printStackTrace();
}catch (IOException e)
{
e.printStackTrace();
}
//************************************************************
}else
{
//**********************Login**********************************
mPrefs = getPreferences(MODE_PRIVATE);
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if (access_token != null)
{
fb.setAccessToken(access_token);
// Making show access tokens button visible
//btnShowAccessTokens.setVisibility(View.VISIBLE);
//listv.setVisibility(View.VISIBLE);
Log.d("FB Sessions", "" + fb.isSessionValid());
}
if (expires != 0)
{
fb.setAccessExpires(expires);
}
{
fb.authorize(this,new String[] {"email","publish_stream"} , new DialogListener()
{
#Override
public void onFacebookError(FacebookError e)
{
Toast.makeText(MainActivity.this, "fbError", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(DialogError e)
{
Toast.makeText(MainActivity.this, "onError", Toast.LENGTH_SHORT).show();
}
#Override
public void onComplete(Bundle values)
{
updateButtonImage();
// Function to handle complete event Edit Preferences and update facebook acess_token
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token",fb.getAccessToken());
editor.putLong("access_expires",fb.getAccessExpires());
editor.commit();
//getting user profile
try {
JSONObject me = new JSONObject(fb.request("me"));
new getFacebookData().execute();
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (JSONException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
//getting users Friend list
mAsyncRunner.request("me/friends", new FriendsRequestListener());
Toast.makeText(getApplicationContext(), "Success ", Toast.LENGTH_LONG).show();
userImage.setVisibility(View.VISIBLE);
textName.setVisibility(View.VISIBLE);
btnShowAccessTokens.setVisibility(View.VISIBLE);
listv.setVisibility(View.VISIBLE);
}
#Override
public void onCancel()
{
Toast.makeText(MainActivity.this, "onCancel", Toast.LENGTH_SHORT).show();
}
});
}
}
}
//***************************************onActivityResult********************************************
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
fb.authorizeCallback(requestCode, resultCode, data);
}
//***********************************getting users Friend list Function*******************************
private class FriendsRequestListener implements RequestListener
{
String friendData;
//Method runs when request is complete
public void onComplete(String response, Object state)
{
Log.v("", "FriendListRequestONComplete");
//Create a copy of the response so i can be read in the run() method.
friendData = response;
Log.v("friendData--", ""+friendData);
//Create method to run on UI thread
MainActivity.this.runOnUiThread(new Runnable()
{
public void run()
{
try
{
//Parse JSON Data
JSONObject json;
json = Util.parseJson(friendData);
//Get the JSONArry from our response JSONObject
JSONArray friendArray = json.getJSONArray("data");
Log.v("friendArray--", ""+friendArray);
for(int i = 0; i< friendArray.length(); i++)
{
JSONObject frnd_obj = friendArray.getJSONObject(i);
friends_list.add(frnd_obj.getString("name")+"~~~"+frnd_obj.getString("id"));
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1,android.R.id.text1, friends_list);
listv.setAdapter(adapter);
} catch (JSONException e)
{
e.printStackTrace();
} catch (FacebookError e)
{
e.printStackTrace();
}
}
});
}
#Override
public void onIOException(IOException e, Object state)
{
}
#Override
public void onFileNotFoundException(FileNotFoundException e,Object state)
{
}
#Override
public void onMalformedURLException(MalformedURLException e,Object state)
{
}
#Override
public void onFacebookError(FacebookError e, Object state)
{
}
}
//**********************************************************************************************
//**************Async class for getting facebook data in background thread**********************
public class getFacebookData extends AsyncTask<String, Void, String>
{
ProgressDialog pd = null;
#Override
protected void onPreExecute(){
pd = ProgressDialog.show(MainActivity.this, "Please wait","Loading please wait..", true);
pd.setCancelable(true);
}
#Override
protected String doInBackground(String... params){
fbUserProfile();
return null;
}
#Override
protected void onPostExecute(String result){
pd.dismiss();
if (Connectiontimeout != true)
{
textName.setText(name);
userImage.setImageBitmap(profilePic);
} else {
Toast.makeText(MainActivity.this, "Connection Time out",Toast.LENGTH_SHORT).show();
}
}
}
//**********************************************************************************************************
//**********************getting user facebook data from facebook server****************************************
public void fbUserProfile()
{
try{
access_token = mPrefs.getString("access_token", null);
JSONObject jsonObj = null;
JSONObject jsonObjData = null;
JSONObject jsonObjUrl = null;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 50000);
HttpConnectionParams.setSoTimeout(httpParameters, 50000);
HttpClient client = new DefaultHttpClient(httpParameters);
String requestURL = "https://graph.facebook.com/me?fields=picture,id,name&access_token="+ access_token;
Log.i("Request URL:", "---" + requestURL);
HttpGet request = new HttpGet(requestURL);
HttpResponse response = client.execute(request);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String webServiceInfo = "";
while ((webServiceInfo = rd.readLine()) != null)
{
Log.i("Service Response:", "---" + webServiceInfo);
jsonObj = new JSONObject(webServiceInfo);
jsonObjData = jsonObj.getJSONObject("picture");
jsonObjUrl = jsonObjData.getJSONObject("data");
name = jsonObj.getString("name");
userName = jsonObj.getString("username");
gender = jsonObj.getString("gender");
imageURL = jsonObjUrl.getString("url");
profilePic = BitmapFactory.decodeStream((InputStream) new URL(imageURL).getContent());
}
} catch (Exception e)
{
Connectiontimeout = true;
}
}
//***********************************************************************************************************
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/login_button"/>
<Button
android:id="#+id/btn_show_access_tokens"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Token"
android:visibility="invisible" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/btn_show_access_tokens"
android:visibility="invisible">
</ListView>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/login"
android:src="#drawable/ic_launcher"
android:visibility="invisible" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/listView1"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/btn_show_access_tokens"
android:layout_toRightOf="#+id/imageView1"
android:text="Name"
android:visibility="invisible"/>
</RelativeLayout>
manifest.file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.simplelogin1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.simplelogin1.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>
in my drawable folder:
login_button
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- When selected -->
<item android:drawable="#drawable/login"
android:state_selected="true" />
<!-- When not selected-->
<item android:drawable="#drawable/login_down" />
</selector>
logout_button
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- When selected -->
<item android:drawable="#drawable/logout"
android:state_selected="true" />
<!-- When not selected-->
<item android:drawable="#drawable/logout_down" />
</selector>
my logcat:
12-26 15:07:01.189: D/Facebook-WebView(8330): Webview loading URL: https://m.facebook.com/dialog/oauth?display=touch&client_id=650535718332424&scope=email%2Cpublish_stream&type=user_agent&redirect_uri=fbconnect%3A%2F%2Fsuccess
12-26 15:07:01.309: D/Facebook-authorize(8330): Login failed: com.facebook.android.DialogError: The connection to the server was unsuccessful.
12-26 15:07:01.329: D/Facebook-WebView(8330): Webview loading URL: https://m.facebook.com/dialog/oauth?display=touch&client_id=650535718332424&scope=email%2Cpublish_stream&type=user_agent&redirect_uri=fbconnect%3A%2F%2Fsuccess
please anyone can help me...