How to give a user the option to select bsckground of a linearlayout from DxsettingsActivity that targets the MainActivity? - select

I want the user to be able to go into settings of my app and select from the images provided or select a photo from their internal or external storage to be applied to the background of the MainActivity. Also I want this image to stay even after the app has been killed until the user decides to change the background again. I have tried multiple codes and I run into errors every time and the main problem I'm having is sending this intent from one Activity to another. I have used code that allow me to apply an image to an ImageView within the same Activity but I cannot take that code and get it to send across to another Activity.
Targets:
LinearLayout - backgroundtop (MainActivity)
Imageview(onClick) - gallery (DxsettingsActivity)
Imageview(onClick) - dx (DxsettingsActivity)
"Gallery" and "dx" are in a customview dialog.
When "gallery" is clicked internal/external storage is opened to select background resource of "backgroundtop" and save that image until user changes it again.
When "dx" is clicked it opens DxWallpaperActivity which will have the images to be selected and saved as the background of "backgroundtop".
I hope I have explain well enough. I'll provide more info if needed. Thank you in advance. I have been struggling with this for days to no avail.
Update: I have managed to accomplish setting and saving images from in-app images to the background. I have tried everything under the sun to pull image from gallery and do the same. I have managed to open gallery and select an image but I can't figure out onActivityResult then send that to the background. Please help.
This is the only code I've got to work but it doesn't have shared preferences and it for an imageview. How can I change it for backgroundresource on linearlayout?
}
private static final String STATE_IMAGE_URI =
"STATE_IMAGE_URI";
private Uri imageUri;
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
if (imageUri != null ) {
state.putParcelable(STATE_IMAGE_URI, imageUri);
}
}
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
if(state == null || !state.containsKey(STATE_IMAGE_URI))
return;
setImage((Uri) state.getParcelable(STATE_IMAGE_URI));
}
private static final int IMAGE_REQUEST_CODE = 9;
private void chooseImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select picture"), IMAGE_REQUEST_CODE);
}
public void onActivityResult(int requestCode, int.
resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != IMAGE_REQUEST_CODE) {
return;
}
if (resultCode != Activity.RESULT_OK) {
return;
}
setImage(data.getData());
}
private void setImage(Uri uri) {
imageUri = uri;
imageview1.setImageURI(uri);
}
private void nothing() {
And for the button clicked
chooseImage();

Related

Zxing barcode scanner continious scanning problem

I'm using Zxing barcode scanner and Rg Pop up pages in Xamarin forms. The whole idea is that when the camera catches a barcode it displays a pop up. The problem is that I want to wait for the user to close the pop up before it scans again. Now if I keep the camera towards a barcode it keeps showing multiple alerts.
public async void Scan(Result result)
{
//random linq to get product
if (product != null)
{
await PopupNavigation.PushAsync(new DisplayDialog(product));
}
}
Method for when user closes the window
private async void Button_OnClicked(object sender, EventArgs e)
{
await PopupNavigation.RemovePageAsync(this);
}
I tried using a flag to stop the scan and setting isScanning or isAnalyzing to false but it didnt work. Any ideas? Thank you!
use a bool to control the flow
bool popup = false;
public async void Scan(Result result)
{
if (popup) return;
//random linq to get product
if (product != null)
{
popup = true;
await PopupNavigation.PushAsync(new DisplayDialog(product));
}
}
then whenever your popup is dismissed, reset the popup flag to false

What is the right usage for the SingleSelectionModel?

we would like to link from a CellTable to a property editor page. We use the SingleSelectionModel to get notified, when a user clicks on an item.
It is initialized like this:
private final SingleSelectionModel<Device> selectionModel = new SingleSelectionModel<Device>();
We then assign the selection change handler:
selectionModel.addSelectionChangeHandler(this);
Our selection change handler looks like this:
#Override
public void onSelectionChange(SelectionChangeEvent event) {
Log.debug("DevicesPresenter: SelectionChangeEvent caught.");
Device selectedDevice = selectionModel.getSelectedObject();
if (selectedDevice != null) {
selectionModel.clear();
if (selectionModel.getSelectedObject() != null){
Log.debug("DevicesPresenter: selected item is " + selectionModel.getSelectedObject());
}
else{
Log.debug("DevicesPresenter: selected item is null");
}
deviceEditorDialog.setCurrentDevice(selectedDevice.getUuid());
// get the container data for this device
clientModelProvider.fetchContainersForDevice(selectedDevice.getUuid());
PlaceRequest request = new PlaceRequest.Builder()
.nameToken(NameTokens.deviceInfo)
.with("uuid", selectedDevice.getUuid())
.build();
Log.debug("Navigating to " + request.toString());
placeManager.revealPlace(request);
}
}
Now there are two issues: There always seem to be two SelectionChangeEvents at once and i really cannot see why. The other thing is: How is the right way do handle selection of items and the related clearing of the selection model? Do we do that the right way?
Thanks!
If you only want to get notified of "clicks" without keeping the "clicked" item selected, use a NoSelectionModel instead; no need to clear the selection model as soon as something is selected.
As for your other issue with being called twice, double-check that you haven't added your selection handler twice (if you can unit-test your DevicesPresenter, introspect the handlers inside the selection model for example)
In your line selectionModel.addSelectionChangeHandler(this); what does this refer?
Here my code how I use SingleSelectionModel
public class MyClass{
private final SingleSelectionModel<CountryDto> selectionModel = new SingleSelectionModel<CountryDto>();
...
public MyClass(){
cellTable.setSelectionModel(selectionModel);
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
#Override
public void onSelectionChange(SelectionChangeEvent event) {
CountryDto selected = selectionModel
.getSelectedObject();
if (selected != null) {
Window.alert("Selected country "+selected.getTitle());
}
}
});
}
}

Espresso and Android contact picker

I try to add a contact with an Android contact picker by Espresso, but this does not work.
This is the command to invoke the contact picker:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, RC_PICK_CONTACT);
The contact picker is shown, when I run Espresso test. OK, now I try to select a specific contact entry by display name (e.g. "Jake"). Unfortunately I don't know how to accomplish this. I've tried the following:
onData(withItemContent("Jake")).inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView())))).perform(click());
I also tried this variation:
onView(withText("Jake")).inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView())))).perform(click());
No success with both approaches. As already mentioned the contact picker is shown, but nothing is selected.
Any idea?
What you're experiencing is normal behavior, since the contact picker belongs to an external activity, whose user interface cannot be manipulated. Trying to assert anything will result in the tests stalling for some time and ending up with a
android.support.test.espresso.NoActivityResumedException: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)?
However, say hello to the new born Espresso-Intents, which is here to save my reputation:
Using the intending API (cousin of Mockito.when), you can provide a
response for activities that are launched with startActivityForResult
UPDATE
Below is my current solution which works fine but would need some decent code clean up:
#Test
public void testContactPickerResult(){
Intent resultData = new Intent();
resultData.setData(getContactUriByName("Joah"));
Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
intending(toPackage("com.google.android.contacts")).respondWith(result);
onView(withId(R.id.contactPickerLauncher))
.check(matches(isDisplayed()))
.perform(click());
onView(withId(R.id.pickedContact))
.check(matches(withText(getContactNumberByName("Joah"))));
}
In the launching activity, I would handle the incoming intent with the contact Uri and do whatever is necessary with it.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
TextView result = (TextView) findViewById(R.id.pickedContact);
if (requestCode == 42 && resultCode == RESULT_OK){
Uri contactUri = data.getData();
String[] projection = {ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
cursor.moveToFirst();
int column = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String number = cursor.getString(column);
result.setText(number);
}
}
Also, the helper methods, to be modified accordingly:
public Uri getContactUriByName(String contactName) {
Cursor cursor = mActivityRule.getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
if (name.equals(contactName)) {
return Uri.withAppendedPath(ContactsContract.Data.CONTENT_URI, id);
}
}
}
return null;
}

Android Activity and Service communication: how to keep the UI up-to-date

I have an Activity A (not the main Activity) that launches a Service S that does some stuff in the background and, in the meanwhile, should made some changes to the UI of A.
Let's just say that S count from 0 to 100 and A should display this count in Real-Time. Since the real job of S is quite more complicated and CPU-consuming, I do not want to use AsyncTask for it (indeed "AsyncTasks should ideally be used for short operations (a few seconds at the most.) [...]") but just a regular Service started in a new Thread (an IntentService would be fine as well).
This is my Activity A:
public class A extends Activity {
private static final String TAG = "Activity";
private TextView countTextView; // TextView that shows the number
Button startButton; // Button to start the count
BResultReceiver resultReceiver;
/**
* Receive the result from the Service B.
*/
class BResultReceiver extends ResultReceiver {
public BResultReceiver(Handler handler) {
super(handler);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
switch ( resultCode ) {
case B.RESULT_CODE_COUNT:
String curCount = resultData.getString(B.RESULT_KEY_COUNT);
Log.d(TAG, "ResultReceived: " + curCount + "\n");
runOnUiThread( new UpdateUI(curCount) ); // NOT WORKING AFTER onResume()!!!
break;
}
}
}
/**
* Runnable class to update the UI.
*/
class UpdateUI implements Runnable {
String updateString;
public UpdateUI(String updateString) {
this.updateString = updateString;
}
public void run() {
countTextView.setText(updateString);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.counter);
countTextView = (TextView) findViewById(R.id.countTextView);
startButton = (Button) findViewById(R.id.startButton);
resultReceiver = new BResultReceiver(null);
}
public void startCounting(View view) {
startButton.setEnabled(false);
//Start the B Service:
Intent intent = new Intent(this, B.class);
intent.putExtra("receiver", resultReceiver);
startService(intent);
}
}
And this is my Service B:
public class B extends Service {
private static final String TAG = "Service";
private Looper serviceLooper;
private ServiceHandler serviceHandler;
private ResultReceiver resultReceiver;
private Integer count;
static final int RESULT_CODE_COUNT = 100;
static final String RESULT_KEY_COUNT = "Count";
/**
* Handler that receives messages from the thread.
*/
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
while ( count < 100 ) {
count++;
//Sleep...
sendMessageToActivity(RESULT_CODE_COUNT, RESULT_KEY_COUNT, count.toString());
}
//Stop the service (using the startId to avoid stopping the service in the middle of handling another job...):
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
//Start up the thread running the service:
HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
this.count = 0;
//Get the HandlerThread's Looper and use it for our Handler
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.resultReceiver = intent.getParcelableExtra("receiver");
//For each start request, send a message to start a job and deliver the start ID so we know which request we're stopping when we finish the job:
Message msg = serviceHandler.obtainMessage();
msg.arg1 = startId;
serviceHandler.sendMessage(msg);
//If we get killed, after returning from here, restart:
return START_REDELIVER_INTENT;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* Send a message from to the activity.
*/
protected void sendMessageToActivity(Integer code, String name, String text) {
Bundle bundle = new Bundle();
bundle.putString(name, text);
//Send the message:
resultReceiver.send(code, bundle);
}
}
Everything works fine but if I click the back button (or the home button) and then I re-open the Activity A then the UI of A is not updated anymore (it just shows the initial configuration of A - i.e. the "startButton" is still clickable and the count is not showed - it seems runOnUiThread(...) is not working anymore). However, the Service B is still running in the background and the I can see the correct count is passed to the Activity A in the Log.d(...). Finally, if I click on the "startButton" again, the counting does not start from the beginning (0) but from where B has been arrived (I've double checked it by showing it in the notification bar).
How can I fix this behaviour? I would like that, when I re-open the Activity A, it automatically continues to receive and update the data from the Service B. Or, in other words, that the Service keeps the UI of the Activity A up-to-date.
Please give me some hints, links or piece of code. Thanks!
When you click back button your Activity is destroyed. When you start the Activity again you get a new Activity. That also happen when you rotate the device. This is Android lifecycle event
The Activity is not good for heavy Business Logic only to show stuff/control stuf.
What you have to do is create a simple MVC, Model View Controller. The view (Activity) should only be used for showing results and controlling the eventflow.
The Service can hold an Array of the count and when your Activity start it will onBind() your Service that is running (or if not running will start the Service since you bind to it) Let the Activity(View) get the Array of results and show it. This simple setup exclude the (M)Model Business Logic.
Update
Following up a bit read this it's Android official docs and perfect start since it do kind of what you asking. As you see in the example in the onStart() the Activity establish a connection with the service and in the onStop() the connection is removed. There's no point having a connection after on onStop(). Just like you asking for. I would go with this setup and not let the Service continuously sending data because that would drain resources and the Activity is not always listening because it will stop when in the background.
Here's an activity that binds to LocalService and calls getRandomNumber() when a button is clicked:

onActivityResult() not getting executed in DialogFragment

I have been looking in thousand posts for this, but I do not find how to solve my problem.
I have an ImageView. When the user clicks on this ImageView, a DialogFragment is displayed, and the user can choose between taking a new picture with the camera, or selecting a picture from the gallery. Until here everything works fine.
The problem is, that the picture selected by the user, should replace the current one in the ImageView, but this bit, is the one that is not working, because the onActivityResult() function that executes this code is not being executed, so the image in the ImageView always remains the same. I would appreciate any help, because I do not see or understand, why this code is not being executed.
I am getting a warning in the LogCat right after the user selects the image:
05-07 12:17:11.542: I/ActivityManager(59): Displayed activity com.android.gallery/com.android.camera.ImageGallery: 935 ms (total 935 ms)
05-07 12:17:12.812: W/FragmentActivity(3614): Activity result no fragment exists for index: 0x10001
05-07 12:17:12.862: W/InputManagerService(59): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy#45fd9c38 (uid=10016 pid=317)
Activity.java:
private ImageView imageLoader = null;
imageLoader = (ImageView) findViewById(R.id.f_imageLoader);
imageLoader.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
ImageLoaderDialog imageLoaderDialog = new ImageLoaderDialog(imageLoader);
imageLoaderDialog.show(getSupportFragmentManager(), "imageLoaderDialog");
}
Activity.xml:
<ImageView
android:id="#+id/f_imageLoader"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="0.20"
android:contentDescription="#string/imgDesc"
android:src="#drawable/my_image" />
ImageLoaderDialog.java:
//Dialog for choosing between new camera image or gallery image.
public class ImageLoaderDialog extends android.support.v4.app.DialogFragment {
private ImageView targetImageView = null;
final int TAKE_PICTURE = 0;
final int PICK_PHOTO = 1;
public ImageLoaderDialog (View view) {
targetImageView = (ImageView) view;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Selecciona");
final String[] imageSources = getResources().getStringArray(R.array.imageSources);
builder.setItems(imageSources, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch(item) {
case TAKE_PICTURE:
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, TAKE_PICTURE);
break;
case PICK_PHOTO:
Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto, PICK_PHOTO);
break;
}
}
});
return builder.create();
}
//Set image to user's selected image.
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == android.app.Activity.RESULT_OK) {
Uri selectedImage = intent.getData();
Log.i("IMAGEN", ""+selectedImage);
targetImageView.setImageURI(selectedImage);
}
}
}
Any help would be very appreciated.
The hosting activity overrode the onActivityResult but did not make a call to super.onActivityResult for unhandled result codes. Apparently even though the fragment is the one making the startActivityForResult call, the activity gets the first shot at handling the result. This makes sense when you consider the modularity of fragments. Once I implemented super.onActivityResult for all unhandled results, the fragment got a shot at handling the result.Try This:
getActivity().onActivityResult(requestCode, resultCode, intent);