android async task executing api's repeteadly - android-asynctask

I am using Android Async Task function to execute an api using urlconnection. this api in turn sends emails to selected users.Now the issue is I am getting spammed by these emails at first I thought of it as an server side issue or my script but I created a new api and used it on IOS version of my application and everything works fine.But when I execute it on android I start getting spams,so I think the Issue lies in my android programming.
public class submitparse extends AsyncTask<String ,String,String> {
String Url;
#Override
protected String doInBackground(String... params) {
URL phonelink;
HttpURLConnection urlConnection = null;
try {
phonelink = new URL(params[0]);
urlConnection = (HttpURLConnection) phonelink
.openConnection();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isw);
String line = "";
StringBuffer buffer = new StringBuffer();
while ((line = br.readLine()) != null) {
buffer.append(line);
}
String finalresult = buffer.toString();
return finalresult;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
urlConnection.disconnect();
} catch (Exception e) {
e.printStackTrace(); //If you want further info on failure...
}
}
return null;
}
I am using this command to call it..
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String link = "";
new submitparse().execute(link);
}
});
On getting result I start another activity,where link is a string containing url.

If you don't care, you can also use just a new Thread. That should fit your needs and works fine. As far as I read, you don't need to use an AsyncTask and therefore IMO a normal Thread would be better.
// Runnable uiThreadRunnable = new Runnable.....
Handler handler = new Handler(); // import android.os.Handler
Runnable runnable = new Runnable() {
public void run() {
// do your stuff
// use 'handler.post(uiThreadRunnable);' to if you NEED to run something on main thread
}
};
Thread thread = new Thread(runnable);
thread.start();

Related

Issue in managing Hibernate transactions

I am using a thread based approach to poll the status of a specific task on AWS. For this, I use a while loop to constantly check the status as shown in below code. The issue is that when the code switches from one Service to another, it runs into an error -
Could not obtain transaction-synchronised hibernate session
The function in the thread is as below:
Runnable task = new Runnable() {
#Override
public void run() {
Session session = null;
try {
session = sessionFactory.openSession();
RmlWorkspace rmlWorkspace = session.get(RmlWorkspace.class, id);
logger.info("Starting Status check for "+id);
if (rmlWorkspace.getCloudStack().getStatus() == RUNNING_STATUS.STARTING) {
while (rmlWorkspace.getCloudStack().getStatus() != RUNNING_STATUS.ON) {
logger.info("Checking Status for "+id);
rmlWorkspace = checkStatus(session, rmlWorkspace);
TimeUnit.SECONDS.sleep(5);
}
} else if (rmlWorkspace.getCloudStack().getStatus() == RUNNING_STATUS.STOPPING) {
while (rmlWorkspace.getCloudStack().getStatus() != RUNNING_STATUS.OFF) {
Transaction tx = session.beginTransaction();
rmlWorkspace = checkStatus(session, rmlWorkspace);
tx.commit();
TimeUnit.SECONDS.sleep(5);
}
}
session.close();
} catch (Exception e) {
logger.info(e.getMessage());
if (session != null)
session.close();
}
}
};
The checkStatus function tries to call a function inside another class with the annotation #Service. The code meets an error at the below code:
private AssumeRoleResult assumeRole() {
try {
BasicAWSCredentials credentials = new BasicAWSCredentials(configAttributeService.getAttribute("aws.iamkey"),
configAttributeService.getAttribute("aws.iampass"));
AWSSecurityTokenService client = AWSSecurityTokenServiceClientBuilder.standard()
.withRegion(Regions.US_WEST_2).withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
AssumeRoleRequest request = new AssumeRoleRequest()
.withRoleArn(configAttributeService.getAttribute("aws.assumerole"))
.withRoleSessionName(UUID.randomUUID().toString()).withDurationSeconds(900);
AssumeRoleResult assumeRoleResult = client.assumeRole(request);
return assumeRoleResult;
} catch (Exception e) {
throw e;
}
}
The class containing the above function has an annotation #Service("xxx")
Could someone explain the reason for this and how to get this working.

kryonet client, send message to server without open a new connection

I'm saying i'm not a programmer but a guy who has been learning to program with java for a while. I hope to find the solution to my problem here. I'm trying to program my home automation system and remote control and to do this, I chose to use Kryonet. My problem is that every time I send the data to the server, the client opens a new connection. It's been 3 weeks since googlo and I try to figure out how to do it but with no results.
Every help is seriously appreciated. This is my code. Thank you.
This code work in my home network.
Sorry for my english...
public class MainActivity extends AppCompatActivity {
Button button;
String IP = "";
EditText editText;
TextView textView;
EditText editText3;
public static String msg_response;
public static String msg_request;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new MyHandler();
button = (Button) findViewById(R.id.button);
editText = (EditText) findViewById(R.id.editText);
editText3 = (EditText) findViewById(R.id.editText3);
textView = (TextView) findViewById(R.id.textView);
int MY_PERMISSIONS_REQUEST_INTERNET = 1;
int MY_PERMISSIONS_REQUEST_ACCESS_NETWORK_STATE = 1;
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.INTERNET},
MY_PERMISSIONS_REQUEST_INTERNET);
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_NETWORK_STATE},
MY_PERMISSIONS_REQUEST_ACCESS_NETWORK_STATE);
int MY_PERMISSIONS_REQUEST_ACCESS_WIFY_STATE = 1;
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_WIFI_STATE},
MY_PERMISSIONS_REQUEST_ACCESS_WIFY_STATE);
textView.setText(msg_response);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
msg_request = valueOf(editText3.getText().toString());
} catch (Exception e) {
e.printStackTrace();
}
MyThread myThread = new MyThread(handler);
myThread.start();
}
});
}
private class MyHandler extends Handler {
#Override
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
if (bundle.containsKey("msg da server")) {
String msgin = bundle.getString("msg da server");
textView.setText(msgin);
}
}
}
class MyThread extends Thread {
private Handler handler;
public MyThread(Handler handler) {
this.handler = handler;
}
public void run() {
System.out.println("MyThread running");
Client client = new Client();
client.start();
Kryo kryoClient = client.getKryo();
kryoClient.register(SampleRequest.class);
kryoClient.register(SampleResponse.class);
try {
client.connect(5000, "192.168.0.101", 54555, 54666);
} catch (IOException e) {
e.printStackTrace();
}
client.addListener(new Listener() {
public void received(Connection connection, Object object) {
if (object instanceof SampleResponse) {
SampleResponse response = (SampleResponse) object;
System.out.println(response.text);
msg_response = response.text.toString();
invia_activity(msg_response);
}
}
});
SampleRequest request = new SampleRequest();
request.text = msg_request;
client.sendTCP(request);
}
private void invia_activity(String invia) {
Message msg = handler.obtainMessage();
Bundle b = new Bundle();
b.putString("msg da server", "" + invia);
msg.setData(b);
handler.sendMessage(msg);
}
}
}
I dont have an direct solution, but i have an tutorial for it. I used the same one. So there the connections keeps open, and you can send as many packets as you need. Its without audio, but the code works well. After that you can experiment with the code. It works fine for me. This is the tutorial
I hope i can help you with this.
EDIT:
Maybe you can make an
public static Connection conn;
and you could use that object again and again as your connection to the server.

TcpSocketClient- UnhandledException when I try read a response inside of a Task that not arrived yet

I'm using this library(https://github.com/rdavisau/sockets-for-pcl) to communicate with a TCP Server, that sends me when a event was generated, then, I have to verify all the time if the TCP Server sent to me a event, but if I try read anything before the TCP Server sends me, it's thrown the UnhandledException, but it only happens if I read inside a Task, in the main thread it thrown a timeout exception, the exception that I expected to happen in Task.
Someone can help me? Thanks. below is my code.
public class CentralTcpService
{
#region ConnectTcpAsync
public async void ConnectTcpAsync()
{
try
{
_sockecClient = new TcpSocketClient();
await _sockecClient.ConnectAsync(Central.Ip, Central.Port);
_writter = new ExtendedBinaryWriter(_sockecClient.WriteStream);
_reader = new ExtendedBinaryReader(_sockecClient.ReadStream);
_writter.WriteString(EvenNotProtocol.MobileReceiverCommand);
_sockecClient.ReadStream.ReadTimeout = int.MaxValue;
EnableTcpService();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
#endregion
#region TcpService
private void EnableTcpService()
{
_cancelationTcpService = new CancellationTokenSource();
new Task(StartService, _cancelationTcpService.Token, TaskCreationOptions.LongRunning).Start();
}
private void StartService()
{
while (!_cancelationTcpService.Token.IsCancellationRequested)
{
var ev = EvenNotProtocol.DeserializeEvent(_reader);
if (ev == null) continue;
_writter.WriteString(EvenNotProtocol.MobileOkCommand);
EventReceived?.Invoke(this, new CentralTcpEventArgs(ev));
}
}
}
public class EvenNotProtocol
{
public static Event DeserializeEvent(ExtendedBinaryReader reader)
{
try
{
reader.SkipBytes(1);
.....
}
catch (IOException e)
{
return null;
}
}
}

How to reuse a SSH (Jsch) session created in an AsyncTask in another class

I'm a Android & Java newbie and here is my situation:
I'm trying to create an app which connects to a Beaglebone Black using a ssh connection and then controls some peripherals connected to the BBB by issuing commands coming from an Android device.
I'm opening (successfully) an ssh session in an AsyncTask while the user sees an splash screen, if the connection was successful the user will get a confirmation and then will be able to send predefined commands by clicking some available buttons.
What I want to do next is left the session opened and then create a new channel (exec or shell ) each time I wish to issue a command and wait for the response from the BBB, but I donĀ“t know how to reuse such ssh session outside the AsynkTask.
is that even possible?
I'm using Android Studio 0.8.2 and Jsch 0.1.51, my code is as follows:
public class SplashScreen extends ActionBarActivity {
public static final int segundos =10;
public static final int milisegundos =segundos*1000;
public static final int delay=2;
private ProgressBar pbprogreso;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
pbprogreso= (ProgressBar)findViewById(R.id.pbprogreso);
pbprogreso.setMax(maximo_progreso());
empezaranimacion();
}
public void empezaranimacion()
{
sshConnect task = new sshConnect();
task.execute(new String[] {"http:"});
new CountDownTimer(milisegundos,1000)
{
#Override
public void onTick(long milisUntilFinished){
pbprogreso.setProgress(establecer_progreso(milisUntilFinished));
}
#Override
public void onFinish(){
finish();
}
}.start();
}
public int establecer_progreso (long miliseconds)
{
return (int)((milisegundos-miliseconds)/1000);
}
public int maximo_progreso () {
return segundos-delay;
}
public class sshConnect extends AsyncTask <String, Void, String>{
ByteArrayOutputStream Baos=new ByteArrayOutputStream();
ByteArrayInputStream Bais = new ByteArrayInputStream(new byte[1000]);
#Override
protected String doInBackground(String... data) {
String host = "xxxxxxx";
String user = "root";
String pwd = "";
int port = 22;
JSch jsch = new JSch();
try {
Session session = jsch.getSession(user, host, port);
session.setPassword(pwd);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
channel.setOutputStream(Baos);
channel.setInputStream(Bais);
//Run Command
channel.setCommand("python ~/BBB_test/testconnect.py");
channel.connect();
try{Thread.sleep(3500);}catch (Exception ee){}
channel.disconnect();
//session.disconnect();
}catch (Exception e){
System.out.println(e.getMessage());
}
return Baos.toString();
}
#Override
protected void onPostExecute(String result) {
if (result.equals("Connected to BBB Baby!!\n")) {
Intent nuevofrom = new Intent(SplashScreen.this, Principal.class);
startActivity(nuevofrom);
finish();
} else {
Intent newfrom = new Intent(SplashScreen.this, ConnecError.class);
startActivity(newfrom);
finish();
}
}
}
//Here is where I want to reuse the opened session and create a new channel
public class sendCommand extends AsyncTask <String, Void, String >{
ByteArrayOutputStream Baosc=new ByteArrayOutputStream();
ByteArrayInputStream Baisc = new ByteArrayInputStream(new byte[1000])
protected String doInBackground (String... command){
try {
ChannelExec channel2 = (ChannelExec)session.openChannel("exec");
channel2.setOutputStream(Baosc);
channel2.setInputStream(Baisc);
//Run Command
channel2.setCommand("python ~/BBB_test/testgpio.py");
channel2.connect();
try{Thread.sleep(3500);}catch (Exception ee){}
channel2.disconnect();
}catch (Exception e) {
System.out.println(e.getMessage());
}
return Baosc.toString();
}
protected void onPostExecute(Long result) {
TextView txt = (TextView) findViewById(R.id.infotext);
txt.setText(result);
}
}
If something else is needed let me know! (it is the first time I ask something in a forum)
Thanks a lot for your time and support!
I managed to get what I wanted by using the recommendation from DamienKnight of creating the session outside the Asynktask class. I create a public classwith three methods to create, return and disconnect the session:
public static class cSession {
String host = "xxx.xxx.xxx.xxx";
String user = "root";
String pwd = "";
int port = 22;
JSch jsch = new JSch();
public Session Met1 (){
try {
session = jsch.getSession(user, host, port);
session.setPassword(pwd);
session.setConfig("StrictHostKeyChecking", "no");
} catch (Exception e2){
System.out.println(e2.getMessage());
}return session;
}
public Session damesession (){
return session;
}
public void close_ses(){
session.disconnect();
}
}
By doing this so, the creation of channels is flexible and I can use the methods from Jsch too.
public class sshConnect extends AsyncTask <String, Void, String>{
ByteArrayOutputStream Baos=new ByteArrayOutputStream();
ByteArrayInputStream Bais = new ByteArrayInputStream(new byte[1000]);
#Override
protected String doInBackground(String... data) {
cSession jschses = new cSession();
Session ses =null;
ses = jschses.Met1();
try {
ses.connect();
ChannelExec channel = (ChannelExec)ses.openChannel("exec");
channel.setOutputStream(Baos);
channel.setInputStream(Bais);
//Run Command
channel.setCommand("python ~/BBB_test/testconnect.py");
channel.connect();
try{Thread.sleep(3500);}catch (Exception ee){}
channel.disconnect();
//session.disconnect();
}catch (Exception e){
System.out.println(e.getMessage());
}
return Baos.toString();
}
Thanks #Damienknight!
Regards
If you are wanting to reuse the session, you dont need to reconect the channel each time. Connect it once as a shell, plugging an input and output stream into it. Use the streams to pass commands and capture output.
See the JSCH example on the JCraft website.
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();

an integer or string of size 1 is required exception

I was trying a sketch program found online that connects wirelessly to my Raspberry pi using HttpURLConnection.. it's catching the exception "an integer or string of size 1 is required" and i dunno where's the error yet. The program basically sends a character or number when the user hits a button on UI to the webserver running on Raspberry pi. here's a part of the send command:
private void sendCommand(String command) {
final String cmd = command;
AsyncTask task = new AsyncTask() {
private String resp;
#Override
protected Object doInBackground(Object... params) {
try {
resp = Sender.getStringResponseFromGetRequest(
"http://192.168.1.111:8888/" + cmd);
} catch (IOException e) {
resp = e.getMessage();
}
return null;
}
};
}
#Override
protected void onPostExecute(Object result) {
if(!resp.equals("OK")){
Toast.makeText(ctx, resp, Toast.LENGTH_LONG).show();
}
super.onPostExecute(result);
}
};
task.execute();
}
}
and here's the getStringResponse.. Method:
public static String getStringResponseFromGetRequest(String requestUrl)
throws IOException {
URL url1;
URLConnection urlConnection;
DataInputStream inStream;
url1 = new URL(requestUrl);
urlConnection = url1.openConnection();
((HttpURLConnection) urlConnection).setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(false);
urlConnection.setUseCaches(false);
inStream = new DataInputStream(urlConnection.getInputStream());
return inStream.readLine();
}

Resources