I am trying to run this code but code inside my runOnUi thread is not executing. I am using evernote-android-job.
He is the code which runs periodically:
public class TempJob extends Job {
public static final String TAG = "job_temp_mqtt";
@Override
@NonNull
protected Result onRunJob(@NonNull Params params) {
Log.d("I'm here", "Position 0");
Looper.prepare();
PubSubActivityTemp worker = new PubSubActivityTemp();
Log.d("I'm here", "Position 1");
worker.exe();
return Result.SUCCESS;
}
public static void scheduleJob() {
Set<JobRequest> jobRequests =
JobManager.instance().getAllJobRequestsForTag(TempJob.TAG);
if (!jobRequests.isEmpty()) {
Log.d("Check: ", "Job is not Empty");
// return;
}
new JobRequest.Builder(TempJob.TAG)
.setPeriodic(TimeUnit.MINUTES.toMillis(15),
TimeUnit.MINUTES.toMillis(7))
.setUpdateCurrent(true) // calls
cancelAllForTag(NoteSyncJob.TAG) for you
.setRequiredNetworkType(JobRequest.NetworkType.ANY)
.setRequirementsEnforced(true)
.build()
.schedule();
}
}
Here is the code from the activity:
public class PubSubActivityTemp extends Activity {
static final String LOG_TAG = GraphSelectType.class.getCanonicalName();
// --- Constants to modify per your configuration ---
// IoT endpoint
// AWS Iot CLI describe-endpoint call returns: XXXXXXXXXX.iot.
<region>.amazonaws.com
private static final String CUSTOMER_SPECIFIC_ENDPOINT = "*************-
ats.iot.us-east-1.amazonaws.com";
// Cognito pool ID. For this app, pool needs to be unauthenticated pool
with
// AWS IoT permissions.
private static final String COGNITO_POOL_ID = "us-east-
1:*************-75c2-4258-b663-21*********83e";
// Name of the AWS IoT policy to attach to a newly created certificate
private static final String AWS_IOT_POLICY_NAME = "PubSub******Cert";
// Region of AWS IoT
private static final Regions MY_REGION = Regions.US_EAST_1;
// Filename of KeyStore file on the filesystem
private static final String KEYSTORE_NAME = "iot_keystore";
// Password for the private key in the KeyStore
private static final String KEYSTORE_PASSWORD = "password";
// Certificate and key aliases in the KeyStore
private static final String CERTIFICATE_ID = "default";
TextView tvStatus;
// TextView tvLastMessage;
Handler mHandler;
AWSIotClient mIotAndroidClient;
AWSIotMqttManager mqttManager;
String clientId;
String keystorePath;
String keystoreName;
String keystorePassword;
KeyStore clientKeyStore = null;
String certificateId;
CognitoCachingCredentialsProvider credentialsProvider;
int tracker = 0; //0 is on, 1 is off
private String topic = "Simran*****";
private String msg0 = "on";
private String msg1 = "off";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void exe() {
Log.d("I'm here", "Position 2");
new Thread() {
public void run() {
Log.d("I'm here", "Position 3");
runOnUiThread(() -> {
Log.d("I'm here", "Position 4");
Toast.makeText(PubSubActivityTemp.this, "Storage not
available", Toast.LENGTH_SHORT).show();
});
Log.d("I'm here", "Position 5");
}
}.start();
}
public void mqtt() {
// tvStatus = (TextView) findViewById(R.id.tvStatus);
// tvLastMessage = (TextView) findViewById(R.id.tvLastMessage);
// MQTT client IDs are required to be unique per AWS IoT account.
// This UUID is "practically unique" but does not _guarantee_
// uniqueness.
clientId = UUID.randomUUID().toString();
// Initialize the AWS Cognito credentials provider
credentialsProvider = new CognitoCachingCredentialsProvider(
// getApplicationContext(), // context
TempApplication.getAppContext(),
COGNITO_POOL_ID, // Identity Pool ID
MY_REGION // Region
);
Region region = Region.getRegion(MY_REGION);
// MQTT Client
mqttManager = new AWSIotMqttManager(clientId,
CUSTOMER_SPECIFIC_ENDPOINT);
// Set keepalive to 10 seconds. Will recognize disconnects more
quickly but will also send
// MQTT pings every 10 seconds.
mqttManager.setKeepAlive(10);
// Set Last Will and Testament for MQTT. On an unclean disconnect
(loss of connection)
// AWS IoT will publish this message to alert other clients.
AWSIotMqttLastWillAndTestament lwt = new
AWSIotMqttLastWillAndTestament("my/lwt/topic",
"Android client lost connection", AWSIotMqttQos.QOS0);
mqttManager.setMqttLastWillAndTestament(lwt);
// IoT Client (for creation of certificate if needed)
mIotAndroidClient = new AWSIotClient(credentialsProvider);
mIotAndroidClient.setRegion(region);
keystorePath = getFilesDir().getPath();
keystoreName = KEYSTORE_NAME;
keystorePassword = KEYSTORE_PASSWORD;
certificateId = CERTIFICATE_ID;
// To load cert/key from keystore on filesystem
try {
if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath,
keystoreName)) {
if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId,
keystorePath,
keystoreName, keystorePassword)) {
Log.i(LOG_TAG, "Certificate " + certificateId
+ " found in keystore - using for MQTT.");
// load keystore from file into memory to pass on
connection
clientKeyStore =
AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// btnConnect.setEnabled(true);
} else {
Log.i(LOG_TAG, "Key/cert " + certificateId + " not found
in keystore.");
}
} else {
Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName
+ " not found.");
}
} catch (Exception e) {
Log.e(LOG_TAG, "An error occurred retrieving cert/key from
keystore.", e);
}
if (clientKeyStore == null) {
Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new
key and certificate.");
new Thread(new Runnable() {
@Override
public void run() {
try {
// Create a new private key and certificate. This call
// creates both on the server and returns them to the
// device.
CreateKeysAndCertificateRequest
createKeysAndCertificateRequest =
new CreateKeysAndCertificateRequest();
createKeysAndCertificateRequest.setSetAsActive(true);
final CreateKeysAndCertificateResult
createKeysAndCertificateResult;
createKeysAndCertificateResult =
mIotAndroidClient.createKeysAndCertificate
(createKeysAndCertificateRequest);
Log.i(LOG_TAG,
"Cert ID: " +
createKeysAndCertificateResult.getCertificateId() +
" created.");
// store in keystore for use in MQTT client
// saved as alias "default" so a new certificate isn't
// generated each run of this application
AWSIotKeystoreHelper.saveCertificateAndPrivateKey
(certificateId,
createKeysAndCertificateResult.getCertificatePem(),
createKeysAndCertificateResult.getKeyPair().getPrivateKey(),
keystorePath, keystoreName, keystorePassword);
// load keystore from file into memory to pass on
// connection
clientKeyStore =
AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// Attach a policy to the newly created certificate.
// This flow assumes the policy was already created in
// AWS IoT and we are now just attaching it to the
// certificate.
AttachPrincipalPolicyRequest policyAttachRequest =
new AttachPrincipalPolicyRequest();
policyAttachRequest.setPolicyName(AWS_IOT_POLICY_NAME);
policyAttachRequest.setPrincipal(createKeysAndCertificateResult
.getCertificateArn());
mIotAndroidClient.attachPrincipalPolicy(policyAttachRequest);
runOnUiThread(new Runnable() {
@Override
public void run() {
// btnConnect.setEnabled(true);
}
});
} catch (Exception e) {
Log.e(LOG_TAG,
"Exception occurred when generating new
private key and certificate.",
e);
}
}
}).start();
}
connect();
subscribe();
}
public void connect() {
try {
mqttManager.connect(clientKeyStore, new
AWSIotMqttClientStatusCallback() {
@Override
public void onStatusChanged(final AWSIotMqttClientStatus
status,
final Throwable throwable) {
Log.d(LOG_TAG, "Status = " + String.valueOf(status));
runOnUiThread(new Runnable() {
@Override
public void run() {
if (status == AWSIotMqttClientStatus.Connecting) {
tvStatus.setText("Connecting...");
} else if (status ==
AWSIotMqttClientStatus.Connected) {
tvStatus.setText("Connected");
} else if (status ==
AWSIotMqttClientStatus.Reconnecting) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.",
throwable);
}
tvStatus.setText("Reconnecting");
} else if (status ==
AWSIotMqttClientStatus.ConnectionLost) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.",
throwable);
}
tvStatus.setText("Disconnected");
} else {
tvStatus.setText("Disconnected");
}
}
});
}
});
} catch (final Exception e) {
Log.e(LOG_TAG, "Connection error.", e);
tvStatus.setText("Error! " + e.getMessage());
}
}
public void subscribe() {
try {
mqttManager.subscribeToTopic(topic, AWSIotMqttQos.QOS0,
new AWSIotMqttNewMessageCallback() {
@Override
public void onMessageArrived(final String topic, final
byte[] data) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
String message = new String(data,
"UTF-8");
Log.d(LOG_TAG, "Message arrived:");
Log.d(LOG_TAG, " Topic: " + topic);
Log.d(LOG_TAG, " Message: " +
message);
//
tvLastMessage.setText(message);
} catch (UnsupportedEncodingException e) {
Log.e(LOG_TAG, "Message encoding
error.", e);
}
}
});
}
});
} catch (Exception e) {
Log.e(LOG_TAG, "Subscription error.", e);
}
}
}
Here is the output from logcat. I ahve filtered out only necessary output. I am not getting any warning or errors:
09-30 11:55:23.662 5705-6268/com.simran.powermanagement D/I'm here:
Position 0
09-30 11:55:23.663 5705-6268/com.simran.powermanagement D/I'm here:
Position 1
Position 2
09-30 11:55:23.665 5705-6269/com.simran.powermanagement D/I'm here:
Position 3
09-30 11:55:23.665 5705-6269/com.simran.powermanagement D/I'm here:
Position 5
Toast
needs context
and when you instantiate an Activity class using new
you just create a java class that it has no context.if you need some method of your activity you must send your activity or its context object to your Job
class and use it for create your activity. like this :
public class PubSubActivityTemp extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
yourJob job=new yourJob (this);
}
}
in your job class :
public class TempJob extends Job {
Activity activity;
public TempJob (Activity activity){
this.activity=activity;
PubSubActivityTemp worker=(PubSubActivityTemp)activity;
}
}
if you you don't want to create your job in PubSubActivityTemp
i suggest you use this way to instantiate PubSubActivityTemp
:
first create a class that extends Application class :
public class Myapp extends Application{
public PubSubActivityTemp pubSubActivityTemp;
}
in AndroidManifast.xml file in <application>
tag use this class for name
attribute :
<application name=".Myapp ">
in your PubSubActivityTemp
onCreate()
methode :
public class PubSubActivityTemp extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp myApp=(MyApp) getApplicationContext();// or getApplication();
myApp.pubSubActivityTemp=this;
}
}
in every class you need PubSubActivityTemp
activity just send to it getApplicationContext
as Context
an in it :
public class TempJob extends Job {
Activity activity;// or use Context context;
public TempJob (Activity activity){
this.activity=activity;
MyApp myApp=(MyApp)activity.getApplicationContext();
PubSubActivityTemp worker=myApp.pubSubActivityTemp;
}
}
in another class that you need job :
public class AnotherActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TempJob job=new TempJob(this);
}
}
and if you just want to find out some code working you can log it with Log.v()
instead Toast