Using facebook graph api to retrieve feeds of a page - java

I am developing an application for a customer, and I have read in app (android platform) posts which he (customer) publishes on a fan page.
I created the method below and when I use the keyword /me runs and got the output to my personal information, but when I use the keyword "729745317037227/feed/" the app closes and returns nothing.
new GraphRequest(
AccessToken.getCurrentAccessToken(),
"729745317037227/feed/",
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
Toast.makeText(
getApplicationContext(),
response.getJSONObject()
+ "",
Toast.LENGTH_SHORT).show();
}
}
).executeAsync();
The entire code, I'm putting in the main, for now I'm just trying to make queries and display the results for later use in fragments.
Main class
package com.clubee.marketnow;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.HttpMethod;
import com.facebook.Profile;
import com.facebook.appevents.AppEventsLogger;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
public class MainActivity extends Activity {
private TextView mainTextView;
private static final int request_code = 5;
public CallbackManager mCallbackManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
mCallbackManager = CallbackManager.Factory.create();
setContentView(R.layout.activity_main);
LoginButton loginButton = (LoginButton) findViewById(R.id.login_button);
mainTextView = (TextView) findViewById(R.id.lol);
loginButton.setReadPermissions("user_friends");
LoginManager.getInstance().logOut(); //ensures that whenever we start the app we're logged out
LoginManager.getInstance().registerCallback(mCallbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
Profile curProfile = Profile.getCurrentProfile();
startNewIntent(curProfile);
new GraphRequest(
AccessToken.getCurrentAccessToken(),
"729745317037227/feed/",
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
Toast.makeText(
getApplicationContext(),
response.getJSONObject()
+ "",
Toast.LENGTH_SHORT).show();
}
}
).executeAsync();
}
#Override
public void onCancel() {
// App code
mainTextView.setText("Status: Logging in cancelled");
}
#Override
public void onError(FacebookException exception) {
// App code
mainTextView.setText("Status: EXCEPTION: " + exception.toString());
}
});
}
private void startNewIntent(Profile elUsero){
Intent i = new Intent(this, RetornoFacebook.class);
i.putExtra("firstName", elUsero.getFirstName());
i.putExtra("lastName", elUsero.getLastName());
i.putExtra("picURI", elUsero.getProfilePictureUri(1500,1500).toString());
startActivityForResult(i, request_code);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onResume() {
super.onResume();
// Logs 'install' and 'app activate' App Events.
AppEventsLogger.activateApp(this);
}
#Override
protected void onPause() {
super.onPause();
// Logs 'app deactivate' App Event.
AppEventsLogger.deactivateApp(this);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mCallbackManager.onActivityResult(requestCode, resultCode, data);
if ((requestCode == request_code) && (resultCode == RESULT_OK)) {
LoginManager.getInstance().logOut();
mainTextView.setText("Status: Logged Out!");
}
}
}
Can anyone help me understand how I do to return the feed of a fan page?
I am racking my brain for weeks with this and do not know where I am going wrong. I have read a million times the fb documentation, and the max I got it the current result.
PS: When I do research in graph api explorer, using the same key (729745317037227/feed/), the return is a success.
tks a lot

The issue could be because of the type of access token that you are using.
"/me runs and got the output to my personal information": Call to this edge needs a User Access Token with the appropriate permissions.
"when I use the keyword "729745317037227/feed/" the app closes and returns nothing": Call to this edge needs a Page Access Token with the appropriate permissions. You might be using a User Access Token here.
Page Access Token – These access tokens are similar to user access
tokens, except that they provide permission to APIs that read, write
or modify the data belonging to a Facebook Page.

Related

WebChromeClient doesn't ask for location permission anymore

I have an Android App which uses WebView to show a map on Open Street Map and few weeks stop working properly.
A few weeks ago when the user tap on show my location on the web page Android shows a prompt to allow the app to load the current position but at the moment just an error is shown: Geolocation error: user denied Geolocation.
I looked here on SO and on Google to find if some part of my code became deprecated or blocked but I didn't find anything useful. The only information I found was about ActionBarActivity but also using AppCompatActivity the problem was the same.
The MVP version of the MainActivity is the following (I deleted other unuseful lines for this example):
package com.vinaysomawat.careerhigh;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
public class MainActivity extends ActionBarActivity {
public String mGeolocationOrigin;
public GeolocationPermissions.Callback mGeolocationCallback;
private static final int REQUEST_FINE_LOCATION=0;
public class GeoWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// When user clicks a hyperlink, load in the existing WebView
view.loadUrl(url);
return true;
}
}
public class GeoWebChromeClient extends WebChromeClient {
#Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
String perm = Manifest.permission.ACCESS_FINE_LOCATION;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
ContextCompat.checkSelfPermission(MainActivity.this, perm) == PackageManager.PERMISSION_GRANTED) {
// we're on SDK < 23 OR user has already granted permission
callback.invoke(origin, true, false);
} else {
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, perm)) {
// ask the user for permission
ActivityCompat.requestPermissions(MainActivity.this, new String[] {perm}, REQUEST_FINE_LOCATION);
// we will use these when user responds
mGeolocationOrigin = origin;
mGeolocationCallback = callback;
}
}}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_FINE_LOCATION:
boolean allow = false;
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// user has allowed this permission
allow = true;
}
if (mGeolocationCallback != null) {
// call back to web chrome client
mGeolocationCallback.invoke(mGeolocationOrigin, allow, false);
}
break;
}
}
WebView mywebview;
#Override
protected void onCreate(Bundle savedInstanceState) {
//Hide TopBar
getSupportActionBar().hide();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mywebview = (WebView)findViewById(R.id.webView);
WebSettings webSettings = mywebview.getSettings();
// Empty Cache
mywebview.clearCache(true);
// Hide Zoom buttons
mywebview.getSettings().setDisplayZoomControls(false);
mywebview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mywebview.getSettings().setBuiltInZoomControls(true);
mywebview.setWebViewClient(new GeoWebViewClient());
// Below required for geolocation
mywebview.getSettings().setJavaScriptEnabled(true);
mywebview.getSettings().setGeolocationEnabled(true);
mywebview.setWebChromeClient(new GeoWebChromeClient());
mywebview.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, android.os.Message resultMsg)
{
WebView.HitTestResult result = view.getHitTestResult();
String data = result.getExtra();
Context context = view.getContext();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(data));
context.startActivity(browserIntent);
return false;
}
});
mywebview.loadUrl("https://mycurrentlocation.net/");
}
#Override
public void onBackPressed(){
if(mywebview.canGoBack()) {
mywebview.goBack();
} else
{
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
int id = item.getItemId();
if(id == R.id.action_settings){
return true;
}
return super.onOptionsItemSelected(item);
}
}
When I click the button to show my current position, in Android Studio I get the following log:
E/Resource: printErrorResource, maybe not a error because module has
entative access to resource called by
=android.content.res.HwResourcesImpl.printErrorResource:2634 android.content.res.ResourcesImpl.openRawResource:444
android.content.res.Resources.openRawResource:1418
android.content.res.Resources.openRawResource:1362
android.support.v4.graphics.TypefaceCompatBaseImpl.createFromResourcesFontFile:304
android.support.v4.graphics.TypefaceCompat.createFromResourcesFontFile:232
I/ResourcesImplEx: The apk asset path =
ApkAssets{path=/system/framework/framework-res.apk}
The apk asset path = ApkAssets{path=/system/framework/framework-res-hwext.apk}
The apk asset path = ApkAssets{path=/preas/oversea/overlay/GmsConfigOverlay.apk}
The apk asset path = ApkAssets{path=/preas/oversea/overlay/GmsGsaConfigOverlay.apk}
The apk asset path = ApkAssets{path=/preas/oversea/overlay/GoogleExtServicesConfigOverlay.apk}
The apk asset path = ApkAssets{path=/preas/oversea/overlay/GoogleModuleMetadataConfigOverlay.apk}
The apk asset path = ApkAssets{path=/preas/oversea/overlay/GooglePermissionControllerConfigOverlay.apk}
The apk asset path = ApkAssets{path=/hw_product/overlay/frameworkResOverlay.apk}
The apk asset path = ApkAssets{path=/odm/overlay/frameworkResOverlay.apk}
The apk asset path = ApkAssets{path=/data/app/com.vinaysomawat.careerhigh-3JvsuNOhaJTzUZrEdMaQnA==/base.apk}
I/ResourcesImplEx: The apk asset path =
ApkAssets{path=/data/app/com.google.android.webview-Lw6x1ElnmD4d1UEVSG95iA==/base.apk}
The apk asset path = ApkAssets{path=/data/app/com.google.android.webview-Lw6x1ElnmD4d1UEVSG95iA==/split_config.it.apk}
The apk asset path = ApkAssets{path=/data/app/com.google.android.webview-Lw6x1ElnmD4d1UEVSG95iA==/split_weblayer.apk}
The apk asset path = ApkAssets{path=/data/app/com.google.android.trichromelibrary_489608833-ndmJcgRaxXQPmZ7r_KqT-w==/base.apk}
and then this log is shown (I think this is the error banner that say that can't load the position):
D/HiTouch_PressGestureDetector: onAttached,
package=com.vinaysomawat.careerhigh, windowType=2,
mHiTouchRestricted=false D/mali_winsys: EGLint
new_window_surface(egl_winsys_display *, void *, EGLSurface,
EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000
Yes. I had a similar problem. Location permissions for an android webview and geolocation are no longer handled by the webChromeClient. They are now handled in the same way as an Android native app. I used the following as a guide and it worked well.
https://developer.android.com/training/location/permissions

How to retrieve snapshot of map from place-picker activity?

I'm creating an app which picks places from the Google maps and stores the address in the database. I also want to store the snapshot of the picked place in the storage, so I can display the data with corresponding snapshot.
When I select a place from the map, the place-picker activity shows the following dialog:
Here in the dialog, the address, latitude and longitude and also the snapshot is shown. I know how to get address and latLng. but don't know how to store that displayed snapshot.
Here is my method which retrieves everything other than that image:
//opening place picker activity.
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST
&& resultCode == Activity.RESULT_OK) {
final Place place = PlacePicker.getPlace(this, data);
final CharSequence name = place.getName();
final CharSequence address = place.getAddress();
String attributions = (String) place.getAttributions();
if (attributions == null) {
attributions = "";
}
tv4.setText(place.getLatLng().toString()+"\n"+name+"\n"+address+"\n"+attributions);
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
I don't know how to get the image and store it in external or internal storage. Is it possible? I've to take snapshot as explained in this link?
EDIT
I have the following activity, which is calling activity of place-picker:
Main2Activity.java:
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlacePicker;
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.LatLngBounds;
import android.database.Cursor;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.maps.OnMapReadyCallback;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
public class Main2Activity extends AppCompatActivity implements OnMapReadyCallback{
private static final int PLACE_PICKER_REQUEST = 1;
private TextView mName;
private TextView mAddress;
private TextView mAttributions;
private GoogleApiClient mGoogleApiClient;
public TextView tv4;
private static final LatLngBounds BOUNDS_MOUNTAIN_VIEW = new LatLngBounds(
new LatLng(37.398160, -122.180831), new LatLng(37.430610, -121.972090));
private Toolbar toolbar;
private GoogleMap mMap;
private boolean flag = false;
DatabaseHelper myDb;
EditText newevent;
Button submit;
Button viewremainders;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
myDb =new DatabaseHelper(this);
newevent=(EditText)findViewById(R.id.newEvent);
submit=(Button)findViewById(R.id.submit);
viewremainders=(Button)findViewById(R.id.view);
toolbar = (Toolbar)findViewById(R.id.app_bar0);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true); //for back button to main activity.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Button pickerButton = (Button) findViewById(R.id.pickerButton);
tv4 = (TextView)findViewById(R.id.textView4);
pickerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
PlacePicker.IntentBuilder intentBuilder =
new PlacePicker.IntentBuilder();
intentBuilder.setLatLngBounds(BOUNDS_MOUNTAIN_VIEW);
Intent intent = intentBuilder.build(Main2Activity.this);
startActivityForResult(intent, PLACE_PICKER_REQUEST);
} catch (GooglePlayServicesRepairableException
| GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
}
});
AddData();
viewremainders();
}
#Override
public void onMapReady(GoogleMap map) {
mMap = map;
}
//method for adding data in Database.
public void AddData(){
submit.setOnClickListener(
new View.OnClickListener(){
#Override
public void onClick(View v){
boolean isInserted =myDb.insertData(newevent.getText().toString(),tv4.getText().toString());
if(isInserted==true)
Toast.makeText(Main2Activity.this,"Data Inserted",Toast.LENGTH_LONG).show();
else
Toast.makeText(Main2Activity.this,"Data not Inserted",Toast.LENGTH_LONG).show();
}
}
);
}
//Method for view all data from database.
public void viewremainders(){
viewremainders.setOnClickListener(
new View.OnClickListener(){
#Override
public void onClick(View v){
Cursor res= myDb.getAllData();
if(res.getCount()==0)
{
Showmessage("Error","No remainders found");
return;
}
StringBuffer buffer=new StringBuffer();
while(res.moveToNext())
{
buffer.append("Id : " +res.getString(0)+"\n");
buffer.append("Event : " +res.getString(1)+"\n");
buffer.append("Location : " +res.getString(2)+"\n");
}
Showmessage("Data",buffer.toString());
}
}
);
}
public void Showmessage(String title,String message)
{
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(message);
builder.show();
}
//opening place picker activity.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST
&& resultCode == Activity.RESULT_OK) {
final Place place = PlacePicker.getPlace(this, data);
final CharSequence name = place.getName();
final CharSequence address = place.getAddress();
String attributions = (String) place.getAttributions();
if (attributions == null) {
attributions = "";
}
// tv4.setText(place.getLatLng().toString()+"\n"+name+"\n"+address+"\n"+attributions); To get latitide and longitudes.
tv4.setText(address+"\n"+attributions);
/* LatLngBounds selectedPlaceBounds = PlacePicker.getLatLngBounds(data);
// move camera to selected bounds
CameraUpdate camera = CameraUpdateFactory.newLatLngBounds(selectedPlaceBounds,0);
mMap.moveCamera(camera);
// take snapshot and implement the snapshot ready callback
mMap.snapshot(new GoogleMap.SnapshotReadyCallback() {
Bitmap bitmap=null;
public void onSnapshotReady(Bitmap snapshot) {
// handle snapshot here
bitmap = snapshot;
try {
FileOutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory().toString()+"/ing.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
Toast.makeText(Main2Activity.this,"dsfds",Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(Main2Activity.this,e.toString(),Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
});*/
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void capture(){
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES).toString();
// create bitmap screen capture
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(Environment.getExternalStorageDirectory().toString()+"/"+"lllll.jpg");
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
openScreenshot(imageFile);
} catch (Throwable e) {
// Several error may come out with file handling or OOM
e.printStackTrace();
}
}
private void openScreenshot(File imageFile) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(imageFile);
intent.setDataAndType(uri, "image/*");
startActivity(intent);
}
//Methods for toolbar
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main2, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
if(id == android.R.id.home){
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
}
Since you are able to get the long and lat coordinates, you can get the map image by using the Google maps api.
Here's the link with examples and docs:
https://developers.google.com/maps/documentation/static-maps/intro
I assume this is what the dialog is doing in the background.
If that does not work, or you want something more exact, I suggest using Wireshark to monitor exactly what data is being sent and received.
I just ran a test with your map locations, and with this url:
https://maps.googleapis.com/maps/api/staticmap?center=37.430610,%20-121.972090&zoom=17&size=400x400&key=[myAPIKey]
I got this image:
Using the coords from your dialog:
Using https://maps.googleapis.com/maps/api/staticmap?markers=37.414333,-122.076444&zoom=17&size=400x250&key=[myKey]
You can use the GoogleMap.SnapshotReadyCallback
interface.
Here is a code example on how to use it:
SnapshotReadyCallback callback = new SnapshotReadyCallback() {
Bitmap bitmap;
#Override
public void onSnapshotReady(Bitmap snapshot) {
bitmap = snapshot;
try {
FileOutputStream out = new FileOutputStream("/some/where/to/save/it/thesnapshot.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}
};
map.snapshot(callback);
You can add this in your code when you show the dialog and in the same time save the snapshot. Read more about it in the link above.
I hope this will be of any help to you and good luck.
If you want to show snapshot of the picked place in the dialog first you have to save the screen of map view into bitmap.
Refer this code to converting your map view into bitmap
Bitmap screen;
View v1 = MyView.getRootView();
v1.setDrawingCacheEnabled(true);
screen= Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
From above code you can get Bitmap which You can further use in your Dialog box by setting this bitmap into image view.
But keep in mind u have to perform all operation before generating dialog and on worker thread.
You might look into maps Lite. It uses the google maps api and map views, but treats each one similar to an image rather than an interactive map. You can still choose your zoom level and add markers to the map.
declare the map in your xml like you would a regular google map fragment
but include the tag map:liteMode="true"
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:name="com.google.android.gms.maps.MapFragment"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraZoom="13"
map:mapType="normal"
map:liteMode="true"/>
or if you're creating the map programmatically you can use
GoogleMapOptions options = new GoogleMapOptions().liteMode(true);
it looks from your Activity code like you know how set up a google map, so you can then modify your onActivityResult to look like this
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST
&& resultCode == Activity.RESULT_OK) {
final Place place = PlacePicker.getPlace(this, data);
final CharSequence name = place.getName();
final CharSequence address = place.getAddress();
String attributions = (String) place.getAttributions();
if (attributions == null) {
attributions = "";
}
tv4.setText(place.getLatLng().toString()+"\n"+name+"\n"+address+"\n"+attributions);
// Add this line to make the lite map show the location you just chose
// and set the zoom level (10f is arbitrary)
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(place.getLatLng(), 10f));
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
More information and citations:
You can start here if you're looking for more info, there are tons of good links on this page
https://developers.google.com/maps/documentation/android-api/lite
you can also check out the Google Lite Maps Demo Activity here:
https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/LiteDemoActivity.java
And here's a great video that explains Lite Maps really well: https://youtu.be/N0N1Xkc_1pU
I faced same issue. I've tried with API key and Server key in both case I faced same error like "The Google Maps API server rejected your request... ". Finally I noticed that "Google Static Maps API" was disable from console. I just enable and everything works fine.

Android: Saving an ArrayList to SharedPreferences, but loading it is not working

After asking a similar question this morning, I did more research and found (I think) a way to save/load my ArrayList by saving it to SharedPreferences (After converting it to a Json String).
The problem is, I don't know where to put my saveListe() and my loadListe().
I don't get any error, but when restarting the application, the list is still the default one (It has 1 game in it).
Those 2 methods and my list are in a ListeJeux Class.
I tried using loadListe() in my mainActivity, and I used saveListe() in another activity (that add a game to the list for test purposes) just after adding a game.
If I launch the other activity, it adds a game to the list (this part is working), but if I restart the application, the list still contains 1 game only (default). What is the problem?
ListeJeux (contains save and load methods + the default list):
package com.example.jouons;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
#SuppressWarnings("deprecation")
public class ListeJeux extends ActionBarActivity {
// By default, the list contains one game, if the listView show more than
// one, then addJeu() works, if it still shows more than one game after a
// restart, then the save/load works (not working for now).
static Jeu jeu1 = new Jeu("Ballon fou", "moyens grands", "intérieur");
static ArrayList<Jeu> jeux = new ArrayList<>(Arrays.asList(jeu1));
// This is only to test.
static void addJeu() {
jeux.add(new Jeu("Ballon fou", "moyens grands", "intérieur"));
}
// Takes "jeux" (this is where the problem happens, I think), and makes it a
// Json String. Then store it in SharedPreference.
static public void saveListe(Context context) {
Gson gson = new Gson();
String listeJson = gson.toJson(jeux);
SharedPreferences prefs = context.getSharedPreferences("listePrefs", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("listeEditor", listeJson);
editor.commit();
}
// Takes the contain of the SharedPreference (Json String) and reverts it to
// an ArrayList. Then returns it.
static public ArrayList<Jeu> loadListe(Context context) {
Gson gson = new Gson();
SharedPreferences prefs = context.getSharedPreferences("listePrefs", MODE_PRIVATE);
String extractedJson = prefs.getString("listeEditor", "");
Type type = new TypeToken<ArrayList<Jeu>>() {
}.getType();
ArrayList<Jeu> jeux = gson.fromJson(extractedJson, type);
return jeux;
}
}
The MainActivity (in which I use the loadList() method):
package com.example.jouons;
import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
#SuppressWarnings("deprecation")
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListeJeux.loadListe(this);
setupTrouvezButton();
setupRechercherButton();
setupListeButton();
}
private void setupListeButton() {
Button listeButton = (Button) findViewById(R.id.btnMainListe);
listeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, ListeActivity.class));
}
});
}
private void setupTrouvezButton() {
Button trouvezButton = (Button) findViewById(R.id.btnMainTrouvez);
trouvezButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, TrouvezActivity.class));
}
});
}
private void setupRechercherButton() {
Button rechercherButton = (Button) findViewById(R.id.btnMainRechercher);
rechercherButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, RechercherActivity.class));
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And the other activity (that add a game to the list then save it):
package com.example.jouons;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
#SuppressWarnings("deprecation")
public class RechercherActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rechercher);
ListeJeux.addJeu();
ListeJeux.saveListe(this);
setupRetourButton();
}
private void setupRetourButton() {
Button retourButton = (Button) findViewById(R.id.btnRechercherRetour);
retourButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.rechercher, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
If you want to save a arraylist to the shared prefrence, you have to serialize the arraylist before you saving. I would prefer saving a serialized object to the sdcard instead of saving it to the shared prefrence, if it is not a confidantial information. if it is a cache file, i would recomend you save it to the app cache directory.
Serialize an object
public class SomeClassName implements Serializable{
private ArrayList<SomeObject> arrayList;
public void setObject(ArrayList<SomeObject> list){
arrayList = list;
}
public ArrayList<SomeObject> getObject(){
return arrayList;
}
}
ActionBarActivity although it is deprecated, it extends Activity, so you should be able to override onCreate, onResume and onPause to call your methods to load and save. For example:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rechercher);
setupRetourButton();
}
#Override
protected void onResume()
{
super.onResume();
ArrayList<Jeu> loaded = ListeJeux.loadListe(this);
for (Jeu j: loaded)
{
// This method to add doesn't exist and this whole loop should
// be refactored into the loadListe method.
ListeJeux.addJue(j)
}
// This size() method doesn't exist either and could also be subsumed into loadList
if (ListeJeux.size() == 0)
{
ListeJeux.addJeu();
ListeJeux.saveListe(this);
}
}
#Override
protected void onPause()
{
// Save the list as the app may stop any time after a pause.
ListeJeux.saveListe(this);
super.onPause();
}
Personally, I would refactor the code a little so the save and load methods on the list (ListeJeux), actually update the internal list. As you can see from the diagram at the top of this Android Documentation, you really only need to load in onResume as it should always be called before the Activity is displayed.

Unable to use Contact Picker

I am new to android programming.
I am unable to invoke the contact picker from my activity.
I have referred to many tutorial,formatted my code accordingly but got no result.
The code for MainActivity.java is:-
package com.example.intents;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater mi=getMenuInflater();
mi.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void invokeForRes(View view)
{
Intent in=new Intent(Intent.ACTION_PICK,Contact.Contacts.CONTENT_URI);
startActivityForResult(in, 1);
}
}
Please help me.......
Thank you in advance.
Use ContactsContract.Contacts.CONTENT_URI, not Contact.Contacts.CONTENT_URI. The latter was the Android 1.x contacts provider, and it was replaced by ContactsContract in Android 2.0, released in late 2009.
/***
Copyright (c) 2008-2012 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
From _The Busy Coder's Guide to Android Development_
http://commonsware.com/Android
*/
package com.commonsware.android.rotation.bundle;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
public class RotationBundleDemo extends Activity {
static final int PICK_REQUEST=1337;
Button viewButton=null;
Uri contact=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
viewButton=(Button)findViewById(R.id.view);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == PICK_REQUEST) {
if (resultCode == RESULT_OK) {
contact=data.getData();
viewButton.setEnabled(true);
}
}
}
public void pickContact(View v) {
Intent i=
new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(i, PICK_REQUEST);
}
public void viewContact(View v) {
startActivity(new Intent(Intent.ACTION_VIEW, contact));
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (contact != null) {
outState.putParcelable("contact", contact);
}
}
#Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
contact=state.getParcelable("contact");
viewButton.setEnabled(contact != null);
}
}
(from this sample project)

InAppBilling crashes on startup

I'm trying to make an app that I can get a simple implementation of in app purchases. I've been falling this guide http://www.techotopia.com/index.php/Integrating_Google_Play_In-app_Billing_into_an_Android_Application_%E2%80%93_A_Tutorial
but it's fraught with probably outdated information and neglects to include all the names of the packages you need to download from the SDK manager.
The main errors I had from this program were seemingly reference errors like I had not imported a certain library or compatibility files were missing. I managed to resolve all of them in eclipse and there are no errors when I run the code but trying it on a device or in the VM, the app crashes when I try to run it there.
I excluded the key you need for the google play connection for obvious reasons.
package com.a.inappbilling;
import com.a.inappbilling.util.IabHelper;
import com.a.inappbilling.util.IabResult;
import com.a.inappbilling.util.Inventory;
import com.a.inappbilling.util.Purchase;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.Button;
import android.content.Intent;
import android.util.Log;
public class InAppBillingActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_app_billing);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.in_app_billing, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_in_app_billing,
container, false);
return rootView;
}
}
private Button clickButton;
private Button buyButton;
#Override
protected void onStart() {
super.onStart();
buyButton = (Button)findViewById(R.id.buyButton);
clickButton = (Button)findViewById(R.id.clickButton);
clickButton.setEnabled(false);
String base64EncodedPublicKey =
"key here";
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new
IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result)
{
if (!result.isSuccess()) {
Log.d(TAG, "In-app Billing setup failed: " +
result);
} else {
Log.d(TAG, "In-app Billing is set up OK");
}
}
});
}
public void buttonClicked (View view)
{
clickButton.setEnabled(false);
buyButton.setEnabled(true);
}
private static final String TAG = "com.a.inappbilling";
IabHelper mHelper;
}
Add permission to your Manifest file
<uses-permission android:name="com.android.vending.BILLING" />
also add to your Manifest file under the Application node
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Also just verify you have added InAppBillingActivity.java to your Manifest file.

Categories