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
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 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
}
}
Im building a graduation project for my collage about "Smart Homes, Home Automation System" implemented with Arduion on a mock-up structure.
To have the full image, the Arduaio takes the pin number via a get request to switch on or of a specific home device.
its all cool when i send the HTTP request from any browser, but when i use the
openConnection();
method, it's like something never happens, but when i use it to get some data about the home rooms and its devices it's working greatly.
i already gave the app the permission to access the internet.
the code from a simple project i made just to solve this praticualy problem:
MainActivity.java
package com.bitsandbytes.xemma_pc.newprototype;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new SendRequest().execute();
}
});
}
private static class SendRequest extends AsyncTask <Void,Void,Void>{
#Override
protected Void doInBackground(Void... params) {
HttpURLConnection httpURLConnection = null ;
URL url ;
try {
url = new URL("http://192.168.1.143/pin=13");
httpURLConnection = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
httpURLConnection.disconnect();
}
return null;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.bitsandbytes.xemma_pc.newprototype.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Press it to Test it"
android:id="#+id/textView"
android:layout_marginTop="154dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pin 13"
android:id="#+id/button"
android:layout_below="#+id/textView"
android:layout_centerHorizontal="true" />
</RelativeLayout>
AndroidManifist.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bitsandbytes.xemma_pc.newprototype">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
i appreciate the help and the tips in advance.
EDIT: thanks you guys for helping me, but what it really helped me was using the getResponseMessage() method, and it works greatly :D
i didn't have to use .connect method to get some JSON strings before, but it was working.
anyway, thanks for the help!
openConnection just parses the URL and creates the appropriate URLConnection subclass. Network I/O doesn't happen until you send or receive something.
You need to read the data and then network IO will occur.
String response = "";
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Set Method here
conn.setRequestMethod("POST");
InputStreamReader in = new InputStreamReader(conn.getInputStream());
BufferedReader br = new BufferedReader(in);
String line= "";
while ((line= br.readLine()) != null) {
response += line;
}
conn.disconnect();
URL.openConnection() only returns a URLConnection to the specified resource.
You can open an actual connection to that resource by calling the connect() method of that particular URLConnection.
For example:
HttpURLConnection connection = (HttpURLConnection) someUrl.openConnection();
connection.connect();
Operations that require a connection (like getInputStream() or getOutputStream()) will implicitly call connect(), so explicitly calling it before such operations is not necessary:
HttpURLConnection connection = (HttpURLConnection) someUrl.openConnection();
connection.connect(); // this is redundant
connection.getInputStream(); // getInputStream() will call connect()
I'm trying to create a simple android app in which I'm trying to connect my app to a webserver where I have a database named akshaynsit1_pathaniswaad and in that database I have a table named table1. In this table I have 3 columns id(int auto increment primary key),name(varchar(30)),addr varchar(30).I'm creating a simple signup page where user will add his name and address and this name and address will get saved to my webserver through post method.
My MainActivity.java is as follows
package com.example.akshay007.sample;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
EditText ed1,ed2;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ed1=(EditText)findViewById(R.id.editText);
ed2=(EditText)findViewById(R.id.editText2);
tv=(TextView)findViewById(R.id.textView2);
}
public void insert(View view){
String name = ed1.getText().toString();
String add = ed2.getText().toString();
insertToDatabase(name,add);
}
private void insertToDatabase(String name, String add){
class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String paramUsername = params[0];
String paramAddress = params[1];
try{
String name = paramUsername;
String address = paramAddress;
String link="http://http://pathaniswaad.com/android_akshay/post.php";
String data = URLEncoder.encode("name", "UTF-8") + "=" + URLEncoder.encode(name, "UTF-8");
data += "&" + URLEncoder.encode("address", "UTF-8") + "=" + URLEncoder.encode(address, "UTF-8");
URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
sb.append(line);
break;
}
return sb.toString();
}
catch(Exception e){
return new String("Exception: " + e.getMessage());
}
//return "success";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), "yo bro", Toast.LENGTH_LONG).show();
//TextView textViewResult = (TextView) findViewById(R.id.textViewResult);
//textViewResult.setText("Inserted");
//tv.setText("ya brah..");
}
}
SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
sendPostReqAsyncTask.execute(name, add);
}
#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);
}
}
activity_main.xml is as follows
<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=".MainActivity">
<EditText
android:layout_width="300dp"
android:layout_height="wrap_content"
android:id="#+id/editText"
android:layout_alignParentTop="true"
android:hint="name"
android:layout_centerHorizontal="true"
android:layout_marginTop="121dp" />
<EditText
android:layout_width="300dp"
android:layout_height="wrap_content"
android:id="#+id/editText2"
android:hint="address"
android:layout_below="#+id/editText"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Signup"
android:id="#+id/button"
android:layout_below="#+id/editText2"
android:layout_centerHorizontal="true"
android:layout_marginTop="56dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Merchant Signup"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="44dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/textView2"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Androidmanifest.xml is as follows
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.akshay007.sample" >
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
my post.php script is as follows
<?php
$con = mysqli_connect("65.50.265.181:336","jfjtyfyfhjfjdy","uitytityut67","akshaynsit1_pathaniswaad");
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
else
{
echo"connection successful <br>";
}
$name = $_POST['name'];
$address = $_POST['address'];
$result = mysqli_query($con,"insert into table1 (name,addr) values ('$name','$address')");
if(mysqli_query($con,$sql)){
echo 'success';
}
else{
echo 'failure';
}
mysqli_close($con);
?>
Please help any kind of help would be appreciated!!!!!!!!!!
TWO things NEED to be fixed:
your post url link looks incorrect:
http://http://pathaniswaad.com/android_akshay/post.php
"http://" is used twice. change it to:
http://pathaniswaad.com/android_akshay/post.php
you have forgotten to append the params to url:
String data = URLEncoder.encode("name", "UTF-8") + "=" + URLEncoder.encode(name, "UTF-8");
data += "&" + URLEncoder.encode("address", "UTF-8") + "=" + URLEncoder.encode(address, "UTF-8");
link += "?"+data; //add this line here
URL url = new URL(link);
Fix these 2 and try again. You should also test you PHP by using a fabricated url directly into your browser. that way it will make sure that there is no issue in the PHP itself.
good luck.
If you do not already have this in your manifest file, add it before the <application> section:
<uses-permission android:name="android.permission.INTERNET" />
Also, I have noticed that your link, in the code, is
http://http://pathaniswaad.com/android_akshay/post.php
Try changing it to
http://pathaniswaad.com/android_akshay/post.php
As the other user has also pointed out, you need the params appended. There is a better way to do this using loopj HttpAsyncClient:
Add to your gradle build:
compile 'com.loopj.android:android-async-http:1.4.9'
Here is a class I created to use this with GitHub Jobs, you can modify it for your uses:
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
public class AsyncRestClient {
private static final String BASE_URL = "https://jobs.github.com/positions";
private static final String JSON_RESPONSE_APPEND = ".json";
private static final AsyncHttpClient client = new AsyncHttpClient();
public static void getPositions(RequestParams params, AsyncHttpResponseHandler responseHandler) {
get(JSON_RESPONSE_APPEND, params, responseHandler);
}
private static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
}
And here is a code snippet where I use this class:
RequestParams params = jobRequested.getRequestParams();
AsyncRestClient.getPositions(params, getPositionsResponseHandler);
You would need to write your own response handler. If you want to see all the code, I have this project on GitHub (it is in active development), and you can see how I wrote the response handlers and callbacks for the responses:
https://github.com/JenniferVanderputten/GitHubJobs
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();