I have two applications that I want to send data between, lets call them ProviderApp and ResolverApp.
In the ProviderApp I have a Content Provider. Here is the AndroidManifest file for this app.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rewardreacher">
<permission android:name="android.permission.READ_GOALS"
/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher_reward"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_reward_round"
android:supportsRtl="true"
android:theme="#style/Theme.RewardReacher">
<provider
android:name=".provider.MyContentProvider"
android:authorities="com.example.rewardreacher.provider.MyContentProvider"
android:readPermission="android.permission.READ_GOALS"
android:multiprocess="true"
android:enabled="true"
android:exported="true">
</provider>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Now I am trying to access this data from ResolverApp using this AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.workouttracker">
<uses-permission android:name="android.permission.READ_GOALS"/>
<queries>
<provider android:authorities="com.example.rewardreacher.provider.MyContentProvider"/>
</queries>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher_workout"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_workout_round"
android:supportsRtl="true"
android:theme="#style/Theme.WorkoutTracker">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And MainActivity
package com.example.workouttracker
import android.Manifest
import android.annotation.SuppressLint
import android.content.ContentValues.TAG
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
private fun isStoragePermissionGranted(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED
) {
Log.v(TAG, "Permission is granted")
true
} else {
Log.v(TAG, "Permission is revoked")
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
1
)
false
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG, "Permission is granted")
true
}
}
#SuppressLint("Range")
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission: " + permissions[0] + "was " + grantResults[0])
val resultView = findViewById<View>(R.id.res) as TextView
val cursor = contentResolver.query(CONTENT_URI, null, null, null, null)
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append("""
${cursor.getString(cursor.getColumnIndex("id"))} - ${cursor.getString(cursor.getColumnIndex("name"))} - ${cursor.getString(cursor.getColumnIndex("frequency"))} - ${cursor.getString(cursor.getColumnIndex("performed"))}
""".trimIndent())
cursor.moveToNext()
}
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
}
}
}
var CONTENT_URI = Uri.parse("content://com.example.rewardreacher.provider.MyContentProvider/goals")
#SuppressLint("Range")
fun onClickShowDetails(view: View?) {
// inserting complete table details in this text field
isStoragePermissionGranted()
// creating a cursor object of the
// content URI
}
}
But I keep getting "Permission is revoked" from the isStoragePermissionGranted()...
What am I doing wrong?
Related
I'm having issues getting Branch to recognize that I clicked on a branch link.
I'm launching the following from hangouts: mens-essentials-mag.test-app.link
I get "+is_first_session":true
but always "+clicked_branch_link":false
Things I've done:
In my Activity:
#Override
protected void onStart() {
super.onStart();
Branch.getTestInstance(this).initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
if (error == null) {
Log.i("BRANCH SDK", referringParams.toString());
} else {
Log.i("BRANCH SDK", error.getMessage());
}
}
}, this.getIntent().getData(), this);
}
In my Application:
// Branch logging for debugging
Branch.enableLogging();
// Branch object initialization
Branch.getAutoTestInstance(this);
In Manifest:
<!-- Branch App Links (optional) -->
<intent-filter android:autoVerify="true">
<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="mens-essentials-mag.test-app.link" />
<data android:scheme="https" android:host="mens-essentials-mag-alternate.test-app.link" />
</intent-filter>
and
<!-- Branch init -->
<meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_[myLiveKey]" />
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="key_test_[myTestKey]" />
<meta-data android:name="io.branch.sdk.TestMode" android:value="true" /> <!-- Set to true to use Branch_Test_Key -->
<!-- Branch install referrer tracking (optional) -->
<receiver android:name="io.branch.referral.InstallListener" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
Also, I used this:
branch.initSessionTtl = 10000;
branch.subscribe(({error, params}) => {
if (error) {
console.log('Error from Branch: ' + error);
return;
} else if (params?.provider_group?.allow_patient_registration_app) {
this.setState({
showSignUp: params?.provider_group?.allow_patient_registration_app,
});
this.props.navigation.navigate('Signup');
}
console.log('Received link response from Branch', params);
});
let lastParams = await branch.getLatestReferringParams();
console.log('Received link response from Branch', lastParams);
This is my code and I can't see what is the problem. The error I keep seeing is No adapter attached; skipping layout.
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gsixacademy.android.bikesrevisited">
<uses-permission android:name="android.permission.INTERNET"/>
<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.BikesRevisited"
android:usesCleartextTraffic="true"
>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
ADAPTER:
package com.gsixacademy.android.bikesrevisited.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gsixacademy.android.bikesrevisited.R
import com.gsixacademy.android.bikesrevisited.models.BikeModel
import com.gsixacademy.android.bikesrevisited.models.BikeResult
import kotlinx.android.synthetic.main.bikes_custom_row.view.*
class Adapter(
var bikeList: ArrayList<BikeResult>,
val bikesOnClickEvent:(BikesOnClickEvent)->Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.bikes_custom_row, parent, false)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
var myHolder = holder as MyViewHolder
myHolder.bindData(bikeList[position], position)
}
inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bindData(itemModel: BikeResult, position: Int) {
itemView.city_TV.text = itemModel.city
itemView.country_TV.text = itemModel.country
}
}
override fun getItemCount(): Int {
return bikeList.size
}
}
BIKES ON CLICK EVENT:
package com.gsixacademy.android.bikesrevisited.adapters
import com.gsixacademy.android.bikesrevisited.models.BikeResult
sealed class BikesOnClickEvent {
data class BikesClicked(val bike:BikeResult):BikesOnClickEvent()
}
APISERVICEBUILDER:
package com.gsixacademy.android.bikesrevisited.api
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object ApiServiceBuilder {
val client=OkHttpClient.Builder().build()
val retrofit= Retrofit.Builder()
.baseUrl("http://api.citybik.es/v2/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
fun <T>buildService(service:Class<T>):T{
return retrofit.create(service)
}
}
BIKESAPI:
package com.gsixacademy.android.bikesrevisited.api
import com.gsixacademy.android.bikesrevisited.models.BikeModel
import retrofit2.Call
import retrofit2.http.GET
interface BikesApi {
#GET("networks")
fun getBikes(): Call<BikeModel>
}
BIKE MODEL
package com.gsixacademy.android.bikesrevisited.models
class BikeModel (val networks:ArrayList<BikeResult> )
BIKE RESULT
package com.gsixacademy.android.bikesrevisited.models
class BikeResult (
val city:String,val country:String
)
BIKE FRAGMENT
package com.gsixacademy.android.bikesrevisited
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.gsixacademy.android.bikesrevisited.R
import kotlinx.android.synthetic.main.recycler_view.*
import androidx.recyclerview.widget.LinearLayoutManager
import com.gsixacademy.android.bikesrevisited.adapters.Adapter
import com.gsixacademy.android.bikesrevisited.api.ApiServiceBuilder
import com.gsixacademy.android.bikesrevisited.api.BikesApi
import com.gsixacademy.android.bikesrevisited.models.BikeModel
import com.gsixacademy.android.bikesrevisited.models.BikeResult
import kotlinx.android.synthetic.main.recycler_view.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class BikeFragment:Fragment() {
var request=ApiServiceBuilder.buildService(BikesApi::class.java)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view=inflater.inflate(R.layout.recycler_view,container,false)
val call=request.getBikes()
call.enqueue(object :Callback<BikeModel>{
override fun onResponse(call: Call<BikeModel>, response: Response<BikeModel>) {
if (response.isSuccessful){
var bikeResponse=response.body()
var bikeList=bikeResponse?.networks
if (bikeList!=null){
var bikelistAdapter=Adapter(bikeList){
}
recycler_view.layoutManager=LinearLayoutManager(context)
recycler_view.adapter=bikelistAdapter
}
}
else{}
}
override fun onFailure(call: Call<BikeModel>, t: Throwable) {
Toast.makeText(activity,t.message, Toast.LENGTH_SHORT)
.show()
}
})
return view
}
}
MAIN ACTIVITY:
package com.gsixacademy.android.bikesrevisited
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
SPLASH FRAGMENT:
package com.gsixacademy.android.bikesrevisited
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class SplashFragment:Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.splash,container,false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
GlobalScope.launch {
Thread.sleep(1500)
findNavController().navigate(R.id.action_splashFragment_to_bikeFragment)
}
}
}
layouts
activity_main
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="#+id/navigation_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:navGraph="#navigation/navigation_graph"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
bikes_custom_row
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:id="#+id/card_view_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="10dp"
app:cardCornerRadius="10dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
tools:ignore="UseCompoindDrawables">
<TextView
android:id="#+id/city_TV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="city"
android:textColor="#color/black"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="#+id/country_TV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="country"
android:textColor="#color/black"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
recycler_view
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_view"/>
</androidx.constraintlayout.widget.ConstraintLayout>
splash
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/ic_launcher_background"
android:scaleType="centerInside"/>
</androidx.constraintlayout.widget.ConstraintLayout>
navigation_graph
<?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"
android:id="#+id/navigation_graph"
app:startDestination="#id/splashFragment">
<fragment
android:id="#+id/splashFragment"
android:name="com.gsixacademy.android.bikesrevisited.SplashFragment"
android:label="SplashFragment" >
<action
android:id="#+id/action_splashFragment_to_bikeFragment"
app:destination="#id/bikeFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="#+id/bikeFragment"
android:name="com.gsixacademy.android.bikesrevisited.BikeFragment"
android:label="BikeFragment" />
</navigation>
com.google.android.gms.vision.ica not found.
W/DynamiteModule: Local module descriptor class for com.google.android.gms.vision.ica not found.
I/DynamiteModule: Considering local module com.google.android.gms.vision.ica:0 and remote module com.google.android.gms.vision.ica:0
AndroidManifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vt.shoppet">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".ShopPetApp"
android:allowBackup="false"
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=".ui.MainActivity"
android:exported="true"
android:theme="#style/SplashTheme"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/ic_pet" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorAccent" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/menu_item_chat" />
<meta-data android:name="com.google.mlkit.vision.DEPENDENCIES" android:value="ica" />
<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="ica"/>
<meta-data
android:name="firebase_performance_logcat_enabled"
android:value="true" />
<service
android:name=".MessagingService"
android:exported="false"
android:permission="android.permission.INTERNET">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
Build in Project
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath(kotlin("gradle-plugin", "1.5.30"))
classpath("com.android.tools.build:gradle:7.0.2")
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5")
classpath("com.google.dagger:hilt-android-gradle-plugin:2.38.1")
classpath("com.google.gms:google-services:4.3.10")
classpath("com.google.firebase:firebase-crashlytics-gradle:2.7.1")
classpath("com.google.firebase:perf-plugin:1.4.0")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
tasks {
register("clean", Delete::class) {
delete(rootProject.buildDir)
}
}
built in app
plugins {
id("com.android.application")
kotlin("android")
kotlin("kapt")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
id("com.google.firebase.firebase-perf")
id("dagger.hilt.android.plugin")
id("androidx.navigation.safeargs.kotlin")
}
android {
compileSdk = 31
buildToolsVersion = "31.0.0"
ndkVersion = "23.0.75998587"
defaultConfig {
applicationId = "com.vt.shoppet"
minSdk = 23
targetSdk = 31
versionCode = 1
versionName = "1.0"
}
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
freeCompilerArgs = listOf("-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi")
}
buildFeatures {
viewBinding = true
}
lint {
isCheckDependencies = true
isCheckGeneratedSources = true
}
splits {
abi {
isEnable = true
isUniversalApk = true
}
}
}
dependencies {
// Kotlin / Java
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.5.2")
// Android Architecture Components
implementation("androidx.activity:activity-ktx:1.4.0")
implementation("androidx.appcompat:appcompat:1.4.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.2")
implementation("androidx.coordinatorlayout:coordinatorlayout:1.1.0")
implementation("androidx.drawerlayout:drawerlayout:1.1.1")
implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.fragment:fragment-ktx:1.4.0")
implementation("androidx.preference:preference-ktx:1.1.1")
implementation("androidx.recyclerview:recyclerview:1.2.1")
kapt("androidx.hilt:hilt-compiler:1.0.0")
// CameraX
val cameraVersion = "1.0.1"
implementation("androidx.camera:camera-camera2:$cameraVersion")
implementation("androidx.camera:camera-core:$cameraVersion")
implementation("androidx.camera:camera-lifecycle:$cameraVersion")
implementation("androidx.camera:camera-view:1.0.0-alpha31")
// Firebase
implementation(platform("com.google.firebase:firebase-bom:28.4.1"))
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.google.firebase:firebase-core")
implementation("com.google.firebase:firebase-crashlytics-ktx")
implementation("com.google.firebase:firebase-firestore-ktx")
implementation("com.google.firebase:firebase-iid")
implementation("com.google.firebase:firebase-messaging")
implementation("com.google.firebase:firebase-perf-ktx")
implementation("com.google.firebase:firebase-storage-ktx")
implementation ("org.tensorflow:tensorflow-lite:1.13.1")
// ML Kit
implementation("com.google.android.gms:play-services-mlkit-image-labeling:16.0.5")
// Firebase UI
val firebaseUiVersion = "8.0.0"
implementation("com.firebaseui:firebase-ui-firestore:$firebaseUiVersion")
implementation("com.firebaseui:firebase-ui-storage:$firebaseUiVersion")
// Glide
val glideVersion = "4.12.0"
implementation("com.github.bumptech.glide:glide:$glideVersion")
kapt("com.github.bumptech.glide:compiler:$glideVersion")
// Hilt
val hiltAndroidVersion = "2.38.1"
implementation("com.google.dagger:hilt-android:$hiltAndroidVersion")
kapt("com.google.dagger:hilt-android-compiler:$hiltAndroidVersion")
// Lifecycle
val lifecycleVersion = "2.3.1"
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-process:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
// Material Components
implementation("com.google.android.material:material:1.4.0")
// Navigation Component
val navigationVersion = "2.3.5"
implementation("androidx.navigation:navigation-fragment-ktx:$navigationVersion")
implementation("androidx.navigation:navigation-ui-ktx:$navigationVersion")
}
kapt {
correctErrorTypes = true
}
hilt {
enableAggregatingTask = true
}
I followed the instructions here https://github.com/react-native-community/react-native-maps/blob/master/docs/installation.md to use MapView on my react-native project. I write in the good place my google map API key but the code still not find it.
Sometimes this error does not appear and my application just crash.
My react-native version is 0.60.4 so I only did the modification for version 0.59 and higher but to verify I also tried with the others modification and nothing resolve this problem.
This is android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="A...w"/>
</application>
This is android/build.gradle
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
supportLibVersion = "28.0.0"
}
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.4.1")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
google()
jcenter()
}
}
/**
+ Project-wide Gradle configuration properties
*/
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
supportLibVersion = "28.0.0"
playServicesVersion = "11.8.0" // or set latest version
androidMapsUtilsVersion = "0.5+"
}
And this is my App.js
import React from 'react'
import {StyleSheet, Text, View, Button} from 'react-native'
//import Main from './screens/Main'
import Navigation from './Navigation/Navigation'
import MapView from 'react-native-maps';
export default class App extends React.Component{
_loadSports(){
}
render () {
return (
<View>
<MapView
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
</View>
//<Navigation/>
)
}
}
const styles = StyleSheet.create({
container : {
flex : 1,
alignItems : 'center',
justifyContent:'center',
}
})
I just expect to solve this problem :/
If your React-Native version is less than (0.6)
You have to add this to the setting.gradle file
include ':react-native-maps'
project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android')
if the error persist please follow the docs carefully on
github react-native-maps installation
In my case it was because of application is running. Stop your running application and rerun it.
I am following the tutorial of the official android SDK,and try to write a simple log in program.
So what I did is..
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.logintutorial"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="20" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/app_id"/>
</manifest>
The MainActivity simply uses fragment transaction.
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
public class MainActivity extends FragmentActivity {
private MainFragment mainFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
mainFragment = new MainFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, mainFragment)
.commit();
} else {
// Or set the fragment from restored state info
mainFragment = (MainFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}
}
}
The MainFragment class is used for the Session Management with the help of the UiLifecyleHelper and the Session.StatusCallBack class.
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.widget.LoginButton;
public class MainFragment extends Fragment {
private static final String TAG = "MainFragment";
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(final Session session, final SessionState state, final Exception exception)
{
onSessionStateChange(session, state, exception);
}
};
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
LoginButton authButton = (LoginButton) view.findViewById(R.id.authButton);
authButton.setFragment(this);
//authButton.setReadPermissions(Arrays.asList("user_likes", "user_status"));
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
// For scenarios where the main activity is launched and user
// session is not null, the session state change notification
// may not be triggered. Trigger it if it's open/closed.
Session session = Session.getActiveSession();
if (session != null &&
(session.isOpened() || session.isClosed()) ) {
onSessionStateChange(session, session.getState(), null);
}
uiHelper.onResume();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
}
Also the main activity's xml file...
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.facebook.widget.LoginButton
android:id="#+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
/>
</LinearLayout>
and finally I put the app id in the string.xml file as
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Login Tutorial</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="app_id">XXX6999249XXXXX</string>
</resources>
When I run it, I get the following exception.
11-10 13:01:46.784: E/AndroidRuntime(31157): FATAL EXCEPTION: main
11-10 13:01:46.784: E/AndroidRuntime(31157): java.lang.RuntimeException:
Unable to start activity
ComponentInfo{com.example.logintutorial/com.example.logintutorial.MainActivity}:
java.lang.NullPointerException: Argument 'applicationId' cannot be null
The metadata tag has to be inside the application tag and not outside!. Change manifest to:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.logintutorial"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="20" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/app_id"/>
</application>
</manifest>