My app keeps crashing as I try to start a new activity (uploadLocation.class).
No errors are highlighted and I can't debug within the uploadLocation class.
I have added permissions to my Manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
MainActivity
As this section of code from the MainActivity is executed the application crashes.
public void uploadMyLocation (View view){
startActivity(new Intent(this, uploadLocation.class));
}
Other than the this class works as it should (complete MainActivity.java below)
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
Button uploadButton;
TextView latitudeView, longitudeView, networkView;
Location lastKnownLocation;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
String latString1, lonString1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uploadButton = (Button) findViewById(R.id.uploadButton);
networkView = (TextView) findViewById(R.id.networkView);
latitudeView = (TextView)findViewById(R.id.latitudeView);
longitudeView = (TextView)findViewById(R.id.longitudeView);
buildGoogleApiClient();
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()){
networkView.setVisibility(View.INVISIBLE);
} else {
uploadButton.setEnabled(false);
}
}
public void uploadMyLocation (View view){
startActivity(new Intent(this, uploadLocation.class));
}
#Override
public void onConnected(Bundle bundle) {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(100); // location updated every second
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
lastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if(lastKnownLocation != null){
latString1 = String.valueOf(lastKnownLocation.getLatitude());
lonString1 = String.valueOf(lastKnownLocation.getLongitude());
}
updateUI();
}
#Override
public void onLocationChanged(Location location) {
latString1 = String.valueOf(location.getLatitude());
lonString1 = String.valueOf(location.getLongitude());
updateUI();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
buildGoogleApiClient();
}
synchronized void buildGoogleApiClient(){
googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
}
#Override
protected void onStart(){
super.onStart();
googleApiClient.connect();
}
#Override
protected void onDestroy(){
super.onDestroy();
googleApiClient.disconnect();
}
void updateUI(){
latitudeView.setText(latString1);
longitudeView.setText(lonString1);
}
}
uploadLocation
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
public class uploadLocation extends AppCompatActivity {
TextView myLatitudeView, myLongitudeView, latitudeView, longitudeView;
String latString, lonString;
public void uploadInfo(View view){
latString = latitudeView.getText().toString();
lonString = longitudeView.getText().toString();
myLatitudeView = (TextView)findViewById(R.id.myLatitudeView);
myLongitudeView = (TextView)findViewById(R.id.myLongitudeView);
myLatitudeView.setText(latString);
myLongitudeView.setText(lonString);
BackgroundOp backgroundOp = new BackgroundOp();
backgroundOp.execute(latString, lonString);
finish();
}
class BackgroundOp extends AsyncTask<String, Void, String>{
String myUrl;
#Override
protected void onPreExecute() {
myUrl = "http://[web address]/[php script]";
}
#Override
protected String doInBackground(String... data) {
String latString, lonString;
latString = data [0];
lonString = data [1];
try {
URL url = new URL(myUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String myDataStream = URLEncoder.encode("Latitude", "UTF-8") + "=" + URLEncoder.encode(latString, "UTF-8") + "&" +
URLEncoder.encode("Longitude", "UTF-8") + "=" + URLEncoder.encode(lonString, "UTF-8");
bufferedWriter.write(myDataStream);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
inputStream.close();
httpURLConnection.disconnect();
return "Upload Successful";
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}
}
XML file
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Upload Location"
android:id="#+id/uploadButton"
android:layout_marginBottom="61dp"
android:layout_above="#+id/networkView"
android:layout_centerHorizontal="true"
android:onClick="uploadInfo" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Data"
android:id="#+id/getDataButton"
android:onClick="uploadMyLocation"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="41dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[Latitude]"
android:id="#+id/latitudeView"
android:layout_centerVertical="true"
android:layout_toStartOf="#+id/uploadButton" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[Longitude]"
android:id="#+id/longitudeView"
android:layout_alignTop="#+id/latitudeView"
android:layout_toEndOf="#+id/uploadButton" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[My Latitude]"
android:id="#+id/myLatitudeView"
android:layout_below="#+id/getDataButton"
android:layout_toStartOf="#+id/getDataButton" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[My Longitude]"
android:id="#+id/myLongitudeView"
android:layout_below="#+id/getDataButton"
android:layout_toEndOf="#+id/getDataButton" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[Network Unavailable]"
android:id="#+id/networkView"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="169dp" />
Compiler log:
03-24 16:11:26.893 17436-17436/? I/art: Late-enabling -Xcheck:jni
03-24 16:11:27.044 17436-17467/com.cityuni.sophie.locationapp I/GMPM: App measurement is starting up
03-24 16:11:27.058 17436-17467/com.cityuni.sophie.locationapp E/GMPM: getGoogleAppId failed with status: 10
03-24 16:11:27.059 17436-17467/com.cityuni.sophie.locationapp E/GMPM: Uploading is not possible. App measurement disabled
03-24 16:11:27.155 17436-17475/com.cityuni.sophie.locationapp D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
03-24 16:11:27.160 17436-17436/com.cityuni.sophie.locationapp D/Atlas: Validating map...
03-24 16:11:27.208 17436-17475/com.cityuni.sophie.locationapp I/Adreno: QUALCOMM build : 40d, I21dda
Build Date : 08/24/15
OpenGL ES Shader Compiler Version: E031.25
Local Branch :
Remote Branch : quic/LA.4.1.1_r9
Remote Branch : NONE
Reconstruct Branch : NOTHING
03-24 16:11:27.216 17436-17475/com.cityuni.sophie.locationapp I/OpenGLRenderer: Initialized EGL, version 1.4
03-24 16:11:27.225 17436-17475/com.cityuni.sophie.locationapp D/OpenGLRenderer: Enabling debug mode 0
03-24 16:11:27.388 17436-17436/com.cityuni.sophie.locationapp I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#3563b026 time:407225888
03-24 16:11:45.883 17436-17436/com.cityuni.sophie.locationapp D/AndroidRuntime: Shutting down VM
03-24 16:11:45.902 17436-17436/com.cityuni.sophie.locationapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.cityuni.sophie.locationapp, PID: 17436
java.lang.IllegalStateException: Could not find method uploadInfo(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'uploadButton'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:325)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:4861)
at android.view.View$PerformClick.run(View.java:19980)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5373)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
03-24 16:12:19.041 17436-17436/com.cityuni.sophie.locationapp I/Process: Sending signal. PID: 17436 SIG: 9
To kindly inform you Every Activity needs to override onCreate() method as per doc
This method is Called when the activity is starting. This is where most initialization should go: calling setContentView(int) to inflate the activity's UI, using findViewById(int) to programmatically interact with widgets in the UI
I suggest you to override necessary methods And also don't forget to call super.onCreate() inside onCreate() method.
UPDATE :
I figured out your error, That is because of this attribute
android:onClick="uploadInfo"
Because XML you provided is activity_main.xml. And you are making the method uploadInfo in another Activity. So I suggest you either remove this attribute OR create uploadInfo method in MainActivity not inside uploadLocation Activity.
To get hints you can press Alt+Enter on that attribute and create method uploadInfo as Android Studio suggests you.
I think you have not added your new activity to the android manifest file.
Try adding this.
<activity android:name=".uploadLocation">
</activity>
When I've start the development on Android I've meet the same problem and i use this for fix my app crash :
Try extends Activity instead of extends AppCompatActivity.
If don't work maybe you have an Component null, check you instanciate all component declared in your XML.
Related
I am new to android studio and I tried to get html content of a webpage using AsyncTask class(deprecated API).I have attached my AndroidManifest.xml file. I have added the neccessary permisions to access internet,still i am getting the error "E/Zygote : no v2" and my app crashes. Please explain what does this error mean and how to eliminate the error.I launched the app in a phone with Android 6.0.1
public class MainActivity extends AppCompatActivity {
public static class DownloadTask extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... urls) {
String result ="";
URL url;
HttpsURLConnection urlConnection;
try {
url = new URL(urls[0]);
urlConnection =(HttpsURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data!=-1){
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
But the LogCat came up with this error
[08-11 11:46:36.426 27036-27036/? E/Zygote: no v2
08-11 11:46:36.426 27036-27036/? W/SELinux: Function: selinux_compare_spd_ram, index[1], priority [2], priority version is VE=SEPF_SECMOBILE_6.0.1_0035
08-11 11:46:36.436 27036-27036/? W/SELinux: SELinux: seapp_context_lookup: seinfo=default, level=s0:c512,c768, pkgname=com.example.guessthecelebrity
08-11 11:46:36.436 27036-27036/? I/art: Late-enabling -Xcheck:jni
08-11 11:46:36.827 27036-27036/com.example.guessthecelebrity D/ResourcesManager: For user 0 new overlays fetched Null
08-11 11:46:36.847 27036-27036/com.example.guessthecelebrity W/System: ClassLoader referenced unknown path: /data/app/com.example.guessthecelebrity-2/lib/arm
08-11 11:46:36.907 27036-27036/com.example.guessthecelebrity D/ResourcesManager: For user 0 new overlays fetched Null
08-11 11:46:36.927 27036-27036/com.example.guessthecelebrity W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter androidx.vectordrawable.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.guessthecelebrity">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permissioandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:largeHeap="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>
</application>
</manifest>
I guess you are not good at using AsyncTask. You are not executing the AsyncTask anywhere. How ever, a better clean approach will be as follows,
XML
<?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="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="#+id/url_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Input a web page url to get." />
<Button
android:id="#+id/url_request_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Request Page"
android:onClick="downloadSiteData"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/url_response"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
MainActivity with AsyncTask:
package com.example.downloadsite;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
EditText urlRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
urlRequest = findViewById(R.id.url_request);
}
public void downloadSiteData(View view) {
String url = urlRequest.getText().toString();
if ( url.equals("")) {
Toast.makeText(MainActivity.this, "URL can't be empty", Toast.LENGTH_SHORT).show();
}
else {
new DownloadTask().execute(url);
}
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(MainActivity.this, "Downloading site data", Toast.LENGTH_SHORT).show();
}
#Override
protected String doInBackground(String... urls) {
String value = urls[0];
String response = null;
URL url = null;
HttpURLConnection urlConnection = null;
InputStream in = null;
try {
url = new URL(value);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
response = readStream(in);
} catch (Exception e) { e.printStackTrace(); }
finally {
urlConnection.disconnect();
}
return response;
}
private String readStream(InputStream inputStream) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String nextLine = "";
String newLine = "";
while ((newLine = reader.readLine()) != null) {
sb.append(nextLine + newLine);
}
} catch (IOException e) { e.printStackTrace(); }
return sb.toString();
}
#Override
protected void onPostExecute(String responseString) {
super.onPostExecute(responseString);
TextView tv = findViewById(R.id.url_response);
tv.setText(responseString);
}
}
}
I'm writing a program where after clicking this button another program will be started.
However, the program force closed when I click the corresponding button.
here's the code.
package com.example.pc.multi_functionapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button)findViewById(R.id.button_1);
Button button2 = (Button)findViewById(R.id.button_2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent int1 = new Intent(MainActivity.this, Accelerometer.class);
startActivity(int1);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent int2 = new Intent(MainActivity.this, Locator.class);
startActivity(int2);
}
});
}
}
Here's the XML code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical"
android:padding="16dp"
android:layout_gravity="center_horizontal"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:id="#+id/button_1"
android:text="Android Accelerometer"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:id="#+id/button_2"
android:text="Android Current Location"
/>
</LinearLayout>
Here's the android manifest code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pc.multi_functionapp">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<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=".Locator"></activity>
<activity android:name=".Accelerometer" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</man
For the program itself, Accelerometer and Locator work properly if I running it one by one.
I'm creating this program in purpose, these two programs can be run in one app, no need to open it in a different app.
I'm expecting after I click the first button, the accelerometer program will be started and when I click the second button, the Locator program will be started.
what happened is, when I click it the program just force closed.
please help me so the button works properly when clicked.
Edit :
Accelerometer Code
package com.example.pc.multi_functionapp;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class Accelerometer extends AppCompatActivity implements SensorEventListener {
private static final String TAG = "MainActivity";
private SensorManager sensorManager;
Sensor accelerometer;
TextView xValue, yValue, zValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
xValue = (TextView) findViewById(R.id.xValue);
yValue = (TextView) findViewById(R.id.yValue);
zValue = (TextView) findViewById(R.id.zValue);
Log.d(TAG, "onCreate: initializing Sensor Services");
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(Accelerometer.this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
Log.d(TAG, "onCreate: Registered accelerometer listener");
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
Log.d(TAG, "onSensorChanged: X: " + sensorEvent.values[0] + "Y: " + sensorEvent.values[1] + "Z: " + sensorEvent.values[2]);
xValue.setText("xValue: " + sensorEvent.values[0]);
yValue.setText("yValue: " + sensorEvent.values[1]);
zValue.setText("xValue: " + sensorEvent.values[2]);
}
}
Locator Code
package com.example.pc.multi_functionapp;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.text.Html;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class Locator extends AppCompatActivity {
TextView textView1, textView2, textView3, textView4, textView5;
FusedLocationProviderClient fusedLocationProviderClient;
Button btLocation;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btLocation = findViewById(R.id.bt_location);
textView1 = findViewById(R.id.text_view1);
textView2 = findViewById(R.id.text_view2);
textView3 = findViewById(R.id.text_view3);
textView4 = findViewById(R.id.text_view4);
textView5 = findViewById(R.id.text_view5);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
btLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(Locator.this
, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
getLocation();
}
else {
ActivityCompat.requestPermissions(Locator.this
, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 44);
}
}
});
}
private void getLocation() {
fusedLocationProviderClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
Location location = task.getResult();
if (location != null){
try {
Geocoder geocoder = new Geocoder(Locator.this, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1 );
textView1.setText(Html.fromHtml("<font color='#6200EE'><B>Latitude :</b><br></font>" + addresses.get(0).getLatitude()));
textView2.setText(Html.fromHtml("<font color='#6200EE'><B>Longitude :</b><br></font>" + addresses.get(0).getLongitude()));
textView3.setText(Html.fromHtml("<font color='#6200EE'><B>Country Name :</b><br></font>" + addresses.get(0).getCountryName()));
textView4.setText(Html.fromHtml("<font color='#6200EE'><B>Locality :</b><br></font>" + addresses.get(0).getLocality()));
textView5.setText(Html.fromHtml("<font color='#6200EE'><B>Address :</b><br></font>" + addresses.get(0).getAddressLine(0)));
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
}
Before CLicked
After Clicked
Oh, your error is simple.
I think you have copied the Activities and you have forgotten to change the layout in the setContentView() of all of your Activities. all of them are R.layout.activity_main so the app is starting the activity_main.xml but the view are getting findViewById() from their real resources.
Crash maybe because of the two reasons.
Make sure you have separate layout for all your activities.
Make sure your activities added in the AndroidManifest.xml file.
To debug, I tried to migrate to a blank activity still it shows the same error. Can't understand why!
So i have that error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: thingtranslator2.jalle.com.thingtranslator2, PID: 14918
java.lang.IllegalStateException: Could not execute method for android:onClick
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24704)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6590)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24704)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6590)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/thingtranslator2.jalle.com.thingtranslator2/cache/tempImage exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1958)
at android.net.Uri.checkFileUriExposed(Uri.java:2357)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:941)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9735)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9741)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9720)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1618)
at android.app.Activity.startActivityForResult(Activity.java:4482)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
at android.app.Activity.startActivityForResult(Activity.java:4440)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
at thingtranslator2.jalle.com.thingtranslator2.MainActivity.getImage(MainActivity.java:157)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24704)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6590)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
And this is my MainActivity code :
package thingtranslator2.jalle.com.thingtranslator2;
import android.app.ProgressDialog;
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.pixplicity.easyprefs.library.Prefs;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import thingtranslator2.jalle.com.thingtranslator2.Rest.ApiInterface;
import thingtranslator2.jalle.com.thingtranslator2.Rest.Translation;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
public
#BindView(R.id.txtTranslation)
TextView txtTranslation;
public
#BindView(R.id.spinner)
Spinner spinner;
public
#BindView(R.id.imgPhoto)
ImageButton imgPhoto;
public
#BindView(R.id.imgSpeaker)
ImageButton btnSpeaker;
public Boolean speakerOn, firstRun;
public TextToSpeech tts;
public List<String> languages = new ArrayList<String>();
public ArrayList<Language> languageList = new ArrayList<Language>();
public ArrayAdapter<Language> spinnerArrayAdapter;
public Language selectedLanguage;
public static final int PICK_IMAGE_ID = 234; // the number doesn't matter
thingtranslator2.jalle.com.thingtranslator2.Tools.MarshMallowPermission marshMallowPermission = new thingtranslator2.jalle.com.thingtranslator2.Tools.MarshMallowPermission(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ButterKnife.bind(this);
btnSpeaker = (ImageButton)findViewById(R.id.imgSpeaker);
imgPhoto = (ImageButton)findViewById(R.id.imgPhoto);
spinner = (Spinner)findViewById(R.id.spinner);
txtTranslation = (TextView)findViewById(R.id.txtTranslation);
//init our Shared preferences helper
new Prefs.Builder()
.setContext(this)
.setMode(ContextWrapper.MODE_PRIVATE)
.setPrefsName(getPackageName())
.setUseDefaultSharedPreference(true)
.build();
// Prefs.clear();
firstRun = Prefs.getBoolean("firstRun", true);
spinner.setOnItemSelectedListener(this);
tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
fillSpinner();
}
}
});
if (firstRun) {
Prefs.putBoolean("firstRun", false);
Prefs.putBoolean("speakerOn", true);
Prefs.putString("langCode", "bs");
}
setSpeaker();
}
private void setSpeaker() {
int id = Prefs.getBoolean("speakerOn", false) ? R.drawable.ic_volume : R.drawable.ic_volume_off;
btnSpeaker.setImageBitmap(BitmapFactory.decodeResource(getResources(), id));
}
public void ToogleSpeaker(View v) {
Prefs.putBoolean("speakerOn", !Prefs.getBoolean("speakerOn", false));
setSpeaker();
Toast.makeText(getApplicationContext(), "Speech " + (Prefs.getBoolean("speakerOn", true) ? "On" : "Off"), Toast.LENGTH_SHORT);
}
private void fillSpinner() {
Iterator itr = tts.getAvailableLanguages().iterator();
while (itr.hasNext()) {
Locale item = (Locale) itr.next();
languageList.add(new Language(item.getDisplayName(), item.getLanguage()));
}
//Sort that array
Collections.sort(languageList, new Comparator<Language>() {
#Override
public int compare(Language o1, Language o2) {
return o1.getlangCode().compareTo(o2.getlangCode());
}
});
spinnerArrayAdapter = new ArrayAdapter<Language>(this, R.layout.spinner_item, languageList);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter);
String def = Prefs.getString("langCode", "bs");
for (Language lang : languageList) {
if (lang.getlangCode().equals(def)) {
spinner.setSelection(languageList.indexOf(lang));
}
}
}
//Get image from Gallery or Camera
public void getImage(View v) {
if (!marshMallowPermission.checkPermissionForCamera()) {
marshMallowPermission.requestPermissionForCamera();
} else {
if (!marshMallowPermission.checkPermissionForExternalStorage()) {
marshMallowPermission.requestPermissionForExternalStorage();
} else {
Intent chooseImageIntent = thingtranslator2.jalle.com.thingtranslator2.Tools.ImagePicker.getPickImageIntent(getApplicationContext());
startActivityForResult(chooseImageIntent, PICK_IMAGE_ID);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) return;
switch (requestCode) {
case PICK_IMAGE_ID:
Bitmap bitmap = thingtranslator2.jalle.com.thingtranslator2.Tools.ImagePicker.getImageFromResult(this, resultCode, data);
imgPhoto.setImageBitmap(null);
imgPhoto.setBackground(null);
imgPhoto.setImageBitmap(bitmap);
imgPhoto.invalidate();
imgPhoto.postInvalidate();
File file = null;
try {
file = savebitmap(bitmap, "pic.jpeg");
} catch (IOException e) {
e.printStackTrace();
}
uploadImage(file);
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
private void uploadImage(File file) {
RequestBody body = RequestBody.create(MediaType.parse("image/*"), file);
RequestBody langCode1 = RequestBody.create(MediaType.parse("text/plain"), selectedLanguage.langCode);
final ProgressDialog progress = new ProgressDialog(this);
progress.setMessage("Processing image...");
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setIndeterminate(true);
progress.show();
ApiInterface mApiService = ApiInterface.retrofit.create(ApiInterface.class);
Call<Translation> mService = mApiService.upload(body, langCode1);
mService.enqueue(new Callback<Translation>() {
#Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
progress.hide();
Translation result = response.body();
txtTranslation.setText(result.Translation);
txtTranslation.invalidate();
if (Prefs.getBoolean("speakerOn", true)) {
tts.speak(result.Translation, TextToSpeech.QUEUE_FLUSH, null);
}
}
#Override
public void onFailure(Call<Translation> call, Throwable t) {
call.cancel();
progress.hide();
Toast.makeText(getApplicationContext(), "Error: " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
public static File savebitmap(Bitmap bmp, String fName) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 60, bytes);
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + fName);
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
return f;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectedLanguage = (Language) spinner.getSelectedItem();
// langCode = languages.get(position);
tts.setLanguage(Locale.forLanguageTag(selectedLanguage.langCode));
Prefs.putString("langCode", selectedLanguage.langCode);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
activity_main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBlack"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"
tools:context="thingtranslator2.jalle.com.thingtranslator2.MainActivity">
<LinearLayout
android:id="#+id/layout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="1">
<Spinner
android:id="#+id/spinner"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_marginBottom="16dp"
android:layout_weight="0.91"
android:gravity="bottom|end" />
<ImageButton
android:id="#+id/imgSpeaker"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="end"
android:layout_weight=".10"
android:background="#android:color/transparent"
android:onClick="ToogleSpeaker"
android:scaleType="fitCenter"
app:srcCompat="#drawable/ic_volume"
android:contentDescription="#string/todo" />
</LinearLayout>
<TextView
android:id="#+id/txtTranslation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/layout1"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:gravity="center_horizontal"
android:onClick="getImage"
android:text="#string/select_image_from_n_gallery_or_take_new_photo"
android:textColor="#android:color/white"
android:textSize="26sp"
tools:text="message" />
<ImageButton
android:id="#+id/imgPhoto"
android:layout_width="fill_parent"
android:layout_height="400dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_below="#id/txtTranslation"
android:background="#drawable/takephoto"
android:onClick="getImage" />
</RelativeLayout>
AndroidMnifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="thingtranslator2.jalle.com.thingtranslator2">
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<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:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I just started android programming a couple of days ago. I'm trying to integrate google plus login into my App. I followed the tutorial here. When I tried to deploy my app, I get an error message saying -
Unfortunately OAuthTest has stopped.
The logcat shows the following error:
10-10 10:31:37.239 32048-32048/agility.oauthtest D/dalvikvm﹕ Late-enabling CheckJNI
10-10 10:31:37.622 32048-32048/agility.oauthtest D/AndroidRuntime﹕ Shutting down VM
10-10 10:31:37.622 32048-32048/agility.oauthtest W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x416a8d40)
10-10 10:31:37.627 32048-32048/agility.oauthtest E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: agility.oauthtest, PID: 32048
java.lang.RuntimeException: Unable to start activity ComponentInfo{agility.oauthtest/agility.oauthtest.login}: java.lang.NullPointerException: Null options are not permitted for this Api
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2198)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException: Null options are not permitted for this Api
at com.google.android.gms.internal.fq.b(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.addApi(Unknown Source)
at agility.oauthtest.login.onCreate(login.java:83)
at android.app.Activity.performCreate(Activity.java:5248)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
My code is as follows
Activity_login.xml
<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"
android:padding="16dp"
tools:context=".login" >
<LinearLayout
android:id="#+id/llProfile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal"
android:weightSum="3"
android:visibility="gone">
<ImageView
android:id="#+id/imgProfilePic"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="2" >
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="20dp" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18dp" />
</LinearLayout>
</LinearLayout>
<com.google.android.gms.common.SignInButton
android:id="#+id/btn_sign_in"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"/>
<Button
android:id="#+id/btn_sign_out"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_logout_from_google"
android:visibility="gone"
android:layout_marginBottom="10dp"/>
<Button
android:id="#+id/btn_revoke_access"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_revoke_access"
android:visibility="gone" />
</LinearLayout>
login.java
package agility.oauthtest;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
import java.io.InputStream;
public class login extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
// Logcat tag
private static final String TAG = "Login";
// Profile pic image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
/**
* A flag indicating that a PendingIntent is in progress and prevents us
* from starting further intents.
*/
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout llProfileLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
// Button click listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
getProfileInformation();
// Update the UI after signin
updateUI(true);
}
/**
* Updating the UI, showing/hiding buttons and profile layout
* */
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
}
}
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.login, menu);
return true;
}
/**
* Button on click listener
* */
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
// Signin button clicked
signInWithGplus();
break;
case R.id.btn_sign_out:
// Signout button clicked
signOutFromGplus();
break;
case R.id.btn_revoke_access:
// Revoke access button clicked
revokeGplusAccess();
break;
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Sign-out from google
* */
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
/**
* Revoking access from google
* */
private void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status arg0) {
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
/**
* Background Async task to load user profile picture from url
* */
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="agility.oauthtest" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".login"
android:label="#string/app_name" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
What I already did -
Cleaned the Application. Rebuilt it.
What I am still confused about.
I created the Client ID in Google API Console, but I've never used it anywhere in the code. And the tutorial seems to be working for many other people.
If anyone could help me here, it would be awesome. Thanks.
pass a single parameter in addApi as .addApi(Plus.API),i.e.
Change
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
to
mGoogleApiClient = new GoogleApiClient.Builder(this,this,this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
as your Logcat shows java.lang.NullPointerException: Null options are not permitted for this Api
hence try this code:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
Ive only been programming a few days, so I am struggling to grasp what I am doing wrong here, hoping the community can point me in the right direction..
Here my MainActivity:
package com.whatsonwhere.app;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
public class MainActivity extends ActionBarActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener{
private SupportMapFragment mapFragment;
private GoogleMap map;
private LocationClient mLocationClient;
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
// Define a DialogFragment that displays the error dialog
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
// Default constructor. Sets the dialog field to null
public ErrorDialogFragment() {
super();
mDialog = null;
}
// Set the dialog to display
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
// Return a Dialog to the DialogFragment.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationClient = new LocationClient(this, this, this);
mapFragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapView));
map = mapFragment.getMap();
map.setMyLocationEnabled(true);
}
/*
* Called when the Activity becomes visible.
*/
#Override
protected void onStart() {
super.onStart();
// Connect the client.
if(isGooglePlayServicesAvailable()){
mLocationClient.connect();
}
}
/*
* Called when the Activity is no longer visible.
*/
#Override
protected void onStop() {
// Disconnecting the client invalidates it.
mLocationClient.disconnect();
super.onStop();
}
/*
* Handle results returned to the FragmentActivity
* by Google Play services
*/
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST:
/*
* If the result code is Activity.RESULT_OK, try
* to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK:
mLocationClient.connect();
break;
}
}
}
private boolean isGooglePlayServicesAvailable() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Location Updates", "Google Play services is available.");
return true;
} else {
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog( resultCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
errorFragment.show(getSupportFragmentManager(), "Location Updates");
}
return false;
}
}
/*
* Called by Location Services when the request to connect the
* client finishes successfully. At this point, you can
* request the current location or start periodic updates
*/
#Override
public void onConnected(Bundle dataBundle) {
// Display the connection status
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
Location location = mLocationClient.getLastLocation();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17);
map.animateCamera(cameraUpdate);
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
#Override
public void onDisconnected() {
// Display the connection status
Toast.makeText(this, "Disconnected. Please re-connect.",
Toast.LENGTH_SHORT).show();
}
/*
* Called by Location Services if the attempt to
* Location Services fails.
*/
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), "Sorry. Location services not available to you", Toast.LENGTH_LONG).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
and my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.whatsonwhere.app" >
<permission
android:name="com.whatsonwhere.app.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.whatsonwhere.app.MAPS_RECEIVE"/>
<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="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.whatsonwhere.app.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.google.android.gms.version" android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="mykey_here(removed)" />
</application>
</manifest>
Activity_main:
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.whatsonwhere.app.MainActivity">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_below="#+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/TopText"
android:id="#+id/textView2"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/nearme"
android:id="#+id/button"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/search"
android:id="#+id/button2"
android:layout_below="#+id/button"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/loc"
android:id="#+id/textView"
android:layout_below="#+id/textView2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
And finally the logcat:
03-25 11:28:19.417 6650-6650/com.whatsonwhere.app D/AndroidRuntime﹕ Shutting down VM
03-25 11:28:19.417 6650-6650/com.whatsonwhere.app W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x415e88b0)
03-25 11:28:19.417 6650-6650/com.whatsonwhere.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.whatsonwhere.app/com.whatsonwhere.app.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2266)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
at android.app.ActivityThread.access$600(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5225)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.whatsonwhere.app.MainActivity.onCreate(MainActivity.java:71)
at android.app.Activity.performCreate(Activity.java:5133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
at android.app.ActivityThread.access$600(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5225)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
03-25 11:28:19.537 6650-6682/com.whatsonwhere.app W/ActivityThread﹕ ClassLoader.loadClass: The class loader returned by Thread.getContextClassLoader() may fail for processes that host multiple applications. You should explicitly specify a context class loader. For example: Thread.setContextClassLoader(getClass().getClassLoader());
03-25 11:28:21.477 6650-6650/com.whatsonwhere.app I/Process﹕ Sending signal. PID: 6650 SIG: 9
When you specify:
setContentView(R.layout.activity_main);
And
mapFragment =((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.mapView));
map = mapFragment.getMap();
The compiler looks for R.id.mapView in R.layout.activity_main .The names are case sensitive.
The line:
map=mapFragment.getMap():
throws a NPE as the mapView isn't found in its respective layout. Check the names if id(s) and whether it is declared in the mentioned layout.
Also, alternatively..you can use:
map = ((SupportMapFragment) this.getSupportFragmentManager()
.findFragmentById(R.id.mapView)).getMap();
saves a variable declaration and l-o-c, if not necessary otherwise.
Add fragment like this:
<fragment
android:id="#+id/mapView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/button"
class="com.google.android.gms.maps.SupportMapFragment" />
Sometimes, when the activity is created, the map is not initialised. This leads to NullPointerException.
You must move the code mapFragment etc from onCreate to onResume.
This will ensure that the activity is created and in foreground.
mapFragment is null after the findFragmentById() call. Please make sure you have id = mapView (case-sensitive) inside activity_main.xml. If you have it there, you can also try to move the work with MapFragment from onCreate to onStart or onResume
Change here from
mapFragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapView));
to
mapFragment = ((MapFragment) getSupportFragmentManager().findFragmentById(R.id.mapView));
Because in your xml file you are using
android:name="com.google.android.gms.maps.MapFragment"