I am new to android.I want to use my service for fetching the Json data from server.when I open my app then all works fine but when I exit my app or when my device go to sleep then there is a Json exception.how can I make my service run every-time in background. Please guide for solving this error.
error:-
E/agdghdgdgdrgrdgrdg: dgdgd
W/System.err: java.net.UnknownHostException: Unable to resolve host
"podgier-
woman.000webhostapp.com": No address associated with hostname
W/System.err: at
java.net.InetAddress.lookupHostByName(InetAddress.java:457)
W/System.err: at
java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
W/System.err: at
java.net.InetAddress.getAllByName(InetAddress.java:215)
W/System.err: at
org.apache.http.conn.DefaultClientConnectionOperator.openConnection
(DefaultClientConnectionOperator.java:137)
W/System.err:at org.apache.http.impl.conn.AbstractPoolEntry.open
(AbstractPoolEntry.java:164)
W/Systemerr:at
org.apache.http.impl.conn.AbstractPooledConnAdapter.open
(AbstractPooledConnAdapter.java:119)
W/System.err: at
org.apache.http.impl.client.DefaultRequestDirector.execute
(DefaultRequestDirector.java:360)
W/System.err:at
org.apache.http.impl.client.AbstractHttpClient.execute
(AbstractHttpClient.java:555)
W/System.err:at
org.apache.http.impl.client.AbstractHttpClient.execute
(AbstractHttpClient.java:487)
W/System.err:at
org.apache.http.impl.client.AbstractHttpClient.execute
(AbstractHttpClient.java:465)
W/System.err: at com.grover.jsonp.JSONParser.makeHttpRequest
(JSONParser.java:62)
W/System.err:at com.grover.jsonp.BackgroundService$gro.doInBackground
(BackgroundService.java:50)
W/System.err: at
com.grover.jsonp.BackgroundService$gro.doInBackground
(BackgroundService.java:41)
W/System.err:at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err:at java.util.concurrent.FutureTask.run
(FutureTask.java:237)
W/System.err: at
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker
(ThreadPoolExecutor.java:1112)
W/System.err: at
java.util.concurrent.ThreadPoolExecutor
$Worker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: android.system.GaiException:
android_getaddrinfo
failed: EAI_NODATA (No address associated with hostname)
W/System.err: at libcore.io.Posix.android_getaddrinfo(Native
Method)
W/System.err: at
libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
W/System.err: at
java.net.InetAddress.lookupHostByName(InetAddress.java:438)
W/System.err: ... 18 more
E/Buffer Error: Error converting result java.io.IOException: Attempted
read
on closed stream.
BackgroundService.java
public class BackgroundService extends Service
{
public BackgroundService(){
}
private static String url ="https://podgier-woman.000webhostapp.com/table.php";
JSONParser jParser = new JSONParser();
ArrayList<String> bcv;
class gro extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
java.util.List<NameValuePair> pr = new ArrayList<NameValuePair>();
JSONObject json = jParser.makeHttpRequest(url, "GET", pr);
bcv = new ArrayList<String>();
try {
JSONArray code = json.getJSONArray("code");
Log.d("list :",code.toString());
for (int i = 0; i < code.length(); i++) {
JSONObject c = code.getJSONObject(i);
bcv.add(c.getString("name"));
// adding each child node to HashMap key => value
// adding contact to contact list
JSONArray p = null;
}
}catch(JSONException e){
}
return null;
}
protected void onPostExecute(String file_url) {
Log.v("sdg","sgfdg"+record.idName);
if(record.idName < bcv.size()){
int xx= bcv.size() - record.idName;
Intent intent = new Intent(BackgroundService.this, record.class);
PendingIntent pIntent = PendingIntent.getActivity(BackgroundService.this, (int) System.currentTimeMillis(),intent, 0);
Log.d("SGsgzxv","dfgzdvv");
Notification n = new Notification.Builder(getApplicationContext())
.setContentTitle("View "+xx+" updated data")
.setContentText("data pending ")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.addAction(R.mipmap.ic_launcher, "call", pIntent)
.addAction(R.mipmap.ic_launcher, "More", pIntent)
.addAction(R.mipmap.ic_launcher, "and more", pIntent)
.build();
Uri so = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
n.sound = so;
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(0,n);
}
record.idName = bcv.size();
bcv.clear();
}
}
private static final String TAG = "BackgroundService";
private ThreadGroup myThreads = new ThreadGroup("ServiceWorker");
#Override
public void onCreate() {
super.onCreate();
Log.v(TAG, "in onCreate()");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
int counter = intent.getExtras().getInt("counter");
Log.v(TAG, "in onStartCommand(), counter = " + counter +
", startId = " + startId);
new Thread(myThreads, new ServiceWorker(counter), "BackgroundService")
.start();
return START_STICKY;
}
class ServiceWorker implements Runnable
{
private int counter = -1;
public ServiceWorker(int counter) {
this.counter = counter;
}
public void run() {
final String TAG2 = "ServiceWorker:" + Thread.currentThread().getId();
// do background processing here...
try {
Log.e(TAG2, "sleeping for 5 seconds. counter = " + counter);
while(true)
{
Thread.sleep(9000);
Log.e("agdghdgdgdrgrdgrdg","dgdgd");
new gro().execute();
}
} catch (InterruptedException e) {
Log.e(TAG2, "... sleep interrupted");
}
}
}
#Override
public void onDestroy()
{
}
#Override
public IBinder onBind(Intent intent) {
Log.v(TAG, "in onBind()");
return null;
}
}
I don't recommend using a background service for such purposes. I know from experience that we are never sure that such a service will not be destroyed by the system.
To perform tasks (periodic, single) I recommend using Firebase Job Dispatcher. In my opinion, this is a more reliable mechanism when it comes to doing background work.
Here is an example of use, given by me: https://stackoverflow.com/a/44489327/8119117
Related
I am trying to create an instance of AlarmManager with pendingIntent, but I cannot understand where I am going wrong.
My android app implements a customer class (eventHandler) which is Serializable. I have converted the object of my class to a byte array in order to pass it as an extra into my alarm intent. The app starts and works fine, reading the byte array and creating the alarm intent in my object with pendingintent. The problem occurs when I try to start a second activity, get the object of my class (which is serializable) and then convert it to a byte array to be passed as an extra.
The code that is a problem is:
Intent intent = new Intent(getActivity(), EventWeatherActivity.class);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bos);
**out.writeObject(event);**
out.flush();
byte[] data = bos.toByteArray();
intent.putExtra(EXTRA_MESSAGE, data);
out.writeObject(event); - is the line causing the error. But event which belongs to eventHandler (Serializable) did run when the app began, so why is it an issue when I am starting another activity?
The error that I am getting is:
W/System.err: java.io.NotSerializableException: android.app.PendingIntent
2020-03-21 10:26:43.440 7646-7646/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
2020-03-21 10:26:43.440 7646-7646/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
2020-03-21 10:26:43.440 7646-7646/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
2020-03-21 10:26:43.443 7646-7646/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
2020-03-21 10:26:43.443 7646-7646/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
2020-03-21 10:26:43.443 7646-7646/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
2020-03-21 10:26:43.444 7646-7646/com.example.scrollingtext W/System.err: at com.example.scrollingtext.EventFragment$1.onItemClick(EventFragment.java:122)
In my customer class (eventHandler event):
Intent alarmIntent = new Intent(context, NotificationReceiver.class);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(this);
out.flush();
byte[] data = bos.toByteArray();
alarmIntent.putExtra("imw.notification", data);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
final int id = (int) System.currentTimeMillis();
pendingIntent = PendingIntent.getBroadcast(context, id, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
I think the problem is that your EventHandler class contains pendingIntent field, which cannot be serialized. You should separate your EventHandler class and describe there only fields you want to serialize. Also please provide the whole listing of your EventHandler class to see what else can cause the problem. Your current listing is not full.
Yes, pendingIntent cannot be serialized, but weirdly when the app initially runs, pendingIntent runs fine within eventHandler and an alarm IS created successfully. The problem comes about when I try to then get a copy of that eventHandler object and convert it into a byte array as above so that I can pass the eventHandler object to my second activity. If I comment out the creation of a pendingIntent and alarm, the app runs fine passing the eventHandler object between activities.
So, as mentioned above I seperated the Alarm creation into a "Notification" class:
public class Notifications implements Serializable {
private PendingIntent pendingIntent;
private int notification_period;
private String notification_interval;
private Activity activity;
private Context context;
private AlarmManager manager;
private eventHandler event;
public Notifications(eventHandler event, int notification_period, String notification_interval, Activity activity, Context context)
{
this.notification_interval = notification_interval;
this.notification_period = notification_period;
this.activity = activity;
this.context = context;
this.event = event;
}
public void setAlarm()
{
manager = (android.app.AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
if(notification_period != -1 && !notification_interval.equals("-1")) {
Intent alarmIntent = new Intent(context, NotificationReceiver.class);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(event);
out.flush();
byte[] data = bos.toByteArray();
alarmIntent.putExtra("imw.notification", data);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
final int id = (int) System.currentTimeMillis();
pendingIntent = PendingIntent.getBroadcast(context, id, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if(notification_interval.equals("minute")) {
manager.setRepeating(android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), notification_period*60*1000, pendingIntent);
}
else if(notification_interval.equals("hour")) {
manager.setRepeating(android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() * android.app.AlarmManager.INTERVAL_HOUR * notification_period, android.app.AlarmManager.INTERVAL_HOUR, pendingIntent);
}
else if(notification_interval.equals("day")) {
manager.setRepeating(android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() * android.app.AlarmManager.INTERVAL_DAY * notification_period, android.app.AlarmManager.INTERVAL_DAY, pendingIntent);
}
Log.d("alarm_set", notification_period + " " + notification_interval);
}
else {
if(pendingIntent != null)
{
manager.cancel(pendingIntent);
Log.d("alarm_cancelled", pendingIntent.toString());
}
}
}
}
..and now with the above, in my eventHandler class:
public void processEvent() {
try {
dailyWeather dWeather = new dailyWeather(raw_weather);
hWeather = new hourlyWeather(raw_weather);
tag = event.get("Tag");
start_date = event.get("Start Date");
start_time = event.get("Start Time");
end_time = event.get("End Time");
location = event.get("Location");
lat = event.get("Lat");
lng = event.get("Lng");
notification_period = Integer.parseInt(event.get("Notification Period"));
notification_interval = event.get("Notification Interval");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate fromDate = LocalDate.parse(start_date, formatter);
LocalDateTime localTime_fromTime = LocalDateTime.parse(start_date + " " + start_time, DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
LocalDateTime localTime_toTime = LocalDateTime.parse(start_date + " " + end_time, DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
if (DAYS.between(LocalDate.now(), fromDate) > 7) {
bActive = false;
}
else if(LocalDateTime.now().isAfter(localTime_toTime)) {
Log.d("Expired", "End time");
bActive = false;
bExpired = true;
bContainsHours = true;
}
else {
bActive = true;
weather = dWeather.getWeather(start_date);
if (!start_time.equals("0")) {
bContainsHours = true;
}
if(notification_period != -1 && !notification_interval.equals("")) {
notificationManager = new Notifications(this, notification_period, notification_interval, activity, context);
notificationManager.setAlarm();
}
}
}catch(Exception e)
{
Log.d("Err", "Error appearing here");
e.printStackTrace();
}
}
now the app crashed when I run it from the beginning, complaining that AlarmManager is not serialized.
java.io.NotSerializableException: android.app.AlarmManager
2020-03-22 12:22:50.371 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
2020-03-22 12:22:50.371 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
2020-03-22 12:22:50.372 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err: at com.example.scrollingtext.Notifications.setAlarm(Notifications.java:47)
2020-03-22 12:22:50.377 16593-16593/com.example.scrollingtext W/System.err: at com.example.scrollingtext.eventHandler.processEvent(eventHandler.java:98)
I am trying to set up AWS Cognito email verification for my app. However, when the email verification number is typed in and the user clicks the verify button, I keep getting a
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
I understand what this means however I am learning as I go, so I am struggling to find exactly where the issue is made.
I have already researched the issues over Stack Overflow and have not found any help directly relating to this issue and amazon cognito. I have tried adjusting the array size and tried to make different catch senerios to see where the code goes wrong.
Here is the Java file that the error comes from
public class verify extends AppCompatActivity {
private static final String TAG = "Cognito";
private CognitoUserPool userPool;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verify);
final EditText verifyCode = findViewById(R.id.verifyCode);
Button verifyButton = findViewById(R.id.verifyButton);
verifyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new ConfirmTask().execute(String.valueOf(verifyCode.getText()));
Intent intent = new Intent(verify.this, stepTwo.class);
startActivity(intent);
}
});
}
protected class ConfirmTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
final String[] result = new String[1];
final GenericHandler confirmationCallback = new GenericHandler() {
#Override
public void onSuccess() {
result[0] = "Successful!";
}
#Override
public void onFailure(Exception exception) {
result[0] = "Failed " + exception.getMessage();
}
};
CognitoSettings cognitoSettings = new CognitoSettings(verify.this);
CognitoUser thisUser = cognitoSettings.getUserPool().getUser(strings[1]);
thisUser.confirmSignUp(strings[0], false, confirmationCallback);
return result[0];
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
Log.i(TAG, "Confirmation result: " + result);
}
}
}
I expect the app to not crash and for the Amazon Cognito User Pool to show that I have verified the email.
Here is my logcat
2019-09-04 18:02:51.418 18206-19048/com.example.medicut E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.medicut, PID: 18206
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$4.done(AsyncTask.java:399)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.example.medicut.verify$ConfirmTask.doInBackground(verify.java:64)
at com.example.medicut.verify$ConfirmTask.doInBackground(verify.java:41)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
I'm working on a term project and I'm new to java and android app development. I have experience in other programming languages, though. I'm trying to reverse engineer an app to make it able to connect and send data via bluetooth. I want to make a list with all the available bluetooth devices, a button to turn on/off bluetooth, one for making the phone discoverable for other devices and another to search for unpaired devices. But every time I add an OnClickListener to the onCreate method, the app crashes before it opens. Could anyone help me out?
The source code for the app I am trying to modify can be found here:
https://github.com/pazaan/600SeriesAndroidUploader
Here is the part that seems to makes it crash:
lvNewDevices.setOnItemClickListener(MainActivity.this);
btnONOFF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "onClick: enabling/disabling bluetooth.");
enableDisableBT();
}
});
btnStartConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startConnection();
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
byte[] bytes = etSend.getText().toString().getBytes(Charset.defaultCharset());
mBluetoothConnection.write(bytes);
}
});
And here is all of OnCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate called");
super.onCreate(savedInstanceState);
Button btnONOFF = (Button) findViewById(R.id.btnONOFF);
btnEnableDisable_Discoverable = (Button) findViewById(R.id.btnDiscoverable_on_off);
lvNewDevices = (ListView) findViewById(R.id.lvNewDevices);
mBTDevices = new ArrayList<>();
btnStartConnection = (Button) findViewById(R.id.btnStartConnection);
//Broadcasts when bond state changes (ie:pairing)
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mBroadcastReceiver4, filter);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//FUCKUP:
lvNewDevices.setOnItemClickListener(MainActivity.this);
btnONOFF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "onClick: enabling/disabling bluetooth.");
enableDisableBT();
}
});
btnStartConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startConnection();
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
byte[] bytes = etSend.getText().toString().getBytes(Charset.defaultCharset());
mBluetoothConnection.write(bytes);
}
});
mRealm = Realm.getDefaultInstance();
RealmResults<PumpStatusEvent> data = mRealm.where(PumpStatusEvent.class)
.findAllSorted("eventDate", Sort.DESCENDING);
if (data.size() > 0)
dataStore.setLastPumpStatus(data.first());
setContentView(R.layout.activity_main);
PreferenceManager.getDefaultSharedPreferences(getBaseContext()).registerOnSharedPreferenceChangeListener(this);
prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
if (!prefs.getBoolean(getString(R.string.preference_eula_accepted), false)) {
stopCgmService();
}
// setup preferences
configurationStore.setPollInterval(Long.parseLong(prefs.getString("pollInterval", Long.toString(MedtronicCnlIntentService.POLL_PERIOD_MS))));
configurationStore.setLowBatteryPollInterval(Long.parseLong(prefs.getString("lowBatPollInterval", Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS))));
configurationStore.setReducePollOnPumpAway(prefs.getBoolean("doublePollOnPumpAway", false));
chartZoom = Integer.parseInt(prefs.getString("chartZoom", "3"));
configurationStore.setMmolxl(prefs.getBoolean("mmolxl", false));
configurationStore.setMmolxlDecimals(prefs.getBoolean("mmolDecimals", false));
// Disable battery optimization to avoid missing values on 6.0+
// taken from https://github.com/NightscoutFoundation/xDrip/blob/master/app/src/main/java/com/eveningoutpost/dexdrip/Home.java#L277L298
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final String packageName = getPackageName();
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
Log.d(TAG, "Requesting ignore battery optimization");
try {
// ignoring battery optimizations required for constant connection
// to peripheral device - eg CGM transmitter.
final Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.d(TAG, "Device does not appear to support battery optimization whitelisting!");
}
}
}
LocalBroadcastManager.getInstance(this).registerReceiver(
statusMessageReceiver,
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_STATUS_MESSAGE));
LocalBroadcastManager.getInstance(this).registerReceiver(
new UpdatePumpReceiver(),
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_UPDATE_PUMP));
mEnableCgmService = Eula.show(this, prefs);
IntentFilter batteryIntentFilter = new IntentFilter();
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_LOW);
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
batteryIntentFilter.addAction(Intent.ACTION_BATTERY_OKAY);
registerReceiver(batteryReceiver, batteryIntentFilter);
IntentFilter usbIntentFilter = new IntentFilter();
usbIntentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
usbIntentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
usbIntentFilter.addAction(MedtronicCnlIntentService.Constants.ACTION_USB_PERMISSION);
registerReceiver(usbReceiver, usbIntentFilter);
LocalBroadcastManager.getInstance(this).registerReceiver(
usbReceiver,
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_NO_USB_PERMISSION));
LocalBroadcastManager.getInstance(this).registerReceiver(
usbReceiver,
new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_USB_REGISTER));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setElevation(0);
getSupportActionBar().setTitle("Nightscout");
}
final PrimaryDrawerItem itemSettings = new PrimaryDrawerItem()
.withName("Settings")
.withIcon(GoogleMaterial.Icon.gmd_settings)
.withSelectable(false);
final PrimaryDrawerItem itemRegisterUsb = new PrimaryDrawerItem()
.withName("Registered devices")
.withIcon(GoogleMaterial.Icon.gmd_usb)
.withSelectable(false);
final PrimaryDrawerItem itemStopCollecting = new PrimaryDrawerItem()
.withName("Stop collecting data")
.withIcon(GoogleMaterial.Icon.gmd_power_settings_new)
.withSelectable(false);
final PrimaryDrawerItem itemGetNow = new PrimaryDrawerItem()
.withName("Read data now")
.withIcon(GoogleMaterial.Icon.gmd_refresh)
.withSelectable(false);
final PrimaryDrawerItem itemUpdateProfile = new PrimaryDrawerItem()
.withName("Update pump profile")
.withIcon(GoogleMaterial.Icon.gmd_insert_chart)
.withSelectable(false);
final PrimaryDrawerItem itemClearLog = new PrimaryDrawerItem()
.withName("Clear log")
.withIcon(GoogleMaterial.Icon.gmd_clear_all)
.withSelectable(false);
final PrimaryDrawerItem itemCheckForUpdate = new PrimaryDrawerItem()
.withName("Check for App update")
.withIcon(GoogleMaterial.Icon.gmd_update)
.withSelectable(false);
assert toolbar != null;
new DrawerBuilder()
.withActivity(this)
.withAccountHeader(new AccountHeaderBuilder()
.withActivity(this)
.withHeaderBackground(R.drawable.drawer_header)
.build()
)
.withTranslucentStatusBar(false)
.withToolbar(toolbar)
.withActionBarDrawerToggle(true)
.withSelectedItem(-1)
.addDrawerItems(
itemSettings,
//itemUpdateProfile, // TODO - re-add when we to add Basal Profile Upload
itemRegisterUsb,
itemCheckForUpdate,
itemClearLog,
itemGetNow,
itemStopCollecting
)
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
if (drawerItem.equals(itemSettings)) {
openSettings();
} else if (drawerItem.equals(itemRegisterUsb)) {
openUsbRegistration();
} else if (drawerItem.equals(itemStopCollecting)) {
mEnableCgmService = false;
stopCgmService();
finish();
} else if (drawerItem.equals(itemGetNow)) {
// It was triggered by user so start reading of data now and not based on last poll.
sendStatus("Requesting poll now...");
startCgmService(System.currentTimeMillis() + 1000);
} else if (drawerItem.equals(itemClearLog)) {
clearLogText();
} else if (drawerItem.equals(itemCheckForUpdate)) {
checkForUpdateNow();
}
return false;
}
})
.build();
mTextViewLog = (TextView) findViewById(R.id.textview_log);
mScrollView = (ScrollView) findViewById(R.id.scrollView);
mScrollView.setSmoothScrollingEnabled(true);
mChart = (GraphView) findViewById(R.id.chart);
// disable scrolling at the moment
mChart.getViewport().setScalable(false);
mChart.getViewport().setScrollable(false);
mChart.getViewport().setYAxisBoundsManual(true);
mChart.getViewport().setMinY(80);
mChart.getViewport().setMaxY(120);
mChart.getViewport().setXAxisBoundsManual(true);
final long now = System.currentTimeMillis(),
left = now - chartZoom * 60 * 60 * 1000;
mChart.getViewport().setMaxX(now);
mChart.getViewport().setMinX(left);
// due to bug in GraphView v4.2.1 using setNumHorizontalLabels reverted to using v4.0.1 and setOnXAxisBoundsChangedListener is n/a in this version
/*
mChart.getViewport().setOnXAxisBoundsChangedListener(new Viewport.OnXAxisBoundsChangedListener() {
#Override
public void onXAxisBoundsChanged(double minX, double maxX, Reason reason) {
double rightX = mChart.getSeries().get(0).getHighestValueX();
hasZoomedChart = (rightX != maxX || rightX - chartZoom * 60 * 60 * 1000 != minX);
}
});
*/
mChart.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (!mChart.getSeries().isEmpty() && !mChart.getSeries().get(0).isEmpty()) {
double rightX = mChart.getSeries().get(0).getHighestValueX();
mChart.getViewport().setMaxX(rightX);
mChart.getViewport().setMinX(rightX - chartZoom * 60 * 60 * 1000);
}
hasZoomedChart = false;
return true;
}
});
mChart.getGridLabelRenderer().setNumHorizontalLabels(6);
// due to bug in GraphView v4.2.1 using setNumHorizontalLabels reverted to using v4.0.1 and setHumanRounding is n/a in this version
// mChart.getGridLabelRenderer().setHumanRounding(false);
mChart.getGridLabelRenderer().setLabelFormatter(
new DefaultLabelFormatter() {
DateFormat mFormat = new SimpleDateFormat("HH:mm", Locale.US); // 24 hour format forced to fix label overlap
#Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
return mFormat.format(new Date((long) value));
} else {
return MainActivity.strFormatSGV(value);
}
}
}
);
}
Here is the logcat output:
09-26 12:38:19.826 6324-6324/? I/art: Late-enabling -Xcheck:jni
09-26 12:38:20.157 6324-6324/info.nightscout.android E/Fabric: Failure onPreExecute()
java.lang.IllegalArgumentException: Fabric could not be initialized, API key missing from AndroidManifest.xml. Add the following tag to your Application element
<meta-data android:name="io.fabric.ApiKey" android:value="YOUR_API_KEY"/>
at io.fabric.sdk.android.services.common.ApiKey.logErrorOrThrowException(ApiKey.java:110)
at io.fabric.sdk.android.services.common.ApiKey.getValue(ApiKey.java:61)
at com.crashlytics.android.core.CrashlyticsCore.onPreExecute(CrashlyticsCore.java:219)
at com.crashlytics.android.core.CrashlyticsCore.onPreExecute(CrashlyticsCore.java:207)
at io.fabric.sdk.android.InitializationTask.onPreExecute(InitializationTask.java:44)
at io.fabric.sdk.android.services.concurrency.AsyncTask.executeOnExecutor(AsyncTask.java:611)
at io.fabric.sdk.android.services.concurrency.PriorityAsyncTask.executeOnExecutor(PriorityAsyncTask.java:43)
at io.fabric.sdk.android.Kit.initialize(Kit.java:69)
at io.fabric.sdk.android.Fabric.initializeKits(Fabric.java:440)
at io.fabric.sdk.android.Fabric.init(Fabric.java:384)
at io.fabric.sdk.android.Fabric.setFabric(Fabric.java:342)
at io.fabric.sdk.android.Fabric.with(Fabric.java:313)
at info.nightscout.android.UploaderApplication.onCreate(UploaderApplication.java:32)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1046)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5402)
at android.app.ActivityThread.-wrap2(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
09-26 12:38:20.202 6324-6379/info.nightscout.android E/Fabric: Error dealing with settings
java.lang.IllegalArgumentException: Fabric could not be initialized, API key missing from AndroidManifest.xml. Add the following tag to your Application element
<meta-data android:name="io.fabric.ApiKey" android:value="YOUR_API_KEY"/>
at io.fabric.sdk.android.services.common.ApiKey.logErrorOrThrowException(ApiKey.java:110)
at io.fabric.sdk.android.services.common.ApiKey.getValue(ApiKey.java:61)
at io.fabric.sdk.android.services.settings.Settings.initialize(Settings.java:78)
at io.fabric.sdk.android.Onboarding.retrieveSettingsData(Onboarding.java:124)
at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:99)
at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:45)
at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:63)
at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:28)
at io.fabric.sdk.android.services.concurrency.AsyncTask$2.call(AsyncTask.java:311)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
09-26 12:38:20.252 6324-6324/info.nightscout.android W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.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
09-26 12:38:20.349 6324-6324/info.nightscout.android I/MainActivity: onCreate called
09-26 12:38:20.652 6324-6324/info.nightscout.android D/AndroidRuntime: Shutting down VM
09-26 12:38:20.652 6324-6324/info.nightscout.android E/AndroidRuntime: FATAL EXCEPTION: main
Process: info.nightscout.android, PID: 6324
java.lang.RuntimeException: Unable to start activity ComponentInfo{info.nightscout.android/info.nightscout.android.medtronic.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2659)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at info.nightscout.android.medtronic.MainActivity.onCreate(MainActivity.java:349)
at android.app.Activity.performCreate(Activity.java:6672)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Move the code setContentView(R.layout.activity_main);
under the super.onCreate(savedInstanceState);
you are mapping the views before adding layout in your code.
your onCreate() should be
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Do mapping all views
Your Error log is showing you your solution. The project is using Fabric API. So naturally you need to add Fabric API key to your project.
Do as suggested in Error log. Add following line in Android Manifest.
<meta-data android:name="io.fabric.ApiKey" android:value="YOUR_API_KEY"/>
For your API key, make a project using Fabric account and get your API key.
I am using a JSON parser to read the data from my JSON file and display it within my app, I was originally using this code to create arrays which works fine but now I have pasted it into a new application to make it get data from the JSON and put it onto a text field which isn't working. I will post the code and error log below.
package com.example.curtisboylan.myapplication;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TechnicianProfile extends AppCompatActivity {
private static String url;
private String TAG = SearchScreen.class.getSimpleName();
private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_technician_profile);
Bundle bundle = getIntent().getExtras();
String username = bundle.getString("username");
String userid = bundle.getString("userid");
setTitle("Technician - " + username);
url = "http://curtisboylan.me/mygeek/mygeekprofile.php?user=" + userid;
Log.d("test", url);
new GetProfile().execute();
}
private class GetProfile extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(TechnicianProfile.this);
pDialog.setMessage("Please Wait..");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray contacts = jsonObj.getJSONArray("MyGeek");
TextView usernametext;
// looping through All Contacts
JSONObject c = contacts.getJSONObject(0);
usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
usernametext.setText(c.getString("name"));
// username.add(c.getString("name"));
// userid.add(c.getString("id"));
// location.add(c.getString("location"));
// reviewscore.add(c.getString("reviewscore"));
// price.add(c.getString("price"));
// urllist.add(c.getString("url"));
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
}
}
D/test: http://curtisboylan.me/mygeek/mygeekprofile.php?user=1
E/EGL_emulation: tid 2593: eglSurfaceAttrib(1174): error 0x3009
(EGL_BAD_MATCH) W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on
surface 0x91199f00, error=EGL_BAD_MATCH E/EGL_emulation: tid 2593:
eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer:
Failed to set EGL_SWAP_BEHAVIOR on surface 0x8f2f5000,
error=EGL_BAD_MATCH E/SearchScreen: Response from url:
{"MyGeek":[{"id":"1","name":"Curtis Boylan","location":"Swords, Co
Dublin","reviewscore":"5.6","url":"https://scontent-lhr3-1.xx.fbcdn.net/v/t1.0-9/11062691_831452480236559_1123476984274233173_n.jpg?oh=8eb4bb9519a2cd3b96b085146b0ae718&oe=596BBB5F","price":"30"}]}
--------- beginning of crash E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.example.curtisboylan.myapplication, PID: 2416
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6891)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1083)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5205)
at android.view.View.invalidateInternal(View.java:13656)
at android.view.View.invalidate(View.java:13620)
at android.view.View.invalidate(View.java:13604)
at android.widget.TextView.checkForRelayout(TextView.java:7347)
at android.widget.TextView.setText(TextView.java:4480)
at android.widget.TextView.setText(TextView.java:4337)
at android.widget.TextView.setText(TextView.java:4312)
at com.example.curtisboylan.myapplication.TechnicianProfile$GetProfile.doInBackground(TechnicianProfile.java:72)
at com.example.curtisboylan.myapplication.TechnicianProfile$GetProfile.doInBackground(TechnicianProfile.java:39)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761) E/EGL_emulation: tid 2593: eglSurfaceAttrib(1174): error 0x3009
(EGL_BAD_MATCH) W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on
surface 0x8f2f5080, error=EGL_BAD_MATCH E/WindowManager:
android.view.WindowLeaked: Activity
com.example.curtisboylan.myapplication.TechnicianProfile has leaked
window DecorView#415df5e[] that was originally added here
at android.view.ViewRootImpl.(ViewRootImpl.java:418)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:322)
at com.example.curtisboylan.myapplication.TechnicianProfile$GetProfile.onPreExecute(TechnicianProfile.java:48)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:620)
at android.os.AsyncTask.execute(AsyncTask.java:567)
at com.example.curtisboylan.myapplication.TechnicianProfile.onCreate(TechnicianProfile.java:36)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
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)
E/WindowManager: android.view.WindowLeaked: Activity
com.example.curtisboylan.myapplication.TechnicianListView has leaked
window DecorView#b6a1d55[] that was originally added here
at android.view.ViewRootImpl.(ViewRootImpl.java:418)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:322)
at com.example.curtisboylan.myapplication.TechnicianListView$GetContacts.onPreExecute(TechnicianListView.java:78)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:620)
at android.os.AsyncTask.execute(AsyncTask.java:567)
at com.example.curtisboylan.myapplication.TechnicianListView.initViews(TechnicianListView.java:67)
at com.example.curtisboylan.myapplication.TechnicianListView.onCreate(TechnicianListView.java:48)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
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)
You can not do any UI operation in doInBackground.
Put set text related stuff in onPostExecutemethod of AsyncTask
#Override
protected void onPostExecute(Void aVoid) {
}
remove UI component from doInBackground and update UI in postExecute method of Asynctask
You are trying to modify a View from a background thread.
View Android UI in not thread safe, and so can only be modified from the main thread.
The offence is this line in your doInBackground()
usernametext.setText(c.getString("name"));
Instead, you should return the found String from the doInBackground, override onPostExecute and set it there.
An other option is wrap is in a runOnUiThread() but honestly that's more complicated and unnecessary in this case.
You cannot use
usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
usernametext.setText(c.getString("name"));
from .doInbackground() method, because this method is executed on background thread, but UI elements can only be changed from a main thread.
Move UI update to .onPostExecute() method.
As the error suggest "Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException" you are doing wrong thing in wrong thread. Please move your setText code to onPostExecute.
You have to use publishProgress and onProgressUpdate.
package com.example.curtisboylan.myapplication;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TechnicianProfile extends AppCompatActivity {
private static String url;
private String TAG = SearchScreen.class.getSimpleName();
private ProgressDialog pDialog;
private TextView usernametext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_technician_profile);
usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
Bundle bundle = getIntent().getExtras();
String username = bundle.getString("username");
String userid = bundle.getString("userid");
setTitle("Technician - " + username);
url = "http://curtisboylan.me/mygeek/mygeekprofile.php?user=" + userid;
Log.d("test", url);
new GetProfile(usernametext).execute();
}
private class GetProfile extends AsyncTask<Void, String, Void> {
private TextView tv;
public GetProfile(TextView tv) {
this.tv = tv;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(TechnicianProfile.this);
pDialog.setMessage("Please Wait..");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray contacts = jsonObj.getJSONArray("MyGeek");
// looping through All Contacts
JSONObject c = contacts.getJSONObject(0);
String str = c.getString("name");
publishProgress(str);
// username.add(c.getString("name"));
// userid.add(c.getString("id"));
// location.add(c.getString("location"));
// reviewscore.add(c.getString("reviewscore"));
// price.add(c.getString("price"));
// urllist.add(c.getString("url"));
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
tv.setText(values[0]);
}
}
}
I want to upload images to fto using simple FTP. But it always failed to upload to FTP. The error always points to the ftp.connect. I don't know why. So I hope u can help me.
Upload.java
public class ImageUpdate extends AppCompatActivity {
private static final String TAG_ID = "id";
private static final String TAG_PESAN = "message";
private static final String TAG_HASIL = "result";
private static final String TAG_IMAGE_ID = "id_image";
private static final String TAG_IMAGE_NAME= "image_name";
ProgressDialog pDialog;
JSONParser jparser = new JSONParser();
ArrayList<HashMap<String, String>> namelist, idList, imageList;
JSONArray names, names1, names2;
private static int RESULT_LOAD_IMG = 1;
String imgDecodableString = null;
Button submit;
static final String FTP_HOST = "xxxxxxxxxx";
static final String FTP_USER = "xxxxxxxxxxxx";
static final String FTP_PASS = "xxxxxxxxxxx";
String name, vid;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client2;
SessionManagement session;
String nm,addr,pos,tlp,mail,usr,pass,id,image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_update);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
client2 = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
session =new SessionManagement(ImageUpdate.this);
HashMap<String, String> user = session.getUserDetails();
id=user.get(SessionManagement.KEY_ID);
nm=user.get(SessionManagement.KEY_NAME);
addr=user.get(SessionManagement.KEY_ALAMAT);
mail=user.get(SessionManagement.KEY_EMAIL);
tlp=user.get(SessionManagement.KEY_TELP);
usr=user.get(SessionManagement.KEY_USERNAME);
pass=user.get(SessionManagement.KEY_PASS);
submit=(Button) findViewById(R.id.buttonUploadPicture);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (imgDecodableString == null) {
Toast.makeText(ImageUpdate.this, "Choose image first, please", Toast.LENGTH_LONG);
} else {
File f = new File(imgDecodableString);
name = f.getName();
uploadFile(f);
}
}
});
}
public void loadImagefromGallery(View view) {
// Create intent to Open Image applications like Gallery, Google Photos
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Start the Intent
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
// When an Image is picked
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
&& null != data) {
// Get the Image from data
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
// Get the cursor
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filename = cursor.getString(columnIndex);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
File f = new File("" + imgDecodableString);
f.getName();
ImageView imgView = (ImageView) findViewById(R.id.imgView);
// Set the Image in ImageView after decoding the String
imgView.setImageBitmap(BitmapFactory
.decodeFile(imgDecodableString));
} else {
Toast.makeText(this, "Pilih Bukti Transaksi",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Failed to Choose", Toast.LENGTH_LONG)
.show();
}
}
public void uploadFile(File fileName) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
SimpleFTP ftp=new SimpleFTP();
try {
ftp.connect("xxxxxxx", 21, "xxxxxxxx", "xxxxxxx");
ftp.bin();
ftp.cwd("img/imageProfil/");
ftp.stor(fileName);
ftp.disconnect();
} catch (Exception e) {
e.printStackTrace();
try {
ftp.disconnect();
Toast.makeText(ImageUpdate.this, "disconnect", Toast.LENGTH_LONG).show();
} catch (Exception e2) {
e2.printStackTrace();
Toast.makeText(ImageUpdate.this, "failed", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client2.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Upload Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.amobi.newlomapodfix/http/host/path")
);
AppIndex.AppIndexApi.start(client2, viewAction);
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Upload Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.amobi.newlomapodfix/http/host/path")
);
AppIndex.AppIndexApi.end(client2, viewAction);
client2.disconnect();
}
}
stackTrace
06-20 22:32:00.692 2845-2845/com.amobi.newlomapodfix W/EGL_emulation: eglSurfaceAttrib not implemented
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: java.io.IOException: SimpleFTP received an unknown response when connecting to the FTP server: 220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at org.jibble.simpleftp.SimpleFTP.connect(SimpleFTP.java:74)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at com.amobi.newlomapodfix.UploadActivity.uploadFile(UploadActivity.java:167)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at com.amobi.newlomapodfix.UploadActivity$1.onClick(UploadActivity.java:100)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at android.view.View.performClick(View.java:4204)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at android.view.View$PerformClick.run(View.java:17355)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at android.os.Handler.handleCallback(Handler.java:725)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at android.os.Handler.dispatchMessage(Handler.java:92)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at android.os.Looper.loop(Looper.java:137)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5041)
06-20 22:32:04.900 2845-2845/com.amobi.newlomapodfix W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
06-20 22:32:04.904 2845-2845/com.amobi.newlomapodfix W/System.err: at java.lang.reflect.Method.invoke(Method.java:511)
06-20 22:32:04.908 2845-2845/com.amobi.newlomapodfix W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-20 22:32:04.912 2845-2845/com.amobi.newlomapodfix W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-20 22:32:04.912 2845-2845/com.amobi.newlomapodfix W/System.err: at dalvik.system.NativeStart.main(Native Method)
This answer explains a nonconform FTP specification in simple FTP, in fact, the server should start with 220 but this library gets an exception.
(https://stackoverflow.com/a/24386510/6093353).
This tutorial implements an easy FTP upload, try to follow this
http://androidexample.com/FTP_File_Upload_From_Sdcard_to_server/index.php?view=article_discription&aid=98