Categories
discuss

Module not specified?

I have recently started learning android development, and I just built an app that changes color and text based on pushing buttons and gestures. It ran fine on my phone (Yay!), but then on my second run, an error occurred. When hitting the “run” button, an edit configurations window opened up:

enter image description here

I also noticed, that on the side where my project tree should be is this instead:

enter image description here

I don’t think there is an issue in the code because it was running fine before, but I would be happy to post the code if needed.

Also

I dont know if this was the reason, but i’ll include this anyway, I tried changing the name of my project, but it wouldn’t work, but I changed it back. I included this in my question because that’s literally the only thing I did before this error occured.

Thank you so much for helping out a fellow programmer, I really appreciate it. I have been looking at many other forums (for some hours) about this topic, but still couldn’t trouble shoot this problem. It seems kind of odd that it was working first, and then it just randomly stopped working. I cant wait for your response!

Here is the dropdown for Module:
enter image description here
As you can see, that is the only option.

Answer

Are you sure you are opening the project as android gradle project ?
Try to import the program not open it

Categories
discuss

Android ImageView.setMatrix() and .invalidate() – repainting takes too much time

Task: I want to resize and move an image across the screen. I want to do this smoothly no matter how big the image is. The code should be supported by the API level 8.

Problem: I tried to use ImageView with scaleType="matrix". Calling ImageView.setMatrix() and then ImageView.invalidate() works great with small images but horrible with big ones. No matter how big the ImageView is.

Can I somehow speed up repainting of the ImageView so it will not recalculate whole image? Maybe there is a way to accomplish the task using different component?


EDIT: More information on what I am trying to achieve.

  • pw, ph – width and height of the picture (in pixels)
  • dw, dh – width and height of the device’s display (in pixels)
  • fw, fh – width and height of the visible frame (in pixels)
  • x, y – position of top left corner of the frame (in pixels) Visualisation of the problem.

I want to display a part of the image on the screen. Properties x, y, fw and fh are changing constantly. I am looking for a part of code (idea), or components which for these 8 specified variables will quickly generate and display the part of the image.


EDIT 2: Info on pw and ph

I assume pw and ph can hold values from 1 to infinity. If this approach causes a lot of trouble we can assume the picture is not bigger than the picture taken with the device’s camera.

Answer

With your help (community) I figured out the solution. I am sure that there are other better ways to do it but my solution is not very complicated and should work with any image, any Android since API level 8.

The solution is to use two ImageView objects instead of one.

The first ImageView will be working like before but loaded image will be scaled down so that it’s width will be smaller than the width of the ImageView and it’s height will be smaller than the height of the ImageView.

The second ImageView will be blank at the start. Everytime the x, y, fw and fh properties are changing the AsyncTask will be executed to load only visible part of the image. When properties are changing fast the AsyncTask will not be able to finish in time. It will have to be canceled and new one will be started. When it finishes the result Bitmap will be loaded onto the second ImageView so it will be visible to user. When the properties changes again loaded Bitmap will be deleted, so it will not cover moving Bitmap loaded to the first ImageView. Note: BitmapRegionDecoder which I will use to load sub-image is available since Android API level 10, so API 8 and API 9 users will only see scaled down image. I decided it is OK.


Code needed:

  • Setting the first (bottom) ImageView scaleType="matrix" (best in XML)
  • Setting the second (top) ImageView scaleType="fitXY" (best in XML)
  • Functions from Android Documentation (here) – thanks to user Vishavjeet Singh.

NOTE: Notice the || operator instead of && while calculating inSampleSize. We want the image loaded to be smaller than ImageView so that we are sure we have enough RAM to load it. (I presume ImageView size is not bigger than the size of the device display. I also presume that the device has enough memory to load at least 2 Bitmaps of the size of the device display. Please tell me if I am making a mistake here.)
NOTE 2: I am loading images using InputStream. To load a file different way you will have to change code in try{...} catch(...){...} blocks.

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                || (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

public Bitmap decodeSampledBitmapFromResource(Uri fileUri,
                                              int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;

    try {
        InputStream is = this.getContentResolver().openInputStream(fileUri);
        BitmapFactory.decodeStream(is, null, options);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    try {
        InputStream is = this.getContentResolver().openInputStream(fileUri);
        return BitmapFactory.decodeStream(is, null, options);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}
  • Function returning a sub-image of an image.

NOTE: Size of Rectangle that will be cut out of source image is relative to the image. Values that specify it are from 0 to 1 because the size of the ImageView and loaded Bitmaps differs from the size of the original image.

public Bitmap getCroppedBitmap (Uri fileUri, int outWidth, int outHeight,
                                    double rl, double rt, double rr, double rb) {
        // rl, rt, rr, rb are relative (values from 0 to 1) to the size of the image.
        // That is because image moving will be smaller than the original.
        if (Build.VERSION.SDK_INT >= 10) {
            // Ensure that device supports at least API level 10
            // so we can use BitmapRegionDecoder
            BitmapRegionDecoder brd;
            try {
                // Again loading from URI. Change the code so it suits yours.
                InputStream is = this.getContentResolver().openInputStream(fileUri);
                brd = BitmapRegionDecoder.newInstance(is, true);

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.outWidth = (int)((rr - rl) * brd.getWidth());
                options.outHeight = (int)((rb - rt) * brd.getHeight());
                options.inSampleSize = calculateInSampleSize(options,
                        outWidth, outHeight);

                return brd.decodeRegion(new Rect(
                        (int) (rl * brd.getWidth()),
                        (int) (rt * brd.getHeight()),
                        (int) (rr * brd.getWidth()),
                        (int) (rb * brd.getHeight())
                ), options);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        else
            return null;
    }
  • AsyncTask loading the sub-image Bitmap.

NOTE: notice declaring a variable of the type of this class. It will be used later.

private LoadHiResImageTask loadHiResImageTask = new LoadHiResImageTask();

private class LoadHiResImageTask extends AsyncTask<Double, Void, Bitmap> {
        /** The system calls this to perform work in a worker thread and
         * delivers it the parameters given to AsyncTask.execute() */
        protected Bitmap doInBackground(Double... numbers) {
            return getCroppedBitmap(
                    // You will have to change first parameter here!
                    Uri.parse(imagesToCrop[0]),
                    numbers[0].intValue(), numbers[1].intValue(),
                    numbers[2], numbers[3], numbers[4], numbers[5]);
        }

        /** The system calls this to perform work in the UI thread and delivers
         * the result from doInBackground() */
        protected void onPostExecute(Bitmap result) {
            ImageView hiresImage = (ImageView) findViewById(R.id.hiresImage);
            hiresImage.setImageBitmap(result);
            hiresImage.postInvalidate();
        }
    }
  • Function that will make it all work together.

This function will be called every time the x, y, fw or fh property changes.
NOTE: hiresImage in my code is the id of the second (top) ImageView

private void updateImageView () {
        //  ... your code to update ImageView matrix ...
        // 
        // imageToCrop.setImageMatrix(m);
        // imageToCrop.postInvalidateDelayed(10);

        if (Build.VERSION.SDK_INT >= 10) {
            ImageView hiresImage = (ImageView) findViewById(R.id.hiresImage);
            hiresImage.setImageDrawable(null);
            hiresImage.invalidate();
            if (loadHiResImageTask.getStatus() != AsyncTask.Status.FINISHED) {
                loadHiResImageTask.cancel(true);
            }
            loadHiResImageTask = null;
            loadHiResImageTask = new LoadHiResImageTask();
            loadHiResImageTask.execute(
                    (double) hiresImage.getWidth(),
                    (double) hiresImage.getHeight(),
                    // x, y, fw, fh are properties from the question
                    (double) x / d.getIntrinsicWidth(),
                    (double) y / d.getIntrinsicHeight(),
                    (double) x / d.getIntrinsicWidth()
                            + fw / d.getIntrinsicWidth(),
                    (double) y / d.getIntrinsicHeight()
                            + fh / d.getIntrinsicHeight());
        }
    }
Categories
discuss

Javascript ES6 – map multiple arrays

Is there a feature in JavaScript 6 that allows to map over multiple arrays ?

Something like a zipper :

 var myFn = function (a, b) { console.log(a, b);}
  var arr1 = ['a', 'b', 'c'];
  var arr2 = [1, 2, 3];

  arr1.map(myFn, arr2); // imaginary syntax.
  // prints :
  // a 1
  // b 2
  // c 3

Answer

Unfortunately, no. What you are looking for is commonly called zip or zipWith. See lodash’s implementation for a reference: https://lodash.com/docs#zipWith

Categories
discuss

ACCESS_FINE_LOCATION permission

I’m litte ashamed. But cant find what’s wrong.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.szymon.gpslab1"
android:versionCode="15"
android:versionName="4.0.3">

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
</manifest>

It’s my manifest. and here’s my code:

public class MainActivity extends AppCompatActivity {
LocationManager locationManager;
LocationListener locationListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationListener = new MyLocationListener();

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
private class MyLocationListener implements LocationListener{

    @Override
    public void onLocationChanged(Location location) {
        System.out.println("ZMIENIAMY SIĘ, zmieniamy siebie");
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}
}

Im using the newest android studio (intellij) with embedded (?) emulator. Phone is out of options. ANd here what i’ve got:

FATAL EXCEPTION: main  
Process: com.example.szymon.gpslab1, PID: 3274  
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.szymon.gpslab1/com.example.szymon.gpslab1.MainActivity}: java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.  

Caused by: java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.  

I belive this is stupid mistake, but I’ve never like developed for android, im the javaman, and i’ve reached every tutorial on net, cant find answer.

Ah and y, I have location on in my emulator.

Answer

This is a common exception if your target SDK is 23 in your build.gradle.

Android 6.0 / sdk 23 introduces a new way of requesting permissions.

See the link below for how to handle permissions:

https://developer.android.com/training/permissions/index.html

Categories
discuss

Angular $resource recursive query

From the API I’m working on I need to take 2 different lists and I need to take in chunks of 20 items to avoid server timeouts.

What I built actually is this:

Items1.query().$promise
.then(function (data) {
  $scope.items1 = data.list;
  return Items2.query().$promise;
})
.then(function (data) {
  $scope.items2 = data.list;
});

With this code I’m downloading the entire list of objects.

Both the query return:

{
    list: [...],
    next: true,
    limit: 20,
    last: 20
}

Basically it is a pagination system.

Both services are like this:

App.factory('Items1', ['$resource',
    function($resource) {
        return $resource('items1/:item1Id', { storeId: '@id'
        }, {
            query: {
                method: 'GET',
                isArray: false
            },
            update: {
                method: 'PUT'
            }
        });
    }
]);

I don’t really know how to make recursive function with $resource in order to push those items in chunks of 20.

Answer

I wrote an example jsfiddle to show recursive promises. Converting it for your example, it would looks something like:

function getList(resource, list, last) {
    return resource.query({last: last}).$promise.then(function(data){
        list = list.concat(data.list);
        if (data.next) {
            return getList(resource, list, data.last);
        }
        return list;
    });
}

getList(Items1, [], 0).$promise.then(function(list) {
    $scope.items1 = list;
});
getList(Items2, [], 0).$promise.then(function(list) {
    $scope.items2 = list;
});

You would need to modify your angular resources to allow you to pass the last parameter in the API call. I’m assuming that the API, if provided with that parameter, will return the next section starting from it.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..