I'm trying to get an implicit deep link working in a very basic Android app. The goal is to demonstrate a basic OAuth flow with Strava's OAuth server to get access to their API.
Strava automatically whitelists 'localhost' plus any authorization callback domain you enter when you register your 'app'. I'm relying on localhost.
I have an activity plus some fragments. In Android Studio I've added a deep link to a fragment that isn't the initial one. My initial fragment asks for a login name and password then creates an IntentUri to hit the Strava OAuth server. This goes just fine and it passes the callback URI in the OAuth request along with the grant requests. The problem is that the callback URI does not go to the deep link.
I've tried a few combinations for callback URIs:
http://localhost/fibonacci/itemFragment
localhost/fibonacci/itemFragment
myapp://localhost/fibonacci/itemFragment
None of these work (yes I always update the URI in the OAuth request and in xml that describes the deep link at the same time.
the callback URI triggers a request to open the browser.
the Strava site flags the callback uri as invalid.
the callback doesn't seem to occur.
I've also tried to test this by creating a shortcut but in each the browser tries to open the shortcut.
Below are my android manifest file, my shortcuts.xml file and my nav_graph.xml.
I should at least be able to get the shortcut to work even if Strava wouldn't work for whatever reason.
Any help is appreciated.
-------------------AndroidManifest.xml---------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.fibonacci">
<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/Theme.Fibonacci">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/Theme.Fibonacci.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="#xml/shortcuts" />
</activity>
</application>
</manifest>
----------------------shortcuts.xml-------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="RichShortcut"
android:enabled="true"
android:shortcutShortLabel="#string/static_shortcut_label_short"
android:shortcutLongLabel="#string/static_shortcut_label_long"
android:shortcutDisabledMessage=
"#string/static_shortcut_disabled_message">
<!-- android:icon="#drawable/donut_with_sprinkles">-->
<intent
android:action="android.intent.action.VIEW"
android:data="myapp://localhost/fibonacci/itemFragment" />
</shortcut>
</shortcuts>
--------------------------nav_graph.xml-------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_graph"
app:startDestination="#id/loginFragment">
<fragment
android:id="#+id/FirstFragment"
android:name="com.example.fibonacci.FirstFragment"
android:label="#string/first_fragment_label"
tools:layout="#layout/fragment_first">
<action
android:id="#+id/action_FirstFragment_to_SecondFragment"
app:destination="#id/SecondFragment" />
</fragment>
<fragment
android:id="#+id/SecondFragment"
android:name="com.example.fibonacci.SecondFragment"
android:label="#string/second_fragment_label"
tools:layout="#layout/fragment_second">
<action
android:id="#+id/action_SecondFragment_to_FirstFragment"
app:destination="#id/FirstFragment" />
</fragment>
<fragment
android:id="#+id/loginFragment"
android:name="com.example.fibonacci.ui.login.LoginFragment"
android:label="fragment_login"
tools:layout="#layout/fragment_login" />
<fragment
android:id="#+id/itemFragment"
android:name="com.example.fibonacci.ItemFragment"
android:label="fragment_item_list"
tools:layout="#layout/fragment_item_list">
<deepLink
android:id="#+id/deepLink"
app:uri="myapp://localhost/fibonacci/itemFragment" />
</fragment>
</navigation>
You haven't registered your <deepLink> in your navigation graph in your manifest, so it will never be triggered by the Android OS.
As per the implicit deep link documentation:
To enable implicit deep linking, you must also make additions to your app's manifest.xml file. Add a single <nav-graph> element to an activity that points to an existing navigation graph, as shown in the following example:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/Theme.Fibonacci.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="#xml/shortcuts" />
<!-- This line is what adds the correct intent filter for your deepLink -->
<nav-graph android:value="#navigation/nav_graph" />
</activity>
Related
i used webview to create app and implemented deep linking like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ariagp.myapplication">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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="https" android:host="mysitename.com" />
</intent-filter>
</activity>
</application>
</manifest>
it will asking my for open with my application before open the links, but the problem is:
two applications will open in the phone task manager (the application does not open in the previous application which is running):
what is the solution?
Add android:launchMode="singleTask" in declared activity in AndroidManifest.xml.
And then, in your activity, you should override onNewIntent() method and you will get arguments there.
Ok, so you don't actually have a problem here.
This is just how deep links work. If you open one in a certain app, the deep link will open your app but in the same window the deep link was originally in.
Your app will have two instances in a way.
You could go to you web brower app and click share and any app that pops up. They all open in the web browsing app window. So there is nothing to worry about. I had the same problem myself before I realised that it is just how things work.
Some apps are just verified to open other apps if they implement the browsability.
Add android:launchMode="singleTask" in declared activity in AndroidManifest.xml.
And then, in your activity, you should override onNewIntent() method and call mNavController.handleDeepLink(intent) there.
It is worth mentioning that you are now able to get your arguments using, private val args: XFragmentArgs by navArgs()in your fragment.
I keep getting the "Default activity is not found" error whenever I want to try and run my app. I have tried 'clean project', 'invalidate caches/restart' and restarted my computer.
UPDATE: I tried running different projects, but they all give the same error too. This makes me think there must be something wrong with settings.
It works perfectly for my friend, but I get the error that the "Default activity is not found". If I try to launch a specific activity it also says the activity is not found. This is the code in the androidmanifest.xml file:
<?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="ek97.fhict.theapp">
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<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/loqate_logo"
android:label="#string/app_name"
android:roundIcon="#drawable/loqate_logo"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".bottomnavigationfinal"
android:label="#string/title_activity_bottomnavigationfinal"/>
<activity android:name="Settings" />
<activity
android:name=".Login"
android:label="#string/title_activity_login" />
<activity
android:name=".Registration"
android:exported="true"
android:label="#string/title_activity_registration" />
<activity android:name=".Navigation" />
<activity android:name=".SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<activity
android:name=".GoogleMaps"
android:label="#string/title_activity_google_maps" >
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
</activity>
<activity android:name=".Profile" />
</application>
</manifest>
If it works for your friend and it is the same code it could be that all you need to do is to refresh the cache of your IDE:
File -> Invalidate Caches / Restart
Try this::
Your manifest is missing default activity
Add to any activity as you consider a default activity
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
I finally solved it by making sure all implementation versions were the same, there were some in a 28.0.0 version and others in a 26.1.0. version. Now the app works fine on the emulator. Thanks for your suggestions though
My app uses the Google Places API to function however when I use the line placeLikelihoods.getStatus().getStatusMessage() , I get the message PLACES_API_KEY_INVALID. I've been googling for days and can't find a solution. When I go to https://console.developers.google.com/apis/credentials?project=myprojectdebug and click on my project, I am redirected to a page that shows my API key, the date I made it and my email used to make it.
This is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="censored b/c its got some private stuff in name">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.INTERNET" />
<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"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<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.gms.version"
android:value="#integer/google_play_services_version" />
<meta-deta
android:name="com.google.android.geo.API_KEY"
android:value="My 39 character API key is here" />
</application>
What am I doing wrong? I feel like giving up but I also want to know what's wrong
EDIT: Found the problem however I can't fix it. I didn't use the proper keytool command shown here https://support.google.com/googleapi/answer/6158862 but when I run this command it gives me an error because my account name has a space between my first and last name thanks to me using a microsoft account.
Ok, i got your error. You misspell meta-data. Check your tag, you wrote 'meta-deta'
check this one in your manifest file i placed
android:name="com.google.android.maps.v2.API_KEY"
instead of this (place below one and check spelling)
android:name="com.google.android.geo.API_KEY"
in your AndroidManifest.xml file like
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/api_key"/>
1) Have you enable/activate google place api?
2) Did you keep switching your workstation? If you run your code using another pc (not the original one you use to generate api key), you need to request new API key because the debug key has changed.
as the title says, when the next line of code
android:screenOrientation="portrait"
is entered in my Manifest file then when I start my app and, for example, dragging the gallery app to it then its not activating the multi window feature which splits the screen... but just replace my app with the gallery app, meaning the gallery app takes all the screen instead of taking only half of it.
If I first open the gallery app and then dragging my app then its working fine.
Also if I remove the above line of code then its working fine.
This is my Manifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.samsunmultiwindowstest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.samsunmultiwindowstest.MainActivity"
android:screenOrientation="portrait"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER"/>
</intent-filter>
</activity>
<uses-library android:required="false" android:name="com.sec.android.app.multiwindow"> </uses-library>
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_H" android:value="598.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H" android:value="598.0dip" />
</application>
how can I force portrait mode and get the multi window feature?
Thank you and sorry for my English.
Check out this Link Screen Orientation. It will help you understand different kinds of screen orientation. Also check this and this. will help you to enable multi window feature
I simply took out the size settings to solve my multiWindow issues.
IE: Remove these lines altogether.
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_H" android:value="598.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W" android:value="632.0dip" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H" android:value="598.0dip" />
I've seen this question asked often, but none of the proposed solutions seem to be working for me. I'm getting
E/AndroidRuntime(897): java.lang.NoClassDefFoundError: android.support.v4.app.FragmentMapActivity$4
when attempting to open a new FragmentMapActivity.
Code:
public class Maps extends FragmentMapActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.maps_simple);
//MapView for the lose :(
Toast.makeText(this, R.string.map_warning, Toast.LENGTH_LONG).show();
MapView mapView = (MapView)findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
R.layout.maps_simple contains:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="<key removed for security>"
/>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="osmstudios.mappingapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="13" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application android:icon="#drawable/icon" android:label="#string/app_name" android:theme="#style/Theme.MapApp" android:hardwareAccelerated="true">
<uses-library android:name="com.google.android.maps" />
<activity android:label="#string/app_name" android:name=".AppMainActivity">
<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>
<activity android:label="#string/app_name" android:name="com.keyes.youtube.OpenYouTubePlayerActivity"></activity>
<activity android:label="#string/app_name" android:name=".Maps">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="osmstudios.mappingapp" />
</intent-filter>
</activity>
</application>
</manifest>
Here is the inner code of the button press that opens the FragmentMapActivity intent:
Intent intent = new Intent(ctx, Maps.class);
startActivity(intent);
Finally, this is what my Libraries folder in the Java Build Path tool look like:
I've been really beating my head against a wall on this one. Any help would be appreciated.
This is bit late but I had the exact same issue and could at least resolve the "java.lang.NoClassDefFoundError:". In project property->java Build path -> Libraries, I had included android-support-v4.jar from android sdk path. This lib was available during compile time but not at run time. You need to copy this jar from sdk path to application libs location that way this lib is statically added to your app and could be found during run time. hope this helps. This solution I found after lots of search in StackOverFlow. Hers is the link. Trying to use DialogFragments via v4 compatability causes NoClassDefFoundErrors
It turns out the issue had to do with a change in Android versions.
More information and the fix can be found http://www.wiseappsllc.com/homepage/android-dev-tips
I had same problem, then i resolved it by checking the build path of the project. There i had two map jars. I deleted one in libraries, Now it is working fine. Just check it may work.