I am having a problem and I ran out of ideas how to fix it.
The goal is, when the user clicks the button an URL is loaded depending on what's selected in settings.
Problem is, I am having trouble setting it up in a right way.
Logically(to me), I tried to set it up in a service. Button is clicked > Service starts > URL is loaded from "IF ELSE". Problem is, I get an error in "IF ELSE" - "Method length must be called from the UI Thread, currently inferred thread is is worker.
public static class Service extends IntentService {
public Service() {
super("wallpaperchanger-download");
}
@Override
protected void onHandleIntent(Intent intent) {
MainActivity mainActivity;
mainActivity = new MainActivity();
if (mainActivity.mEditTextHashtag.length() > 2) {
WallpaperManager wm = WallpaperManager.getInstance(this);
int height = wm.getDesiredMinimumHeight();
int width = wm.getDesiredMinimumWidth();
String url = "https://source.unsplash.com/all/?" + mainActivity.mEditTextHashtag.getText() + "/" + width + "x" + height + "/";
try {
InputStream input = new URL(url).openStream();
Log.v(TAG, url);
wm.setStream(input);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
loading = false;
}
}
}
Ok, fair enough. I created new Method getPhoto(); in UI Thread and put the code in there. Then, I called mainActivity.getPhoto(); in Service. Problem is, I get an error - "Attempt to invoke virtual method 'int android.widget.EditText.length()' on a null object reference"
Any ideas on what I should do?
Full code in all its glory:
package com.edip.splashwallpaper;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.Toast;
import java.io.InputStream;
import java.net.URL;
public class MainActivity extends android.app.Activity {
final static String TAG = "AllInOne";
final static int CHANGE_INTERVAL = 30 * 1000; //30 sec for testing
static boolean loading = false;
WallpaperManager wm;
//Layout Views
Switch mSwitchFixedPhoto, mSwitchControls, mSwitchSave, mSwitchPause;
Spinner mSpinnerCategories, mSpinnerInterval;
EditText mEditTextHashtag;
Button mWallpaperButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Layout Views Initialized
mSwitchFixedPhoto = (Switch) findViewById(R.id.sw_fixedphoto);
mSwitchControls = (Switch) findViewById(R.id.switch_controls);
mSwitchSave = (Switch) findViewById(R.id.switch_save);
mSwitchPause = (Switch) findViewById(R.id.switch_pause);
mSpinnerCategories = (Spinner) findViewById(R.id.spinner_categories);
mSpinnerInterval = (Spinner) findViewById(R.id.spinner_interval);
mEditTextHashtag = (EditText) findViewById(R.id.et_hashtag);
mWallpaperButton = (Button) findViewById(R.id.btn_set_wallpaper);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapterCategory = ArrayAdapter.createFromResource(this,
R.array.categories_array, R.layout.dialog_spinner_layout);
// Specify the layout to use when the list of choices appears
adapterCategory.setDropDownViewResource(R.layout.dialog_spinner_layout);
// Apply the adapter to the spinner
mSpinnerCategories.setAdapter(adapterCategory);
ArrayAdapter<CharSequence> adapterInterval = ArrayAdapter.createFromResource(this,
R.array.interval_array, R.layout.dialog_spinner_layout);
adapterInterval.setDropDownViewResource(R.layout.dialog_spinner_layout);
mSpinnerInterval.setAdapter(adapterInterval);
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PendingIntent pending = PendingIntent.getBroadcast(MainActivity.this,
666, new Intent("com.edip.splashwallpaper.CHANGE_WALLPAPTER_TIMER"),
PendingIntent.FLAG_CANCEL_CURRENT);
((AlarmManager) getSystemService(Context.ALARM_SERVICE))
.setRepeating(AlarmManager.RTC, System.currentTimeMillis(),
CHANGE_INTERVAL, pending);
}
});
}
public void getPhoto() {
if (mEditTextHashtag.length() > 2) {
wm = WallpaperManager.getInstance(this);
int height = wm.getDesiredMinimumHeight();
int width = wm.getDesiredMinimumWidth();
String url = "https://source.unsplash.com/all/?" + mEditTextHashtag.getText() + "/" + width + "x" + height + "/";
try {
InputStream input = new URL(url).openStream();
Log.v(TAG, url);
wm.setStream(input);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
loading = false;
} else {
Toast.makeText(this, "Something else", Toast.LENGTH_SHORT).show();
}
}
public static class Service extends IntentService {
public Service() {
super("wallpaperchanger-download");
}
@Override
protected void onHandleIntent(Intent intent) {
MainActivity mainActivity;
mainActivity = new MainActivity();
mainActivity.getPhoto();
}
}
public static class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
if (!loading) {
loading = true;
context.startService(new Intent(context, Service.class));
}
}
}
}
Thanks :)
First of all, you should never instantiate an activity by yourself.
Second, as a best practice, your service shouldn't know about your activity, or that it has an edit text. Instead you should send the URL to load inside your intent, when the PendingIntent is created, like this :
Intent intent = new Intent("com.edip.splashwallpaper.CHANGE_WALLPAPTER_TIMER");
intent.putExtra("USER_URL", "https://source.unsplash.com/all/?" + mEditTextHashtag.getText() + "/" + width + "x" + height + "/");
PendingIntent pending = PendingIntent.getBroadcast(MainActivity.this,
666, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Then within your service, read the url like so :
@Override
protected void onHandleIntent(Intent intent) {
String url = intent.getStringExtra("USER_URL");
// ...
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments