I am using Google places API for android to let the user select cities in the world. Then I use the placeId to get an image to something similar to google maps.
Picture example
Every single time I'm getting the photos bundle successfully but it contains no images. It works just fine if I use the placeId of any restaurant or cafe or any other single spot but not for a whole city.
Here's the method I'm using to get the images.
public void loadPlaceImage(final ImageView imageView, String placeId) {
/**
* Load a bitmap from the photos API asynchronously
* by using buffers and result callbacks.
*/
Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId)
.setResultCallback(new ResultCallback<PlacePhotoMetadataResult>() {
#Override
public void onResult(PlacePhotoMetadataResult photos) {
if (!photos.getStatus().isSuccess()) {
Log.d(TAG, "Couldn\'t receive photos bundle successfully.");
return;
}
Log.d(TAG, "Photo bundle received successfully");
PlacePhotoMetadataBuffer photoMetadataBuffer = photos.getPhotoMetadata();
if (photoMetadataBuffer.getCount() > 0) {
// Display the first bitmap in an ImageView in the size of the view
photoMetadataBuffer.get(0)
.getScaledPhoto(mGoogleApiClient, imageView.getWidth(),
imageView.getHeight())
.setResultCallback(new ResultCallback<PlacePhotoResult>() {
#Override
public void onResult(PlacePhotoResult placePhotoResult) {
if (!placePhotoResult.getStatus().isSuccess()) {
Log.d(TAG, "Couldn\'t retrieve the photo successfully.");
return;
}
Log.d(TAG, "Successfully retrieved photo from photo bundle.");
imageView.setImageBitmap(placePhotoResult.getBitmap());
}
});
} else {
Log.d(TAG, "0 images in the buffer.");
}
photoMetadataBuffer.release();
}
});
}
I used your code in my android studio, it hadn't problem in your code.
I guess you forgot to add meta-data in Manifest.
<application
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<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="YOURKEY"/>
</application>
it is for reference to set up your "Android KEY"
https://developers.google.com/places/android-api/signup
https://console.developers.google.com/apis (this Link can set your key)
By the way, you can use:
Log.d(TAG,"result getStatus "+result.getStatus().getStatus());
to check your error message, hope it will help you
Related
I've implemented iOS and Android SDK, now I'm testing my app configuration in test environment. While with iOS everything seems working fine, I've noticed that with Android, the install event is correctly attributed to my quick link, any other events I'm sending (even thos I can correctly see them in the liveview) are not attributed to the quick link used to open the app.
Here my dependencies:
com.android.tools.build:gradle:3.1.1
com.google.gms:google-services:4.2.0
io.fabric.tools:gradle:1.31.0
com.android.support:appcompat-v7:28.0.0
Here the main lines of code:
#Override
protected void handleOnStart() {
super.handleOnStart();
Branch.enableDebugMode();
// Branch object initialization
Branch.getAutoInstance(this.getActivity().getApplication());
branchInstance = Branch.getInstance();
branchInstance.disableTracking(trackingDisabled);
branchInstance.initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
if (error != null) {
log("onInitFinished - " + error.getMessage());
} else {
log("onInitFinished invoked with " + referringParams.toString());
testEvent();
// Retrieve deeplink keys from 'referringParams' and evaluate the values to determine where to route the user
// Check '+clicked_branch_link' before deciding whether to use your Branch routing logic
}
}
}, getActivity().getIntent().getData(), getActivity());
}
#Override
public void onNewIntent(Intent intent) {
this.setIntent(intent);
}
private void testEvent() {
BranchEvent event = new BranchEvent(BRANCH_STANDARD_EVENT.VIEW_ITEM);
event.logEvent(this.getActivity());
}
And my AndroidManifest.xml looks like this:
<application android:launchMode="singleTask" .....>
<meta-data android:name="io.branch.sdk.BranchKey" android:value="#string/branchio_key_live" />
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="#string/branchio_key_test" />
<meta-data android:name="io.branch.sdk.TestMode" android:value="#bool/branchio_test_mode" />
<receiver android:enabled="#bool/branchio_track_referral_active" android:name="io.branch.referral.InstallListener" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
It looks like your code is slightly different than what we recommend in our Android Docs, so I would recommend you conform your code as closely as possible to our code snippets as possible. For example, we recommend initializing in the onStart() method whereas you are doing yours in handleOnStart(). Here are the Android docs: https://docs.branch.io/apps/android/
If you do this and are still having difficulties, please send an email to support#branch.io and provide your App ID which is found in your Account Settings on your dashboard so we can investigate this further.
Background
Back a few years ago, I asked how TeamViewer allows the user to control the device without normal interaction with the device. I was told it's a special "backdoor" that manufacturers allow specifically for this app, and only possible using root priviledge for other apps.
Seeing that an app like "Airplane Mode Shortcut" allows to toggle airplane mode, by automatic navigation to its screen and toggling the switch, it made me realize this situation has changed.
The problem
It is said in the docs:
Starting with Android 4.0 (API Level 14), accessibility services can
act on behalf of users, including changing the input focus and
selecting (activating) user interface elements. In Android 4.1 (API
Level 16) the range of actions has been expanded to include scrolling
lists and interacting with text fields. Accessibility services can
also take global actions, such as navigating to the Home screen,
pressing the Back button, opening the notifications screen and recent
applications list. Android 4.1 also includes a new type of focus,
Accessibilty Focus, which makes all visible elements selectable by an
accessibility service.
These new capabilities make it possible for developers of
accessibility services to create alternative navigation modes such as
gesture navigation, and give users with disabilities improved control
of their Android devices.
But there is no more information about how to use it.
Only samples I've found are at the bottom, but those are very old and a part of the apiDemos bundle.
The question
How do I make a service that can query, focus, click, enter text, and perform other UI related operations?
By implementing AccessibilityService (https://developer.android.com/training/accessibility/service.html) you get access to that features.
You can either inspect or perform action on the element lastly interacted by user or inspect whole application which currently active.
Intercept user events by implementing onAccessibilityEvent(AccessibilityEvent event), here you can retrieve virtual view (representing original view) with event.getSource() and then inspect it with getClassName() or getText() or anything you find in the documentation.
Inspect whole application by calling getRootInActiveWindow() and iterate throught tree of virtaul views with getRootInActiveWindow().getChild(index).
Both getRootInActiveWindow() and event.getSource() return AccessibilityNodeInfo, on which you can invoke performAction(action) and do something like Click, Set Text, etc..
Example: Play Store
Search for 'facebook' app and open it's page on play store, once you opened the play store app.
#Override
public void onAccessibilityEvent(final AccessibilityEvent event) {
AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
//Inspect app elements if ready
if (rootInActiveWindow != null) {
//Search bar is covered with textview which need to be clicked
List<AccessibilityNodeInfo> searchBarIdle = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.android.vending:id/search_box_idle_text");
if (searchBarIdle.size() > 0) {
AccessibilityNodeInfo searchBar = searchBarIdle.get(0);
searchBar.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
//Check is search bar is visible
List<AccessibilityNodeInfo> searchBars = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.android.vending:id/search_box_text_input");
if (searchBars.size() > 0) {
AccessibilityNodeInfo searchBar = searchBars.get(0);
//Check is searchbar have the required text, if not set the text
if (searchBar.getText() == null || !searchBar.getText().toString().equalsIgnoreCase("facebook")) {
Bundle args = new Bundle();
args.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "facebook");
searchBar.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args);
} else {
//There is no way to press Enter to perform search, so find corresponding suggestion and click
List<AccessibilityNodeInfo> searchSuggestions = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.android.vending:id/suggest_text");
for (AccessibilityNodeInfo suggestion : searchSuggestions) {
if(suggestion.getText().toString().equals("Facebook")) {
//We found textview, but its not clickable, so we should perform the click on the parent
AccessibilityNodeInfo clickableParent = suggestion.getParent();
clickableParent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
}
}
EDIT: full code below:
MyAccessibilityService
public class MyAccessibilityService extends AccessibilityService {
#Override
public void onCreate() {
super.onCreate();
Log.d("MyAccessibilityService", "onCreate");
}
#Override
public void onAccessibilityEvent(final AccessibilityEvent event) {
Log.d("MyAccessibilityService", "onAccessibilityEvent");
AccessibilityNodeInfo rootInActiveWindow = getRootInActiveWindow();
//Inspect app elements if ready
if (rootInActiveWindow != null) {
//Search bar is covered with textview which need to be clicked
List<AccessibilityNodeInfo> searchBarIdle = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.android.vending:id/search_box_idle_text");
if (searchBarIdle.size() > 0) {
AccessibilityNodeInfo searchBar = searchBarIdle.get(0);
searchBar.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
//Check is search bar is visible
List<AccessibilityNodeInfo> searchBars = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.android.vending:id/search_box_text_input");
if (searchBars.size() > 0) {
AccessibilityNodeInfo searchBar = searchBars.get(0);
//Check is searchbar have the required text, if not set the text
if (searchBar.getText() == null || !searchBar.getText().toString().equalsIgnoreCase("facebook")) {
Bundle args = new Bundle();
args.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "facebook");
searchBar.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args);
} else {
//There is no way to press Enter to perform search, so find corresponding suggestion and click
List<AccessibilityNodeInfo> searchSuggestions = rootInActiveWindow.findAccessibilityNodeInfosByViewId("com.android.vending:id/suggest_text");
for (AccessibilityNodeInfo suggestion : searchSuggestions) {
if (suggestion.getText().toString().equals("Facebook")) {
//We found textview, but its not clickable, so we should perform the click on the parent
AccessibilityNodeInfo clickableParent = suggestion.getParent();
clickableParent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
}
}
#Override
public void onInterrupt() {
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.findfacebookapp">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name=".MyAccessibilityService"
android:label="#string/accessibility_service_label"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibility_service_config"/>
</service>
</application>
</manifest>
res/xml/accessibility_service_config.xml
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackAllMask"
android:accessibilityFlags="flagDefault"
android:canRequestEnhancedWebAccessibility="true"
android:canRetrieveWindowContent="true"
android:description="#string/app_name"
android:notificationTimeout="100"/>
MainActivity
public class MainActivity extends AppCompatActivity {
public void onEnableAccClick(View view) {
startActivityForResult(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 1);
}
}
I am trying to get the call block numbers in android N, i want to know the given is block number or not (ex:- 5554 emulator number)
Contacts, sms, phone state permissions has been given to allow to access the block numbers and i followed the "Android Developer" site https://developer.android.com/reference/android/provider/BlockedNumberContract.html
But i am unable to get the block numbers, i am using latest android studio 2.2.2 and checked the functionality in android N emulator i don't have device.
Here is my code.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Button onclick method to show the logs
public void displayBlockCursorCount(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String number = "5552";
if (BlockedNumberContract.canCurrentUserBlockNumbers(MainActivity.this)) {
if (BlockedNumberContract.isBlocked(MainActivity.this, number)) {
Log.e(TAG, "given number is blocked >>>>>> " + number);
}
}
}
}
}
I am getting the
java.lang.SecurityException: Caller must be system, default dialer or default SMS app.
Please post the comment if down comment and thanks for advance.
To access blocked contacts,Your app should be default calling app or Messaging app else it throws security exception.
Add additional check
private boolean isAppAsDefaultDialer() {
TelecomManager telecom = mContext.getSystemService(TelecomManager.class);
if (getApplicationContext().getPackageName().equals(telecom.getDefaultDialerPackage())) {
return true;
}
return false;
}
or check sources https://android.googlesource.com/platform/packages/providers/BlockedNumberProvider/+/android-7.0.0_r1/src/com/android/providers/blockednumber/BlockedNumberProvider.java
And make you app as defaul dialer
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="tel"/>
</intent-filter>
I need to find what was the source of my app open like(fb,twitter,g+) is there a way to find it.
I know there is a open referrer in header of url but how can i fetch this information in android app
Google provide online material for this:
https://codelabs.developers.google.com/codelabs/deeplink-referrer
Summary
You can use Activity#getReferrer() to get the referrer of the deep link. It's available since API 22.
For API Level 21 and below, you can use the following snippet from above online material:
private static final String REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
/** Returns the referrer on devices running SDK versions lower than 22. */
private Uri getReferrerCompatible(Activity activity) {
Intent intent = activity.getIntent();
Uri referrerUri = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
if (referrerUri != null) {
return referrerUri;
}
String referrer = intent.getStringExtra(REFERRER_NAME);
if (referrer != null) {
// Try parsing the referrer URL; if it's invalid, return null
try {
return Uri.parse(referrer);
} catch (ParseException e) {
return null;
}
}
return null;
}
Take a look at Firebase Dynamic Links
https://firebase.google.com/docs/dynamic-links/
Try this
On your android manifest file register your acitivity which have to open on link click
<activity
android:name=".YOURACTIVITY"
android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"
android:host="somedomainname.com"
android:pathPrefix="/index"/>
</intent-filter>
</activity>
On your html
Click me
depending on #Ahmad Fadli answer (works but some application might not be detected)
I had a similar use case, so someone might need it , you could use both of them too :
fun getReferrerCompatible(activity: Activity?): String? {
if (activity == null)
return null
try {
val intent = activity.intent
val bundle = intent.extras
if (bundle != null) {
val keySet = bundle.keySet().toTypedArray()
for (k in keySet) {
if (k.contains("application_id")) {
return bundle.getString(k)
}
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
return activity.referrer?.toString()
}
} catch (e: Exception) {
Crashlytics.logException(e)
}
return null
}
the default referrer actually does not give you chrome application for some deep links ,for some reason it would return "google.com"
I'm trying to integrate InMobi in my app and I can show banner ads successfully but unable to add interstitial ads.
I've added this code in the activity from where I want to show ad.
InMobi.setLogLevel(InMobi.LOG_LEVEL.DEBUG);
InMobi.initialize(this, "Property-id");
final IMInterstitial interstitial = new IMInterstitial(this, "Property-id");
interstitial.setIMInterstitialListener(new IMInterstitialListener() {
#Override
public void onInterstitialFailed(IMInterstitial imInterstitial, IMErrorCode imErrorCode) {
Log.e(DEBUG_TAG, "Interstitial failed" + "... Error code = " + imErrorCode +
"... Internstial = " + imInterstitial);
}
#Override
public void onInterstitialLoaded(IMInterstitial imInterstitial) {
Log.e(DEBUG_TAG, "interstitial loaded");
if (interstitial.getState() == IMInterstitial.State.READY) {
interstitial.show();
}
}
#Override
public void onShowInterstitialScreen(IMInterstitial imInterstitial) {
}
#Override
public void onDismissInterstitialScreen(IMInterstitial imInterstitial) {
}
#Override
public void onInterstitialInteraction(IMInterstitial imInterstitial, Map<String, String> stringStringMap) {
}
#Override
public void onLeaveApplication(IMInterstitial imInterstitial) {
}
});
interstitial.loadInterstitial();
And for testing, I've added everything mentioned here in AndroidManifest.xml file. I've added all the permissions there, hardwareAccelerated=true in application tag and this:
<activity
android:name="com.inmobi.androidsdk.IMBrowserActivity"
android:configChanges="keyboardHidden|orientation|keyboard|smallestScreenSize|screenSize"
android:hardwareAccelerated="true"
android:theme="#android:style/Theme.Translucent.NoTitleBar" />
<receiver
android:name="com.inmobi.commons.analytics.androidsdk.IMAdTrackerReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="com.inmobi.share.id" />
</intent-filter>
</receiver>
<service
android:name="com.inmobi.commons.internal.ActivityRecognitionManager"
android:enabled="true" />
But I keep getting this error "The ad request was successful, but no ad was returned" and after a small time gap, it gives "Ad network failed to retrieve ad".
For banner ads it worked successfully though. I tried it again but it's not working now. Is there something wrong with inmobi diagnostics as mentioned here (Sohan says this in his comments).
I'm from the InMobi team. Are you replacing the "Property-Id" in your code with your actual property id? I'm unsure if the code you provided above is your actual code or for illustrative purposes only...