Android Google Place Picker: no nearby places until map pan - google-places-api

When the place picker launches, there is a 3-5 second long loading circle animation next to where the nearby places list should appear. After the loading circle disappears, no nearby places are shown in the list, and no nearby places pins are shown on the map.
Now, if pan the map (zoom doesn't do anything) in any direction a fair amount, the nearby places load just fine.
The first image below is taken after the place picker launches, it will stay this way without loading any nearby places until I pan the map.
The second image is taken after I have panned the map, where the nearby places loaded correctly.
At the bottom is my relevant code, let me know if you need more.
<manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<application
<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>
// Emulator is using google play services version 9.4.52
dependencies {
compile 'com.google.android.gms:play-services-maps:9.4+'
compile 'com.google.android.gms:play-services-places:9.4+'
compile 'com.google.android.gms:play-services-location:9.4+'
}
#Override
protected void onCreate(Bundle savedInstanceState) {
mGoogleApiClient = new GoogleApiClient
.Builder(this)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.enableAutoManage(this, this)
.build();
}
public void choosePlace() {
try {
PlacePicker.IntentBuilder intentBuilder = new PlacePicker.IntentBuilder();
Intent intent = intentBuilder.build(this);
startActivityForResult(intent, PLACE_PICKER_REQUEST);
} catch (GooglePlayServicesRepairableException e) {
// This is not being thrown
} catch (GooglePlayServicesNotAvailableException e) {
// This is not being thrown
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// This is not being called
}

Did you add this?
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="your_key" />
I had the same issue because I forgot to add meta-data to my manifest

Related

AutomationId for TabBar items not getting set in Android with Xamarin Forms

So I have the following code:
<TabBar Route="Dashboard">
<Tab Title="Dashboard" AutomationId="DashboardId">
//more codes here
</Tab>
<Tab AutomationId="AddNewId">
//more codes here
</Tab>
<Tab Title="Statistics" AutomationId="StatisticsId">
//more codes here
</Tab>
</TabBar>
Note that in my MainActivity's OnCreate() I have set up the following:
Xamarin.Forms.Forms.ViewInitialized += (object sender, Xamarin.Forms.ViewInitializedEventArgs e) => {
if (!string.IsNullOrWhiteSpace(e.View.AutomationId))
{
e.NativeView.ContentDescription = e.View.AutomationId;
}
};
This works perfectly with my other elements except for the TabBar items. Somehow the TabBar items are getting the Title property and setting is at the accessibilityId/content-dec.
Anyone knows why this is and how can I make it so it will get the right AutomationId? Thanks
There are multiple issues with AutomationId on Android.
The underlying problem is discussed in Android - Using AutomationId prevents TalkBack screenreader accessibility:
Xamarin.Forms "borrows" the ContentDescription property on Android for Automation IDs. These IDs polute Android's TalkBack accessibility tree, making apps almost impossible to navigate.
This means you can support test automation or accessibility, not both. Our app needs to support both.
In the case of Tabs, presumably Xamarin code is doing what you see: copying Title to content-desc, so that Android text readers will speak it.
The suggested work-around is to write custom renderer(s) that do what you need. Described in a comment by codingL3gend :
i was able to find a work around to this issue by creating a customrenderer and respective custom component to allow for overriding the native android method(s) that get triggered when accessibility events are fired. you will need to create some bindable properties on your custom component that you can access in the custom renderer to allow for setting the content description value to what you want but that's simple enough.
this method gets triggered in the control/custom renderer whenever an accessibility event is fired
public override bool OnRequestSendAccessibilityEvent(Android.Views.View child, AccessibilityEvent e)
{
if (AccessibilityHandler.IsAccessibilityEnabled(_context) && child != null)
{
if (!string.IsNullOrEmpty(_automationId) && _automationId.Equals(child.ContentDescription))
{
child.ContentDescription = $"{_automationName} {_helpText}";
}
}
return base.OnRequestSendAccessibilityEvent(child, e);
}
then you can set the contentDescription value of the control/custom renderer back to what the automationId value was originally when the control/custom renderer is detached from the view.
protected override void OnDetachedFromWindow()
{
base.OnDetachedFromWindow();
if (!string.IsNullOrEmpty(_automationId))
{
Control.ContentDescription = _automationId;
}
}
helper class
public static class AccessibilityHandler
{
public static bool IsAccessibilityEnabled(Context context)
{
var accessibility = (AccessibilityManager)context.GetSystemService(MainActivity.AccessibilityService);
return accessibility?.GetEnabledAccessibilityServiceList(Android.AccessibilityServices.FeedbackFlags.Spoken)?.Count > 0;
}
}
If you only need AutomationId during testing, or you can live with the effect this has on Accessibility Screen Readers (esp. it won't be multi-lingual), then you could make a much simpler custom renderer for use when testing.
Put this in your custom renderer (if isn't Tab, then change <Tab> to appropriate Xamarin class):
protected override void OnElementChanged( ElementChangedEventArgs<Tab> e )
{
base.OnElementChanged( e );
if (e.OldElement != null)
{
// Removing previous element.
// TBD: Remove obsolete references. (usually not needed)
}
if (Element == null)
// Going away with no replacement.
return;
UpdateAutomationId();
}
void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Element.AutomationId))
{
UpdateAutomationId();
}
}
void UpdateAutomationId()
{
var _automationId = Element.AutomationId;
if (!string.IsNullOrEmpty(_automationId))
{
Control.ContentDescription = _automationId;
}
}

reaching a page from xamarin.forms inside android project

I'm working on an android app with xamarin. I made tabbed pages. For the second page, i want to show the camerastream from my android camera. For that, some sample code said me I need to use a textureView inside the android part of the app, but that textureview needs to be putted on that second page. Whenever I try to reach a Stacklayout inside that Page, the following error shows up: 'Page1.camera' is inaccessible due to its protection level.
Using x:FieldModifier="public" inside that stacklayout doesn't work either.
Here is the structure of my code to make it more clear
Here I make the tabbed pages:
MainPage = new TabbedPage
{
Children = {
new MainPage(),
new Page1(),
new Page2()
}
};
Inside that Page1 i have this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App4.Page1"
Title="Licht">
<StackLayout x:Name="camera" x:FieldModifier="public" Orientation="Vertical">
</StackLayout>
</ContentPage>
And inside the MainActivity.cs i have this where i have to access the camera.
_textureView = new TextureView(Page1.camera);
And this is the structure of my app
And this is the structure of my app
Using x:FieldModifier="public" inside that stacklayout doesn't work either.
I have tried x:FieldModifier="public"in xamarin form, even though I use x:FieldModifier="public", the "camera" property is still private. This feature is not useful.
As far as I know there is no way to access "camera" inside MainActivity.cs in Xamarin form.
As a workaround you can design a page render for android platform and create a TextureView in your page render code.
how to create a page render
_textureView = new TextureView(Page1.camera);
BTW to initialize TextureView you need the object that implements the ISurfaceTextureListener interface at android platform.
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity,ISurfaceTextureListener
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
TextureView textureView = new TextureView(this);
textureView.SurfaceTextureListener = this;
LoadApplication(new App());
}
public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
{
//start
}
public bool OnSurfaceTextureDestroyed(SurfaceTexture surface)
{
//stop
}
public void OnSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
{
throw new NotImplementedException();
}
public void OnSurfaceTextureUpdated(SurfaceTexture surface)
{
throw new NotImplementedException();
}
}
Please follow the TextureView guide for Android.

Adding Icons to Tab while Actionbar is active

I'm trying to get a "simple" UI done, but I'm stuck at where I want to put icons in my bottom tabs. So far I got the following code:
`public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTabHost mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(
mTabHost.newTabSpec("tab1").setIndicator("AddStuff", getResources().getDrawable(R.drawable.ic_add_white_24dp)),
FragmentTabAdd.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab2").setIndicator("Favorites", getResources().getDrawable(R.drawable.ic_add_white_24dp)),
FragmentTabSelectFavorites.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab3").setIndicator("Messages", getResources().getDrawable(R.drawable.ic_add_white_24dp)),
FragmentTabMessages.class, null);
}
#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;
}`
and I got the following as my .xml for each tab:
<?xml version="1.0" encoding="utf-8"?>
<selector android:layout_width="match_parent"
android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<!-- When selected, use black -->
<item android:drawable="#drawable/ic_add_black_24dp"
android:state_selected="true" />
<!-- When not selected, use white-->
<item android:drawable="#drawable/ic_add_white_24dp" />
</selector>
I worked through several different tutorials, but none had an Actionbar and a Tabbar with icons. I'm happy for any tipps and suggestions.
Thank you in advance!
I found the answer myself after several hours of trying different things.
The way to add Icons to the bottom tab bar is to insert "null" here:
mTabHost.addTab(
mTabHost.newTabSpec("tab1").setIndicator("AddStuff", getResources().getDrawable(R.drawable.ic_add_white_24dp)),
FragmentTabAdd.class, null);
null has to be written where "AddStuff" is now.
I even colored the background with an image:
mTabHost.setBackground(getResources().getDrawable(R.drawable.tab_background));
Maybe this will help someone else save some time :)

getResource not working (Even though I have a correct pathfile)

[NOTE: This thread is edited.. cause the first question is already answered but the current question is not]
Can someone tell me why this is not working?
This is from a tutorial. I read a lot on different threads about this problem and I found out that I need to create a new Source Folder. I name it to Images then add Hello.jpg to it by dragging the image into the folder and it works.
Now they said that in order to use the image you need to put "/nameofthefolder/file.filetype/"
So I put it in the correct path.
But my problem is, it is not working.. My code is very simple.. Add an image to an JLabel
I can't put an picture on because I need 10 rep.. but I create a Source Folder and add Image to that folder correctly I promise
I know this question sounds stupid but I am very new to programming... please have a kind consideration on the beginner..
package myGUI102;
import java.awt.*;
import javax.swing.*;
public class myGUIAddImage extends JFrame{
private ImageIcon image1;
private JLabel label1;
myGUIAddImage (){
setLayout(new FlowLayout());
image1 = new ImageIcon (getClass().getResource("/Images/Hello.jpg"));
label1 = new JLabel (image1);
add (label1);
}
public static void main(String[] args) {
myGUIAddImage mygui = new myGUIAddImage();
mygui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mygui.setVisible(true);
mygui.pack();
mygui.setTitle("My Image");
}
}
Replace the below code
Intent mainactivity = new Intent("com.neoapps.quizj.QUIZJMENU");
startActivity(mainactivity);
with
Intent mainactivity = new Intent(this,Quizjmenu.class);
startActivity(mainactivity);
This will start Quizjmenu activity. Between i don't actually understand what you are trying to achieve by directly re-directing users from MainActivityQuizj to Quizjmenu when they start your app.
Doesn't the purpose of MainActivityQuizj gets defeated in this instance ? (or) maybe this is just an example code from which you are trying to put forward your issue.
Also, your android manifest for activity needs to be updated as per the below,
<activity
android:name=".MainActivityQuizj"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Quizjmenu"
android:label="#string/app_name" >
</activity>

How to record video from front facing camera in Xamarin.Android?

I am using following code in an Android application written in Xamarin:
var recorder = new MediaRecorder ();
recorder.SetVideoSource (VideoSource.Camera);
recorder.SetAudioSource (AudioSource.Mic);
recorder.SetOutputFormat (OutputFormat.Default);
recorder.SetVideoEncoder (VideoEncoder.Default);
recorder.SetAudioEncoder (AudioEncoder.Default);
recorder.SetOutputFile (path);
recorder.SetPreviewDisplay (video.Holder.Surface);
recorder.Prepare ();
recorder.Start ();
It works but i have a problem. It uses background camera and orientation is landscape. How can I use front facing camera for recording the video and set orientation to portrait ?
Source: Android can't record video with Front Facing Camera, MediaRecorder start failed: -19
First, make sure that your permissions are set up correctly.
Specifically, to record video, you'll want:
<uses-feature android:name="android.hardware.camera.front" />
<uses-feature android:name="android.hardware.microphone"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> Second,
and this is the tricky part, this line from the tutorial does not work
with the front-facing camera!
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
That signature for CamcorderProfile.get() defaults to a profile for
the back-facing camera:
Returns the camcorder profile for the first back-facing camera on the
device at the given quality level. If the device has no back-facing
camera, this returns null.
Instead, use
http://developer.android.com/reference/android/media/CamcorderProfile.html#get(int,%20int).
The first parameter is the id of the camera that you opened,
specifically, the front-facing camera.
This is how you do it:
First make sure your minimum supported API version is Gingerbread 2.3
Second ensure all permissions have been added to manifest file
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And use this snippet to get reference to front camera and display the preview in video view while recording
if (Camera.NumberOfCameras < 2) {
Toast.MakeText (this, "Front camera missing", ToastLength.Long).Show ();
return;
}
_camera = Camera.Open (1);
_camera.SetDisplayOrientation (90);
_camera.Unlock ();
recorder = new MediaRecorder ();
recorder.SetCamera (_camera);
recorder.SetAudioSource (AudioSource.Mic);
recorder.SetVideoSource (VideoSource.Camera);
recorder.SetOutputFormat (OutputFormat.Default);
recorder.SetAudioEncoder (AudioEncoder.Default);
recorder.SetVideoEncoder (VideoEncoder.Default);
recorder.SetOutputFile (path);
recorder.SetOrientationHint (270);
recorder.SetPreviewDisplay (previewVideoView.Holder.Surface);
recorder.Prepare ();
recorder.Start ();
I used #Kartik's solution with a small modification. Not all devices have a rear facing camera(2012 Nexus 7 is a great example). This verison of the code goes through all available cameras and checks if the camera is truly the front one.
for (int camIndex = 0; camIndex < Camera.NumberOfCameras; camIndex++)
{
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.GetCameraInfo(camIndex, cameraInfo);
if (cameraInfo.Facing == CameraFacing.Front)
{
try
{
_camera = Camera.Open(camIndex);
_camera.SetDisplayOrientation(270);
_camera.Unlock();
}
catch (Exception e)
{
Toast.MakeText(this, "Front camera missing", ToastLength.Long).Show();
}
}
}

Resources