#StackBounty: #java #android #printing #wifi-direct ANDROID -How to print a text file using WiFi Direct

Bounty: 100

I have a working Android app that displays user stats. I want to send a small report with plain text format (.txt) to a WiFi Direct printer. I have downloaded the sample demo app from Android. I did the proper modification in order to look for .txt file. But I don’t understand why my code is not working. After selecting the file I want to print, nothing happens.

The current configuration for my EPSON printer bellow.

  • Wi-Fi Direct Mode : On

  • Communication Mode: AP

  • Operation Mode: IEEE802.11g/n

  • Communication Speed: Auto

  • SSID: DIRECT-D3A36C54
  • Channel: 7
  • Security Level: WPA2-PSK(AES)

  • Link Status: Unknown

This is the DeviceDetailFragment class

public class DeviceDetailFragment extends Fragment implements WifiP2pManager.ConnectionInfoListener {
    protected static final int CHOOSE_FILE_RESULT_CODE = 20;
    private View mContentView = null;
    private WifiP2pDevice device;
    private WifiP2pInfo info;
    ProgressDialog progressDialog = null;
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContentView = inflater.inflate(R.layout.device_detail, null);
        mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WifiP2pConfig config = new WifiP2pConfig();
                config.deviceAddress = device.deviceAddress;
                config.wps.setup = WpsInfo.LABEL;
                config.wps.pin = "12345677";
//                config.groupOwnerIntent = 15;
                if (progressDialog != null && progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }
                progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
                        "Connecting to :" + device.deviceAddress, true, true
//                        new DialogInterface.OnCancelListener() {
//
//                            @Override
//                            public void onCancel(DialogInterface dialog) {
//                                ((DeviceActionListener) getActivity()).cancelDisconnect();
//                            }
//                        }
                );
                ((DeviceListFragment.DeviceActionListener) getActivity()).connect(config);
            }
        });
        mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        ((DeviceListFragment.DeviceActionListener) getActivity()).disconnect();
                    }
                });
        mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Allow user to pick a text file from storage or other
                        // registered apps
                        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                        intent.setType("text/*");
//                        intent.setType("image/*");
                        startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
                    }
                });
        return mContentView;
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // User has picked a text file. Transfer it to group owner i.e peer using
        // FileTransferService.
        Uri uri = data.getData();
        TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
        statusText.setText("Sending: " + uri);
        Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
        Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
        serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
        serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
                info.groupOwnerAddress.getHostAddress());
        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8315); //631
        getActivity().startService(serviceIntent);
    }
    @Override
    public void onConnectionInfoAvailable(final WifiP2pInfo info) {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
        this.info = info;
        this.getView().setVisibility(View.VISIBLE);
        // The owner IP is now known.
        TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
        view.setText(getResources().getString(R.string.group_owner_text)
                + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
                : getResources().getString(R.string.no)));
        // InetAddress from WifiP2pInfo struct.
        view = (TextView) mContentView.findViewById(R.id.device_info);
        view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
        // After the group negotiation, we assign the group owner as the file
        // server. The file server is single threaded, single connection server
        // socket.
        if (info.groupFormed && info.isGroupOwner) {
            new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
                    .execute();
        } else if (info.groupFormed) {
            // The other device acts as the client. In this case, we enable the
            // get file button.
            mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
            ((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
                    .getString(R.string.client_text));
        }
        // hide the connect button
        mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
    }
    /**
     * Updates the UI with device data
     *
     * @param device the device to be displayed
     */
    public void showDetails(WifiP2pDevice device) {
        this.device = device;
        this.getView().setVisibility(View.VISIBLE);
        TextView view = (TextView) mContentView.findViewById(R.id.device_address);
        view.setText(device.deviceAddress);
        view = (TextView) mContentView.findViewById(R.id.device_info);
        view.setText(device.toString());
    }
    /**
     * Clears the UI fields after a disconnect or direct mode disable operation.
     */
    public void resetViews() {
        mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
        TextView view = (TextView) mContentView.findViewById(R.id.device_address);
        view.setText(R.string.empty);
        view = (TextView) mContentView.findViewById(R.id.device_info);
        view.setText(R.string.empty);
        view = (TextView) mContentView.findViewById(R.id.group_owner);
        view.setText(R.string.empty);
        view = (TextView) mContentView.findViewById(R.id.status_text);
        view.setText(R.string.empty);
        mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
        this.getView().setVisibility(View.GONE);
    }
    /**
     * A simple server socket that accepts connection and writes some data on
     * the stream.
     */
    public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
        private Context context;
        private TextView statusText;
        /**
         * @param context
         * @param statusText
         */
        public FileServerAsyncTask(Context context, View statusText) {
            this.context = context;
            this.statusText = (TextView) statusText;
        }
        @Override
        protected String doInBackground(Void... params) {
            try {
                ServerSocket serverSocket = new ServerSocket(8315); //631
                Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
                Socket client = serverSocket.accept();

                Log.d(WiFiDirectActivity.TAG, "Server: connection done");
//                final File f = new File(Environment.getExternalStorageDirectory() + "/"
//                        + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
//                        + ".txt");


                final File f = new File(Environment.getExternalStorageDirectory() + "/"
                        + context.getPackageName() + "/wifip2pshared-" + ".txt");
                File dirs = new File(f.getParent());
                if (!dirs.exists())
                    dirs.mkdirs();
                f.createNewFile();
                Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
                InputStream inputstream = client.getInputStream();
                copyFile(inputstream, new FileOutputStream(f));
                serverSocket.close();
                return f.getAbsolutePath();
            } catch (IOException e) {
                Log.e(WiFiDirectActivity.TAG, e.getMessage());
                return null;
            }
        }
        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(String result) {
            if (result != null) {
                statusText.setText("File copied - " + result);
//                Log.e("...File copied - ", result);
                Intent intent = new Intent();
                intent.setAction(android.content.Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.parse("file://" + result), "text/*");
                context.startActivity(intent);
            } else {
                Log.e("File copied is NULL- ", result);
            }
        }
        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPreExecute()
         */
        @Override
        protected void onPreExecute() {
            statusText.setText("Opening a server socket");
        }
    }
    public static boolean copyFile(InputStream inputStream, OutputStream out) {
        byte buf[] = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            out.close();
            inputStream.close();
        } catch (IOException e) {
            Log.d(WiFiDirectActivity.TAG, e.toString());
            return false;
        }
        return true;
    }
}


Get this bounty!!!

#StackBounty: #android #android-source #alsa #android-kernel #android-rom Modifying in-call voice playback in Android custom ROM

Bounty: 200

I would like to modify Android OS (official image from AOSP) to add preprocessing to normal phone call playback sound.

I’ve already achieved this filtering for app audio playback (by modifying HAL and audioflinger).

I’m OK with targeting only a specific device (Nexus 5X). Also, I only need to filter playback – I don’t care about recording (uplink).

UPDATE:
To make it clear – I’m OK with modifying Qualcomm specific drivers, or whatever part that runs on Nexus 5X can help me modify in-call playback.

UPDATE #2:

I’m attempting to create a Java layer app that routes the phone playback to the music stream in real time.
I’ve already succeeded in installing it as a system app, getting permissions for initializing AudioRecord with AudioSource.VOICE_DOWNLINK.
However, the recording gives blank samples, it doesn’t record the voice call.

Code inside my worker thread:

// Start recording
        int recBufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
        mRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_DOWNLINK, 44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, recBufferSize);

        // Start playback
        int playBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
        mTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, playBufferSize, AudioTrack.MODE_STREAM);

        mRecord.startRecording();;
        mTrack.play();

        int bufSize = 1024;
        short[] buffer = new short[bufSize];
        int res;
        while (!interrupted())
        {
            // Pull recording buffers and play back
            res = mRecord.read(buffer, 0, bufSize, AudioRecord.READ_NON_BLOCKING);

            mTrack.write(buffer, 0, res, AudioTrack.WRITE_BLOCKING);
        }

        // Stop recording
        mRecord.stop();
        mRecord.release();
        mRecord = null;

        // Stop playback
        mTrack.stop();
        mTrack.release();;
        mTrack = null;

I’m running on Nexus 5X, my own AOSP custom ROM, Android 7.1.1.
I need to find the place which will allow call recording to work – probably somewhere in hardware/qcom/audio/hal in platform code.

Also I’ve been looking at:
The function voice_check_and_set_incall_rec_usecase at hardware/qcom/audio/hal/voice.c
But wasn’t able to make sense out of it or how to make it work.


Get this bounty!!!

#StackBounty: #android #animation #scroll #android-tablayout #android-coordinatorlayout CoordinatorLayout + TabView + AnimateView(From …

Bounty: 50

Yesterday I am playing with CoordinatorLayout with TabView

1) What is my target ?

  • CoordinatorLayout with TabView
  • When I scroll up at that time One View As show in .GIF move down.
  • and Stick on the Top of the TabView (inside AppBar).

enter image description here

2) Where I reached ?

  • CoordinatorLayout with TabView with pretty scrolling.
  • TabView with Appbar Stop Scrolling At Top after Then Scroll RecyclerView.

enter image description here

3) Where I stuck ?

  • When I scroll Up One View Scroll Down but TabView Stick At Top not like 1st gif.

4) Code snippet

  • Xml file
    <android.support.design.widget.AppBarLayout
        android:id="@+id/main.appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <!--- ADD TAB_LAYOUT HERE -->
    
    
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll">
    
            <ImageView
                android:id="@+id/main.backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                android:src="@drawable/abc"
                app:layout_collapseMode="none" />
    
    
            <!-- ADD ANY THING THAT GETS SCROLLED ALL THE WAY UP WITH TOOLBAR -->
        </android.support.design.widget.CollapsingToolbarLayout>
    
    
        <!-- our tablayout to display tabs  -->
        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
    
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
    
    
    </android.support.design.widget.AppBarLayout>
    
    
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    

  • Java file (move upper view down code)
    AppBarLayout ab = (AppBarLayout) findViewById(R.id.main_appbar);ab.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
    
            int ScrollStart = (ab.getHeight() - tabLayout.getHeight() - llTop.getHeight() - llTop.getHeight());
            int scrollStop = (ab.getHeight() - tabLayout.getHeight() - llTop.getHeight());
            if ((-verticalOffset) > ScrollStart && (-verticalOffset) < scrollStop) {
                llTop.setVisibility(View.VISIBLE);
                llTop.setTranslationY(((-verticalOffset) - ScrollStart) - llTop.getHeight());
                Log.e("point", "" + ((-verticalOffset) - ScrollStart));
    
            } else if ((-verticalOffset) >= scrollStop) {
                llTop.setVisibility(View.VISIBLE);
            } else {
                llTop.setVisibility(View.INVISIBLE);
            }
    
    
        }
    });
    


Get this bounty!!!

#StackBounty: #java #android #android-asynctask #google-api #location Get location on user state returns by ActivityRecognition

Bounty: 50

I need to get location(By fusedlocation API) of user after ActivityRecognition state returns(Which calls every 3 mins), like IN_VEHICLE,ON_FOOT,RUNNING etc.

On each event i need user location after regular interval For example:

if user is still then send location every 5 hours
if user is running then send location every 1 mins
if user is Driving then send location every 15 mins.

But i tried several ways but none of my logic works, which can send location after getting user state by ActivityRecognition .

Issue I am current having

  • ActivityRecognation Gets User State every 3 mins but it should not call location update until ‘LocationRequest.setInterval(Interval)’ LocationRequest.setInterval(FastestInterval); crossed.

Here is IntentService With FusedLocation

public class Activity_Recognized_Service extends IntentService implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener {
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public static final String TAG = "###RECOGNISED SRVCE###";
    Timer timer;
    GoogleApiClient LocationAPIclient;
    LocationRequest mLocationRequest;
    Location mCurrentLocation;
    boolean startLocationFirst=true;


    public Activity_Recognized_Service() {
        super("Activity_Recognized_Service");
    }

    public Activity_Recognized_Service(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d(TAG, "On Handle Intent");
        if (ActivityRecognitionResult.hasResult(intent)) {
            Log.d(TAG, "ActivityRecognition Has Result");
            ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
            handleDetectedActivities(result.getProbableActivities());
            Navigation_Drawer nav = new Navigation_Drawer();
            nav.UserMovementResult(result);

        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG,"On Create Calling");
        if (LocationAPIclient == null) {
            Log.d(TAG, "Location API is NULL Value Of This ");
            LocationAPIclient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }

    }

    private void handleDetectedActivities(List<DetectedActivity> probableActivities) {

        for (DetectedActivity activity : probableActivities) {
            switch (activity.getType()) {
                case DetectedActivity.IN_VEHICLE:
                    Log.d(TAG, "In Vehicle " + activity.getConfidence());
                    if (activity.getConfidence() >= 75) {
                        //Send Notification To User
                        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                        builder.setContentText("In Vehicle");
                        builder.setSmallIcon(R.drawable.elaxer_x);
                        builder.setContentTitle("Elaxer");
                        NotificationManagerCompat.from(this).notify(0, builder.build());
                        requestLocatonSetting(10*60*1000,8*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
                        //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST
                        LocationAPIclient.connect();
                        if (startLocationFirst){
                            Log.d(TAG,"Start Location Update For Car");
                        }
                    }
                    break;
                case DetectedActivity.ON_BICYCLE:
                    Log.d(TAG, "On Bicycle " + activity.getConfidence());
                    if (activity.getConfidence() >= 75) {
                        //Send Notification To User
                        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                        builder.setContentText("On Bicycle");
                        builder.setSmallIcon(R.drawable.elaxer_x);
                        builder.setContentTitle("Elaxer");
                        NotificationManagerCompat.from(this).notify(0, builder.build());
                        requestLocatonSetting(7*60*1000,5*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
                        //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST
                        LocationAPIclient.connect();
                    }
                    break;
                case DetectedActivity.ON_FOOT:
                    Log.d(TAG, "On Foot " + activity.getConfidence());
                    if (activity.getConfidence() >= 75) {
                        //Send Notification To User
                        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                        builder.setContentText("On Foot");
                        builder.setSmallIcon(R.drawable.elaxer_x);
                        builder.setContentTitle("Elaxer");
                        NotificationManagerCompat.from(this).notify(0, builder.build());
                    }
                    break;
                case DetectedActivity.RUNNING:
                    Log.d(TAG, "On Running " + activity.getConfidence());
                    if (activity.getConfidence() >= 75) {
                        //Send Notification To User
                        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                        builder.setContentText("Running");
                        builder.setSmallIcon(R.drawable.elaxer_x);
                        builder.setContentTitle("Elaxer");
                        NotificationManagerCompat.from(this).notify(0, builder.build());
                        requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
                        //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST
                        LocationAPIclient.connect();
                    }
                    break;
                case DetectedActivity.STILL:
                    Log.d(TAG, "On Still " + activity.getConfidence());
                    if (activity.getConfidence() >= 75) {
                        //Send Notification To User
                        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                        builder.setContentText("Still");
                        builder.setSmallIcon(R.drawable.elaxer_x);
                        builder.setContentTitle("Elaxer");
                        NotificationManagerCompat.from(this).notify(0, builder.build());

                            requestLocatonSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
                          //  requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST
                            LocationAPIclient.connect();


                    }
                    break;
                case DetectedActivity.TILTING:
                    Log.d(TAG, "On Tilting " + activity.getConfidence());
                    if (activity.getConfidence() >= 75) {
                        //Send Notification To User
                        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                        builder.setContentText("Tilting");
                        builder.setSmallIcon(R.drawable.elaxer_x);
                        builder.setContentTitle("Elaxer");
                        NotificationManagerCompat.from(this).notify(0, builder.build());

                        requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
                        //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST
                        LocationAPIclient.connect();
                    }
                    break;
                case DetectedActivity.WALKING:
                    Log.d(TAG, "On Walking " + activity.getConfidence());
                    if (activity.getConfidence() >= 75) {
                        //Send Notification To User
                        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                        builder.setContentText("Let's Walk");
                        builder.setSmallIcon(R.drawable.elaxer_x);
                        builder.setContentTitle("Elaxer");
                        NotificationManagerCompat.from(this).notify(0, builder.build());
                        requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds
                        LocationAPIclient.connect();

                    }
                    break;
                case DetectedActivity.UNKNOWN:
                    Log.d(TAG, "UnKnown " + activity.getConfidence());
                    break;
            }
        }
    }

    public void setTimer(int Minutes) {
        Log.d(TAG, "==================================================");
        Log.d(TAG, "Set Timeer Starts It will Run Every " + Minutes);
        int MilliSeconds = 60000 * Minutes;
        final Handler handler = new Handler();
        timer = new Timer();
        TimerTask doAsynchronousTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            //CODE THAT YOU WANT TO EXECUTE AT GIVEN INTERVAL


                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                        }
                    }
                });
            }
        };
        timer.schedule(doAsynchronousTask, 0, MilliSeconds);
        Log.d(TAG, "==================================================");
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d(TAG, "On Connected Running");
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
         mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(LocationAPIclient);
        if (mCurrentLocation!=null){
            Log.d(TAG,"Last Known Location Is not Null ");
            new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy()));
        }
        else {
            Log.d(TAG,"Last Known Location Is NULL Start Location Updates");
            LocationServices.FusedLocationApi.requestLocationUpdates(LocationAPIclient,mLocationRequest,this);
        }

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG,"On Location Changed Calling");
        mCurrentLocation=location;
        new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy()));
        Log.d(TAG,"Stopping Location Update");
       // LocationServices.FusedLocationApi.removeLocationUpdates(LocationAPIclient,this);
    }

    public void requestLocatonSetting(int Interval,int FastestInterval,int LocationAccuracy){
        mLocationRequest=new LocationRequest();
        mLocationRequest.setInterval(Interval);
        mLocationRequest.setFastestInterval(FastestInterval);
        mLocationRequest.setPriority(LocationAccuracy);

    }

}


Get this bounty!!!

#StackBounty: #android #maven #bintray #jcenter Add Warning "A newer version of ….. is available" for custom library

Bounty: 50

I’ve just released my library with version 1.2.1, code is in Github

As you can see in the picture:
enter image description here

I’m getting “Warning” that i’m using old version of appcompat library but there’s no warning for my library.

I’ve distribute my library via Bintray to maven & jcenter.

Does anyone knows how to enable this Note/Warning on my library line?

Thanks very much!


Get this bounty!!!

#StackBounty: #android #google-play-services #google-oauth #google-authentication #android-broadcastreceiver android GoogleAuthUtil.get…

Bounty: 500

I have a background service that calls GoogleAuthUtl.getTokenWithNotification and it works properly but I’m trying to implement the callback portion of this function and that isn’t working properly.

I’ve implemented a broadcast receiver and added it to the manifest, I also have an activity in my app. Below are the relevant pieces of code.

GoogleAuthUtil.getTokenWithNotification

GoogleAuthUtil.getTokenWithNotification(this.getContext(), account, "oauth2:" + GmailScopes.GMAIL_SEND, null, new Intent(AuthReceiver.AUTH_INTENT));

AuthReceiver

public class AuthReceiver extends BroadcastReceiver
{
    public final static String AUTH_INTENT = "com.testoauth.AUTH_INTENT";

    public AuthReceiver()
    {
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Log.d("RECEIVER", "Received Auth broadcast.");
        NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancelAll();
    }
}

AndroidManifest

<receiver android:name=".AuthReceiver" android:enabled="true" android:exported="true">
    <intent-filter>
        <action android:name="com.testoauth.AUTH_INTENT" />
    </intent-filter>
</receiver>

I have no clue why it is not receiving the broadcast. I don’t see any exceptions in the logs and no indication that the receiver was called at all, it won’t even break on a breakpoint when debugging. Am I doing something incorrectly?

EDIT

I’m using min sdk 15 and target sdk 22

From the GoogleAuthUtil.getTokenWithNotification API documentation:

This method is specifically provided for background tasks. In the
event of an error that needs user intervention, this method takes care
of pushing relevant notification. After the user addresses the
notification, the callback is broadcasted. If the user cancels then
the callback is not fired.

The callback is not fired regardless of the user canceling or not. Aside from gcm saying the notification has been displayed, there is no indication that the specified broadcast intent has been sent in the logs.


Get this bounty!!!

#StackBounty: #javascript #java #android #printing Android EPSON thermal Print data from web-view on click?

Bounty: 50

This is my Code here

Here In my activity I am using Epson SDK to print data form web-view to android activity..

So on Web-veiw Onclick It will start Printer Activity and It will print

What I am trying to do is….. OnClick from Web-view it will Open printer Activity so that it should print and Exit…

So here I have created a Web-view… With the help of JS it sill Open my activity form Web-view (onclick) till now its fine… But I tried to Add print and exit.. onclick but Its not working… Because I need to select language and Printer Model….

How ever in shared_DiscoveryActivity I am adding Printer and saved it in shared prefs… so it will not ask any more… its working

but In Main Activity I tried to remove buttons… But not wokring… I am getting Error (ERR_PARM) in printing… my code is fine..

Without Language and model no its not printing… I tried to give them in shared prefs but its not working…

Can any one help me to print the data OnClick from Web-view it will Open printer Activity so that it should print and Exit…

I have given my complete code.. if any ask me…
please suggest me on this kind plz…

Update

In new update I have given my entire code from github with Web-view in assets folder…. Please suggest me on this kind

Update 1

Here In my Code I am struck here

mPrinter = new Printer(((SpnModelsItem) mSpnSeries.getSelectedItem()).getModelConstant(),
                               ((SpnModelsItem) mSpnLang.getSelectedItem()).getModelConstant(),
                               mContext);

I am getting this at output for SpnModel , language and total mPrinter with both of them I tried same But I got this

    System.out:----- spnSeries -----android.widget.Spinner{24440249 VFED..C. ........ 0,444-466,516 #7f0e007b app:id/spnModel}
System.out: ----- lang -----android.widget.Spinner{1a6c617c VFED..C. ........ 0,604-366,676 #7f0e007d app:id/spnLang}
System.out: ----- printer -----com.epson.epos2.printer.Printer@b8250d6



System.out:----- spnSeries -----android.widget.Spinner{24440249 VFED..C. ........ 0,444-466,516 #7f0e007b app:id/spnModel}
System.out: ----- lang -----android.widget.Spinner{1a6c617c VFED..C. ........ 0,604-366,676 #7f0e007d app:id/spnLang}
System.out: ----- printer -----com.epson.epos2.printer.Printer@144a56f8

its Different always…

At initializeObject() in MainActivity… The Only thing is the if I overcome this manually or some other My printer is done.

On create only I am trying use runPrintReceiptSequence() But due to the above printer Language and Model selection I need to press a button.. I want to Do this without pressing a button or Do this language selection and Model selection from Shared Prefs… Like I have done adding Printer Discovery in shared_DiscoveryActivity.java

Please suggest me on this kind….


Get this bounty!!!

#StackBounty: #android #recyclerview #android-databinding #observablelist #android-binding-adapter Android data binding ObservableList …

Bounty: 100

I find it hard to spot the real raison d’etre of the android.databinding.ObservableList as a data binding feature.

At first it looked like a cool tool to display lists, through data binding, adding them via xml to a RecyclerView.
To do so, I made a BindingAdapter like this:

@BindingAdapter(value = {"items"}, requireAll = false)
public static void setMyAdapterItems(RecyclerView view, ObservableList <T> items) {
    if(items != null && (view.getAdapter() instanceof MyAdapter)) {
        ((GenericAdapter<T>) view.getAdapter()).setItems(items);
    }
}

This way, I can use the attribute app:items in a RecyclerView with a MyAdapter set to it, to update its items.

Now the best feature of ObservableList is you can add an OnListChangedCallback to it, which handles the same events available in the RecyclerView to add/move/remove/change items in it without actually reloading the whole list.

So the logic I thought to implement was the fallowing:

  1. I start with an empty MyAdapter
  2. When my items are fetched from my APIs, I instantiate an ObservableArrayList wrapping them and pass it to the binding
  3. Data binding invokes my BindingAdapter passing the items to MyAdapter
  4. When MyAdapter receives new items, it clears its old ones and adds an OnListChangedCallback to the ObservableList received to handle micro-changes
  5. If anything changes in the ObservableList, MyAdapter will change accordingly without refreshing completely
  6. If i want to display a completely different set of the same items type, I can just re-set the binding variable, so the BindingAdapter will be invoked again and MyAdapter items will be completely changed.

For example, if I want to display items of type Game which I have two different lists for: “owned games” and “wishlist games”, I could just call binding.setItems(whateverItems) to completely refresh the displayed items, but for example, if I move the “wishlist games” around the list to organize them by relevance, only micro-changes will be executed within each list without refreshing the whole thing.

Turns out this idea was unfeasible because data binding re-executes the BindingAdapter every time a single change is made to an ObservableList, so for example I observe the fallowing behaviour:

  1. I start with an empty MyAdapter
  2. When my items are fetched from my APIs, I instantiate an ObservableArrayList wrapping them and pass it to the binding
  3. Data binding invokes my BindingAdapter passing the items to MyAdapter
  4. When MyAdapter receives new items, it clears its old ones and adds an OnListChangedCallback to the ObservableList received to handle micro-changes
  5. If anything changes in the ObservableList, the BindingAdapter is invoked again, thus MyAdapter receives the whole list again and completely refreshes.

This behaviour seems quite broken to me because prevents the ObservableList from being usable within an data-bound xml. I cannot seriously figure out a legit case in which this behaviour is desirable.

I looked up some examples: here and this other SO question

In the first link all the examples used the ObservableList directly to the Adapter without even passing form xml and actual data binding, while in the code linked in the SO answer, the developer did basically the same thing I tried to do, adding:

if (this.items == items){
        return;
}

at the beginning of his Adapter.setItems(ObservableList<T> items) to discard all the cases where the method is invoked because of simple changes in the ObservableList.

What is the need of this behaviour? What might be some cases where this behaviour is desirable? I feel like ObservableList is a feature added with data binding and is really useful except when used with actual data binding, in which case it forces you to defend from its behaviour.
If I declare it as a simple List in both xml data tags and in BindingAdapter signature, then I can cast it back to ObservableList inside MyAdapter and it works just fine, but this is quite a bad hack.
If it was just a separate feature from data binding, without triggering the binding at every change it would have been much better in my opinion.


Get this bounty!!!

#StackBounty: #android #caching #mvp MVP Adapter Data Cache

Bounty: 50

I’m developing project following MVP architecture. Usually, when I use recyclerView, my presenter controls Adapter data. But now I need to make recycler adapter with data from cache (or something like cache), recycler’s size dosen’t depends on cache size, so I make cache via HashMap where the key is – position of recycler, if there is an item in map then the data shows, else empty row with something like “add events” btn. And I can’t realize where the place for that cache in such structure – Model (Dao or something like CacheManager) or in Adapter.

The cache idea is following: I have some types of events which store in database, every event modifying changes it in db – so the cache has to be updated either.

The main questions are: where to keep this cache and load it to adapter, how can i keep it sync with database changes.

P.S. Also I tries to use RX, so if it can be solved with it – would be very interesting to try.

P.P.S If it the Repository pattern is the way to solve – welcome. Read about it sometime ago.


Get this bounty!!!

#StackBounty: #android #notifications #remote-input How to specify min and/or max length in RemoteInput

Bounty: 50

I use RemoteInput in my Android N notifications.

I want to set a min and max text length limit for the input.

Google Hangouts got this (i.e. the send button enables when the user entered at least 1 character). Anyone know how this can be done? I’ve tried to check the Android docs but no luck.


Get this bounty!!!