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();
Related
I am using Android Studio 2.2 and I'm trying to see if a web service is up when pressing a button, but I receive the following error. I'm a beginner so any advice is helpful.
Thank you very much.
This is the code in android studio. I found something on the internet but I'm not sure what every line is doing.
package com.example.roxanapena.myapp6;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.HttpCookie;
import static java.net.Proxy.Type.HTTP;
public class MainActivity extends AppCompatActivity {
public boolean available() throws IOException {
URL url = new URL("https://www.Google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("OK");
return true;
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
System.out.println("WRONG");
return false;
// Server returned HTTP error code.
}
}
Button button3;
public void buttonClicked(View view) throws IOException {
button3 = (Button) findViewById(R.id.button3);
EditText mytextField = (EditText) findViewById(R.id.mytextField);
Log.i("Ok", String.valueOf(available()));
}
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
This is a part of the error I receive when i am pressing the button in app :
03-01 12:13:08.977 28514-28514/com.example.roxanapena.myapp6 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.roxanapena.myapp6, PID: 28514
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
Later Edit: This is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/GreenRed"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.roxanapena.myapp6.MainActivity">
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="buttonClicked"
android:text="Button"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="135dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_constraintRight_creator="1"
tools:layout_constraintLeft_creator="1" />
<EditText
android:id="#+id/mytextField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="142dp"
android:layout_marginTop="143dp"
android:ems="10"
android:hint="Name"
android:inputType="textPersonName"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button3"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#mipmap/ic_launcher"
android:layout_marginBottom="43dp"
app:layout_constraintBottom_toTopOf="#+id/button3"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="44dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1" />
</android.support.constraint.ConstraintLayout>
When doing a Network Call in android first check in your application Manifest if Internet Permission is given to your application.
If not first provide permission in your application Manifest file like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.truckit">
<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/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
</application>
Then to do a handshaking request with a server use an AsyncTask. Never do Network Calls on main thread because it will block your main thread and application will freeze until your application receives a response from the server. Use a simple AsyncTask like this:
public class HandShakingTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
System.out.println(connection.getResponseMessage());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("OK");
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
System.out.println("WRONG");
// Server returned HTTP error code.
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Then call it in your button click method.
new HandShakingTask().execute("https://www.google.com");
Then it will be fine
Result:
2019-03-02 00:52:55.618 5575-5597/com.truckit I/System.out: OK
Here is a sample how to call via AsyncTask.
This code contains also code to pass data to server in JSON (if needed).
Also take care about a possible redirection to another URL, as described in my code
handShakeResponse = new DownloadAsyncTask().execute(request).get();
DownloadAsyncTask declaration:
private class DownloadAsyncTask extends AsyncTask<JSONObject, Void, String> {
#Override
protected String doInBackground(JSONObject... params) {
JSONObject response = null;
JSONObject request = params[0];
if (request != null) {
URL new_url;
String server_response = null;
HttpURLConnection urlConnection = null;
try {
new_url = new URL(HANDSHAKE_SERVER);
urlConnection = (HttpURLConnection) new_url.openConnection();
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setRequestMethod("POST");
urlConnection.setInstanceFollowRedirects(true);
urlConnection.setDoOutput(true);
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "utf-8"));
writer.write(request.toString());
writer.flush();
writer.close();
os.close();
int response_code = urlConnection.getResponseCode();
if(response_code == HttpURLConnection.HTTP_OK) {
server_response = readStream(new BufferedInputStream(urlConnection.getInputStream()));
} else {
Log.e(getClass().getSimpleName(), "response code:" + String.valueOf(response_code));
if (response_code == HttpURLConnection.HTTP_MOVED_PERM || response_code == HttpURLConnection.HTTP_MOVED_TEMP) {
String server = urlConnection.getHeaderField("Location");
if (server == null || server.isEmpty()) {
Log.e(TAG, "Redirect not found!");
} else {
Log.e(TAG, "Redirecting to: " + server);
//You must handle here the redirection
return "redirect"; //this is just a flag for me, do your own handling
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return server_response;
}
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onCancelled() {
// Cancel task
}
#Override
protected void onPreExecute() {}
}
Initialise button in onCreate
public class MainActivity extends AppCompatActivity {
public boolean available() throws IOException {
URL url = new URL("http://www.Google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("OK");
return true;
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
System.out.println("WRONG");
return false;
// Server returned HTTP error code.
}
}
Button button3;
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button3 = (Button) findViewById(R.id.button3);
EditText mytextField = (EditText) findViewById(R.id.mytextField);
}
public void buttonClicked(View view) throws IOException{
Log.i("Ok", String.valueOf(available()));
}
}
Either use android:onClick="buttonClicked" in you xml for button
or set OnClicklistener on you button
button3.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
buttonClicked()
}
});
public void buttonClicked() {
Log.i("Ok", String.valueOf(available()));
}
Make network call on background thread
You can use AsynTask check this link for network guide
https://developer.android.com/training/basics/network-ops/connecting
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 trying to build an audio recorder in the android studio. I followed this tutorial:
https://www.youtube.com/watch?v=XANjoeEeQ1Y
Which did not work for me? When I pushed the "record" button, nothing happened.
Therefrom I added action listeners with onClick() methods and such. Still didn't work. Then I added a text view to show me the status for debugging purpose.
After adding the status textView I found out that the beginRecording() method goes straight to the catch statement.
I watched another youtube video
https://www.youtube.com/watch?v=lWaypoRVfSc
which seems to do more or less the same thing regarding the MediaRecorder.
So.. My question is. What have I done wrong? How can I make it actually record when the RECORD button is pushed?
Thank you in advance.
Here comes my code:
package com.example.natalie.recorder;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPLayer;
private MediaRecorder recorder;
private String OUTPUT_FILE;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Button startR = (Button) findViewById(R.id.startBtn);
Button stopR = (Button) findViewById(R.id.finishBtn);
Button playRecording = (Button) findViewById(R.id.playBtn);
Button stopPlaying = (Button) findViewById(R.id.stopBtn);
final TextView statusTV;
statusTV = (TextView) findViewById(R.id.statusTextView);
OUTPUT_FILE= Environment.getExternalStorageDirectory().getAbsolutePath()+"/audiorecorder.3gpp";
/*------START BUTTON------*/
startR.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
final TextView stv=statusTV;
try {
beginRecording();
stv.setText("Recording");
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
stv.setText("Error");
}
}
});
/*------STOP BUTTON------*/
stopR.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
final TextView stv=statusTV;
try {
stopRecording();
stv.setText("Stopped");
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
statusTV.setText("Error");
Log.d("here","dd",e);
}
}
});
playRecording.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
try {
playRecording();
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
statusTV.setText("Error");
}
}
});
stopPlaying.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
try {
stopPlayback();
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
statusTV.setText("Error");
}
}
});
}
private void stopPlayback() throws Exception{
if(mediaPLayer != null)
mediaPLayer.stop();
}
private void playRecording() throws IOException {
ditchMediaPLayer();
mediaPLayer = new MediaPlayer();
mediaPLayer.setDataSource(OUTPUT_FILE);
mediaPLayer.prepare();
mediaPLayer.start();
}
private void ditchMediaPLayer() {
if (mediaPLayer != null) {
try{
mediaPLayer.release();
} catch(Exception e) {
e.printStackTrace();
}
}
}
private void stopRecording() {
if(recorder != null)
recorder.stop();
}
private void beginRecording() throws Exception{
ditchMediaRecorder();
File outFile = new File(OUTPUT_FILE);
if (outFile.exists()) {
outFile.delete();
}
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
record.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(OUTPUT_FILE);
recorder.prepare();
recorder.start();
}
private void ditchMediaRecorder() {
if(recorder != null)
recorder.release();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
The AndroidManifest look like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.natalie.recorder">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.RECORD_AUDIO"
/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
The content_main.xml comes here:
<Button
android:id="#+id/stopBtn"
android:layout_width="249dp"
android:layout_height="56dp"
android:background="#color/colorAccent"
android:text="Stop PLayback"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/playBtn" />
<Button
android:id="#+id/playBtn"
android:layout_width="249dp"
android:layout_height="48dp"
android:background="#color/colorAccent"
android:text="Play Recording"
app:layout_constraintBottom_toTopOf="#+id/stopBtn"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/finishBtn" />
<Button
android:id="#+id/finishBtn"
android:layout_width="249dp"
android:layout_height="48dp"
android:background="#color/colorAccent"
android:text="Finish Recording"
app:layout_constraintBottom_toTopOf="#+id/playBtn"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/startBtn" />
<Button
android:id="#+id/startBtn"
android:layout_width="247dp"
android:layout_height="48dp"
android:background="#color/colorAccent"
android:text="Start Recording"
app:layout_constraintBottom_toTopOf="#+id/finishBtn"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/statusTextView"
android:layout_width="246dp"
android:layout_height="22dp"
android:text="Status"
android:textAlignment="center"
android:textSize="24sp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toTopOf="#+id/startBtn"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
You asked for CAMERA, WRITE_STORAGE and RECORD_AUDIO permission but you don't asked for at your activity. take a look at this.
use:
ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) to check the status of the permission and compare it with PackageManager.PERMISSION_GRANTED which mean that your permission is accepted like this :
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
and inside the onRequestPermissionsResult do something like this :
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//do work
}
}
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.
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"