I am trying to get the gmail inbox using javamail with this code:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import java.util.Properties;
public class HomeActivity extends Activity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button emailRead=(Button)findViewById(R.id.button);
emailRead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Runnable r=new Runnable() {
#Override
public void run() {
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(props, null);
IMAPStore imapStore = null;
try {
imapStore = (IMAPStore) session.getStore("imaps");
imapStore.connect("imap.gmail.com", "myemail#gmail.com", "mypassword");
final IMAPFolder folder = (IMAPFolder) imapStore.getFolder("Inbox");
folder.open(IMAPFolder.READ_WRITE);
Message m[]=folder.getMessages();
for(Message n:m){
System.out.println(n.getSubject());
}
} catch (MessagingException e) {
e.printStackTrace();
}
}
};
Thread t=new Thread(r);
t.start();
}
});
}
}
It works in emulator, but when run on a real device(with working internet connection) I constantly fail and get the exception:
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: imap.gmail.com, 993; timeout -1;
nested exception is:
java.net.SocketTimeoutException: failed to connect to imap.gmail.com/2607:f8b0:400e:c02::6c (port 993) after 90000ms
Why am I receiving an MailConnectException, and how can I fix it?
EDIT:
Here are the links I have tried, but with the same result:
1)Reading Gmail mails using android SDK
2)Are there any good short code examples that simply read a new gmail message?
3)Reading all new messages from my gmail using javamail
Its just the subset of what I have tried before posting. I request someone to please share a live working code, which works on a real device here.
EDIT2:
I have tested this on three real devices. One was using wifi internet.Two others were using Gprs for net connectivity. So it appears that gmail setting for javamail have changed with android. The javamail code is working for me on desktop java.But seems something strange with android real devices.
U are not allowed to use networking in main UI thread from android 3.0 and up.
So setup aSyncTask to solve your problem
Related
This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 1 year ago.
I am new to android dev
I have made as simple app in android (for api_version greater than 23) which fetches the name of all running apps. But the app doesn't work properly. When I click the button the functionality registered in "onClickListner" is not working.
package com.sakthi.appban;
import androidx.appcompat.app.AppCompatActivity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.List;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
displayAllApps();
}
});
}
private void displayAllApps(){
PackageManager pm = getPackageManager();
List<ApplicationInfo> installedApplications = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for(ApplicationInfo application : installedApplications){
Toast.makeText(this, application.name, Toast.LENGTH_SHORT).show();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Toast.makeText(this, "Task Ended", Toast.LENGTH_SHORT).show();
}
Hope I will get help
Thanks in advance
I think you might have seen these message in logs if you run this code you will get this error when you click on the button
Error:
java.lang.IllegalStateException: You must either set a text or a view
Here application.name may get null for some of the apps. This may cause IllegalStateException because you are passing null to a Toast.
To fix this simply add an if condition to null check like this:
if(application.name != null) {
Toast.makeText(this, application.name, Toast.LENGTH_SHORT).show();
}
Then it should work.
Update:
You can remove this code from your code which causing ANR:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
The problem is that I am trying to loop in the UI thread.
So the UI thread cannot handle the UI operation..
and my program crashed.More info here
I'm using socket-io on android .
('com.github.nkzawa:socket.io-client:0.3.0')
While testing my app on Nexus 10 device (Android 4.2.1) i discovered that after calling mSocket.connect() a libcore.net.http.HttpConnection Object is created every 12.7 seconds or so by libcore.net.http.HttpConnectionPool. that causes "Too many open files error" and eventually the app freezes or crash .
Does not happen on (Android 4.4.2) Samsung GS5 device
It doesn't happens if i connect to a non SSL server (http vs https)
I'm connecting to a self signed certificate server - not sure if it's related to the leak .
calling socket disconnect does not free the HttpConnection objects
while investigating the leak i created an empty android project that reproduce the leak. Below i attached only the code that was added on top an empty "hello world" project.
note that on my original app - the connection to the server is successful.
onError callbacks are placed but not called. On the server side only one connection is made .Emitting and receiving Msgs is successful . Only when the HttpConnection Object count reaches to 300 or so, "too many open files" error occurs and causes various problems.
the fact that it happens only on some android versions,only on SSL connections, and that connect causes the leak but disconnect does not free it, really puzzles me.
-code
Added to build.gradle dependencies
compile 'com.github.nkzawa:socket.io-client:0.3.0'
Added to Android Manifest
<uses-permission android:name="android.permission.INTERNET" />
Main Activity....
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.....
mSocket.connect();
}
private TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
private Socket mSocket;
{
try
{
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, null);
IO.setDefaultSSLContext(sc);
HttpsURLConnection.setDefaultHostnameVerifier(new RelaxedHostNameVerifier());
mSocket = IO.socket("https://10.0.0.1");
mSocket.connect() ;
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
catch (URISyntaxException e) {
e.printStackTrace();
}
}
public static class RelaxedHostNameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
OK . got it .
The every 12.7 sec connection leak was the ping . changing the ping interval on my server helped a little.
but it turns out that httpConnection was leaked on every Msg sent to the server.
so basically it was not a solution.
After a little bit of digging i found this online.
http://android-developers.blogspot.co.il/2011/09/androids-http-clients.html
To summarize.
"Prior to Froyo, HttpURLConnection had some frustrating bugs. In particular, calling close() on a readable InputStream could poison the connection pool. Work around this by disabling connection pooling:"
private void disableConnectionReuseIfNecessary() {
// HTTP connection reuse which was buggy pre-froyo
if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
System.setProperty("http.keepAlive", "false");
}
}
As stated i'm suffering from this leak on Jelly bean not froyo. I removed the condition.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.setProperty("http.keepAlive", "false") ;
...
}
I'm trying to take control over the Play/Pause html DOM elements (in a browser open in a pc) from an android device.
In the html page (in Google Chrome browser) there's a <video> tag so I can control it like this:
//js code
document.querySelector("video").play();
document.querySelector("video").pause();
But I want that to run from an android device so I'm using GCM.
I read here and got some insight but I still have some questions.
First, since I'm writing in eclipse, and it sees no document variable, it produces an error. So how can eclipse recognize that element in the html page so I can compile and install the apk on the device?
Where do I specify the page url I want to communicate with? (send play/pause commands)
To run js inside java I'm using Rhino. I looked through the examples in the documentation but I'm still not sure if a #JSFunction annotation is enough to declare a js function.
Here's my code:
import com.alaa.chromote.util.SystemUiHider;
import com.google.android.gcm.GCMRegistrar;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import android.view.View.OnClickListener;
import org.mozilla.javascript.*;
import org.mozilla.javascript.annotations.*;
public class MainApplication extends Activity {
private final static String GCM_SENDER_ID = "484514826047";
private static final String LOG_TAG = "GetAClue::GCMIntentService";
private Button playButton;
private Button pauseButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_application);
playButton = (Button) findViewById(R.id.PlayButton);
pauseButton = (Button) findViewById(R.id.PauseButton);
playButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.VISIBLE);
//connect to gcm
GCMRegistrar.checkDevice( this );
GCMRegistrar.checkManifest( this );
final String regId = GCMRegistrar.getRegistrationId( this );
if( regId.equals( "" ) ) {
GCMRegistrar.register( this, GCM_SENDER_ID );
}
else {
Log.v( LOG_TAG, "Already registered" );
}
Context.enter(); //start Rhino
setupListeners();
}
#JSFunction
public void play() { document.querySelector("video").play(); }
#JSFunction
public void pause() { document.querySelector("video").pause(); }
private void setupListeners()
{
playButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
play();
}
});
pauseButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
pause();
}
});
}
#Override
protected void onStop() {
Context.exit(); //stop Rhino
super.onStop();
}
}
How do I continue from here?
First, since I'm writing in eclipse, and it sees no document variable, it produces an error. So how can eclipse recognize that element in the html page so I can compile and install the apk on the device?
answ: On your android device you just pass a message to the chrome browser. A.k. an action variable that is set to play or stop. You chrome app will then pick up the message and act accordingly. Also you can send the url as an variable in the message if you want to be able to play different urls.
Where do I specify the page url I want to communicate with? (send play/pause commands)?
answ: Do you already created the chrome app you want and verified it works? It should check with a google cloud server for messages. That server keeps track of the url for you.
To run js inside java I'm using Rhino. I looked through the examples in the documentation but I'm still not sure if a #JSFunction annotation is enough to declare a js function.?
answ: It seems you are misunderstanding the part what the android app does (sending the play action) and what the chrome browser does (actually playing the movie)
I hope my answer has helped a little, feedback is appreciated :)
I have currently been testing some examples being found on the internet on sending NDEF messages through the NFC on my android phone.
I have three phones that I tested the phone with: Samsung Galaxy Nexus (Android 4.4.4), S3 (Android 4.4.2) and S4 (Android 4.4.4).
The app works perfect the way I wanted it to on the GN (it sends the message), however on the S3 and the S4 it sends the package name of the app instead of the message.
Can anybody help me with this? Does anyone know why or how to fix this? I am pretty new to Android dev and don't fully understand why it is doing this.
Code:
package tapit.cbstech.com.tap_it_3;
import android.app.Activity;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
public class main extends Activity implements CreateNdefMessageCallback {
NfcAdapter mNfcAdapter;
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
mNfcAdapter.setNdefPushMessageCallback(this, this);
}
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
String text = ("abcdefghi");
NdefMessage msg = new NdefMessage(
new NdefRecord[] { NdefRecord.createMime("text/plain", text.getBytes()),
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//NdefRecord.createApplicationRecord("hello test")
});
return msg;
}
#Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = (NdefMessage) rawMsgs[0];
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
On the GNexus I get the "abcdefghi" but on the S3 and S4 I get "tapit.cbstech.com.tap_it_3"
Any help is appreciated! Thanks in advance!
Edit: Tested on a friends S3 and does the same (sending the package name) and tested on another friends nexus 5 (running Android L) and it worked sending the "abcdefghi" message.
I'm trying to record sound using Android Emulator. I know that this question is popular over the internet, I checked many posts, it seems that only one person succeded: Can the Android emulator record and play back audio using pc hardware?. (it think he used
File fTmFile; insteadof String fTmpFile;
which i also tried). And following Philip's advice and the official site tutorial http://developer.android.com/guide/topics/media/audio-capture.html and also other resources, I'm still not able to record. My application throws exception at line:
fMediaRecorder.prepare();
more exactley, this is what I first get:
W/System.err(1042): java.io.FileNotFoundException: /mnt/sdcard/audiorecordtest.3gp (Permission denied)
which makes me think is something wrong with the storage location, because even I added 'SD Card Support' property for the emulator with size 256 MiB, I'm not able to acces it, furthermore I can see in the emulator the message: "Your phone does not have a SD Card inserted" when I go to Music.
I added both audio record and external storage permissions, in AndroidManifest.xml and both audio (record+playback) hardware settings to the emulator 2.3.3 on Win 7. Is anything wrong within my app, the way I storage the file or something else? Please, if anybody has any idea feel free to share, it will be appreciated.
Here is the full source code:
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class RecordSoundActivity extends Activity {
private MediaRecorder fMediaRecorder = null;
private Button btnrecord;
private Button btnstop;
String fTmpFile;
public RecordSoundActivity() {
fTmpFile = Environment.getExternalStorageDirectory().getPath();
fTmpFile += "/audiorecordtest.3gp";
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnrecord = (Button) findViewById(R.id.button1);
btnstop = (Button) findViewById(R.id.button2);
btnrecord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(RecordSoundActivity.this, "Recording...", Toast.LENGTH_LONG).show();
Recording();
}
});
btnstop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
fMediaRecorder.stop();
fMediaRecorder.release();
}
});
}
public void Recording() {
fMediaRecorder = new MediaRecorder();
fMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
fMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
fMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
fMediaRecorder.setAudioChannels(1);
fMediaRecorder.setAudioSamplingRate(8000);
fMediaRecorder.setOutputFile(fTmpFile);
try {
fMediaRecorder.prepare();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
try {
fMediaRecorder.start();
} catch (IllegalStateException e) {
// TODO: handle exception
e.printStackTrace();
}
//fMediaRecorder.stop();
//fMediaRecorder.release();
}
}
Try and see if it works for Android 4.0. I know I had some issues with the camera in the emulator, in lower version (Lower than 4.0) it just wouldn't recognize my laptop webcam. But when I tried it on 4.0, when the AVD was loading a popup message came and asked me if I want to connect the webcam to the AVD, and once I agreed it worked.
Another poster in SO asked this question too, about the camera, and changing the AVD version to 4.0 did help him.
Maybe its the same for audio recording too, as both are external hardware for the typical PC.