#StackBounty: #android #android-layout #android-activity View visibility state loss when resuming activity with previously started Acti…

Bounty: 50

Explanation:

  • I start an Activity B with an Activity transition from Activity A.

  • After starting the new Activity B, I change visibility states of some views (View.GONE) in B.

The issue is:

When starting a new Activity C and going back to Activity B (or forcing an onPause in B), the views with the changed visibility states appearing again, without any touch of the views by code or else.

The following video explains the issue in pictures: https://youtu.be/oqCZo5CSkQk

When using no transition, everything works as expected. Has anybody an idea, how to prevent the view state loss when resuming the Activity? Do i use the ActivityOptionsCompat wrong?

I use the support libraries:

'com.android.support:support-v4:27.1.1' and
'com.android.support:appcompat-v7:27.1.1'

But the issue also appears for older versions and on different phone manufactures (Pixel, Samsung, etc.).

Here the code for reproducing the issues:

Layouts

Activity A:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

  <TextView
      style="@style/TextAppearance.AppCompat.Title"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_margin="24dp"
      android:gravity="center"
      android:text="Activity A | this starts the transition to another activity"/>

  <android.support.v7.widget.AppCompatImageView
      android:id="@+id/imageToAnimate"
      android:layout_width="20dp"
      android:layout_height="20dp"
      app:srcCompat="@android:drawable/star_big_on"/>

  <Button
      android:id="@+id/start_next_activity"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="30dp"
      android:text="start Another Activity"/>

</LinearLayout>

Activity B:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

  <TextView
      style="@style/TextAppearance.AppCompat.Title"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_margin="24dp"
      android:gravity="center"
      android:text="Activity B | with progressbar"/>

  <android.support.v7.widget.AppCompatImageView
      android:id="@+id/imageToAnimate"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:transitionName="toAnimate"
      app:srcCompat="@android:drawable/star_big_on"/>

  <ProgressBar
      android:id="@+id/progress"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="24dp"
      android:visibility="gone"/>

  <TextView
      android:id="@+id/dismiss_text"
      style="@style/TextAppearance.AppCompat.Subhead"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginBottom="24dp"
      android:text="Also a text to dismiss"/>

  <Button
      android:id="@+id/show"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="SHOW"/>

  <Button
      android:id="@+id/hide_gone"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="SET GONE"/>

  <Button
      android:id="@+id/hide_invisible"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="SET INVISIBLE"/>

  <Button
      android:id="@+id/start_activity_c"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="START activity"/>


</LinearLayout>

Activity C:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

  <TextView
      style="@style/TextAppearance.AppCompat.Title"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Activity C"
      android:textSize="40sp"/>

</LinearLayout>

Activity source code

Activity A:

public class DebugActivityA extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a);
        findViewById(R.id.start_next_activity).setOnClickListener(v -> startWithTransition());
    }

    private void startWithTransition() {
        ActivityOptionsCompat options = ActivityOptionsCompat
                .makeSceneTransitionAnimation(DebugActivityA.this,
                                              findViewById(R.id.imageToAnimate),
                                              "toAnimate");
        startActivity(new Intent(DebugActivityA.this, DebugActivityB.class), options.toBundle());
    }

}

Activity B:

public class DebugActivityB extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);

        View progressbar = findViewById(R.id.progress);
        View dismissText = findViewById(R.id.dismiss_text);
        progressbar.setVisibility(View.VISIBLE);
        findViewById(R.id.show).setOnClickListener(v -> {
            progressbar.setVisibility(View.VISIBLE);
            dismissText.setVisibility(View.VISIBLE);
        });
        findViewById(R.id.hide_gone).setOnClickListener(v -> {
            progressbar.setVisibility(View.GONE);
            dismissText.setVisibility(View.GONE);
        });
        findViewById(R.id.hide_invisible).setOnClickListener(v -> {
            progressbar.setVisibility(View.INVISIBLE);
            dismissText.setVisibility(View.INVISIBLE);
        });
        findViewById(R.id.start_activity_c).setOnClickListener(this::startOtherActivity);
    }

    private void startOtherActivity(View view) {
        startActivity(new Intent(this, DebugActivityC.class));
    }

}

Activity C:

public class DebugActivityC extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_c);
    }

}


Get this bounty!!!

#StackBounty: #bluetooth #android Answer android calls on ubuntu via bluetooth

Bounty: 50

I can successfully connect my android device as audio source, and listen to music, youtube videos etc. on my laptop(that are played on android phone). But when I’m in a call, the audio doesn’t go through the laptop, but it works on my bluetooth headset. If I select an option on my android phone to transfer the call via bluetooth(like I would on my headset), there’s no sound on my computer…

What I tried:


Get this bounty!!!

#StackBounty: #android #bluetooth How to show BluetoothDevicePicker in Android?

Bounty: 50

I love this quick select dialog that pops up when you enable bluetooth. But it doesn’t always show. I’d like to display this dialog programmatically.

enter image description here

The closest I can get is with:

Intent bluetoothPicker = new Intent("android.bluetooth.devicepicker.action.LAUNCH");
        bluetoothPicker.putExtra("android.bluetooth.devicepicker.extra.FILTER_TYPE", 1);
        bluetoothPicker.putExtra("android.bluetooth.devicepicker.extra.NEED_AUTH", false);
        bluetoothPicker.putExtra("android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE", "com.cake.x0a.WoBo");

However, there are some slight differences, as you can see . But the biggest problem is, when you select a device, the dialog closes without attempting to connect to the device. With error:

E/WindowManager: android.view.WindowLeaked: Activity
com.android.settings.bluetooth.BluetoothScanDialog has leaked window
com.android.internal.policy.impl.PhoneWindow$DecorView{428851c0
V.E….. R……D 0,0-640,855} that was originally added here
at android.view.ViewRootImpl.(ViewRootImpl.java:467)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:267)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:289)
at com.android.settings.bluetooth.BluetoothScanDialog.initialize(BluetoothScanDialog.java:86)
at com.android.settings.bluetooth.BluetoothScanDialog.onPostCreate(BluetoothScanDialog.java:103)
at android.app.Instrumentation.callActivityOnPostCreate(Instrumentation.java:1156)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2396)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471)
at android.app.ActivityThread.access$900(ActivityThread.java:175)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5602)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)

enter image description here

The good news is, it still sends the DEVICE_SELECTED intent before it closes, so I could still connect to it programmatically. But it’s really dirty. I want to use the self-contained LocalBluetoothMonitor from native android, which can scan, connect, pair, all on its own without changing activities.


Get this bounty!!!

#StackBounty: #java #android #android-fragments #android-viewpager java.lang.IllegalStateException: Fragment not attached to a context

Bounty: 50

I have a tablayout with a viewpager in my MainActivity.

My PagerAdapter looks like this:

public class MainActivityPagerAdapter extends PagerAdapter {

    public MainActivityPagerAdapter(FragmentManager fm, int numOfTabs) {
        super(fm, numOfTabs);
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                return new StoresFragment();
            case 1:
                return new OrdersFragment();
            default:
                return null;
        }
    }
}

I am coming back from another activity like this:

Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish(); //finishAffinity();

But then I get an java.lang.IllegalStateException in one of my Fragments in the viewpager of the MainActivity.

I read many related questions and tried to solve this. It is said, that this happens when one keeps references to Fragments outside of the PagerAdapter. But I am not doing this, as you can see in my code.

Does anyone know what I am doing wrong?

Edit – Stacktrace

FATAL EXCEPTION: main
    Process: com.lifo.skipandgo, PID: 23665
    java.lang.IllegalStateException: Fragment OrdersFragment{42c2a740} not attached to a context.
    at android.support.v4.app.Fragment.requireContext(Fragment.java:614)
    at android.support.v4.app.Fragment.getResources(Fragment.java:678)
    at com.lifo.skipandgo.activities.fragments.OrdersFragment$1.results(OrdersFragment.java:111)
    at com.lifo.skipandgo.connectors.firestore.QueryResult.receivedResult(QueryResult.java:37)
    at com.lifo.skipandgo.controllers.UserController$2.onUpdate(UserController.java:88)
    at com.lifo.skipandgo.connectors.firestore.QuerySubscription.onEvent(QuerySubscription.java:59)
    at com.lifo.skipandgo.connectors.firestore.QuerySubscription.onEvent(QuerySubscription.java:18)
    at com.google.firebase.firestore.zzg.onEvent(Unknown Source)
    at com.google.firebase.firestore.g.zzh.zza(SourceFile:28)
    at com.google.firebase.firestore.g.zzi.run(Unknown Source)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5653)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
    at dalvik.system.NativeStart.main(Native Method)

Edit:
Interesting is, that the view has defenitely loaded when the error occurs. Because the error occurs about 10-15 seconds later after the fragment is shown again. I this in my orderFragment, where the error occurs:

orders = new QueryResult<UserOrder>(UserOrder.class) {
            @Override
            public void results(List<UserOrder> results) { 
orderLoadingMessage.setBackgroundColor(getResources().getColor(R.color.green)); 
    }
}

I do this in onCreateView and this result comes about 10-15 seconds after the view loaded.


Get this bounty!!!

#StackBounty: #android #navigation-drawer #android-jetpack #android-architecture-navigation #android-components Android Navigation Arch…

Bounty: 50

I’m currently using the Android Architecture Component’s Navigation, but I’m running into an issue with my Navigation Drawer. It shows the hamburger menu when at my starting destination, but other Fragments are showing the up arrow. I believe I’ve setup my navigation_graph incorrectly.

Here you can see my nav drawer, showing 2 items, Home and Settings. When in either of these Fragments, you should see the Hamburger icon.

nav drawer

However, when navigating to the Settings Fragment, it shows the Up arrow.

toolbar

navigation.graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    app:startDestination="@id/nav_home">

    <!-- Start at HomeFragment -->
    <fragment
        android:id="@+id/nav_home"
        android:name=".HomeFragment"
        android:label="@string/home">

        <!-- Navigate to the Search -->
        <action
            android:id="@+id/action_nav_home_to_nav_search"
            app:destination="@id/nav_search" />
    </fragment>


    <fragment
        android:id="@+id/nav_settings"
        android:name=".SettingsFragment"
        android:label="@string/settings">

        <!-- Navigate to the Search -->
        <action
            android:id="@+id/action_nav_settings_to_nav_search"
            app:destination="@id/nav_search" />
    </fragment>



    <fragment
        android:id="@+id/nav_search"
        android:name=".SearchFragment"
        android:label="@string/search" />

</navigation>

I feel like HomeFragment and SettingsFragment should be related somehow but I’m not sure how to define that.

main_drawer.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@id/nav_home"
            android:icon="@drawable/ic_home_white_24dp"
            android:title="@string/home" />

        <item
            android:id="@id/nav_settings"
            android:icon="@drawable/ic_settings_white_24dp"
            android:title="@string/settings" />
    </group>
</menu>

And then within MainActivity, I just set it up like this.

navController = findNavController(R.id.mainNavigationFragment)
setupActionBarWithNavController(this, navController, drawer_layout)

build.gradle

// Navigation
implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-alpha04'
implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-alpha04'

Thanks.


Get this bounty!!!

#StackBounty: #java #android #sockets #inputstream #serversocket Error while reading inputstream : Software caused connection abort&#39…

Bounty: 100

I am basically trying to host a server on an Android Device. Client devices connect to the server over TCP and send requests. The server performs the action requested by the client and then writes data back to the socket. The connection is not terminated by the server and requests are to be continuously read over the socket and replied to.

Note: The first 4 bytes of each request message contain the length of the actual message/request.

The parseXmlInputAndExecuteCmd function executes various asynchronous operations depending on the content of the input XML string. This eventually causes a change in boolean value of ‘allowResponse’ variable to true and a certain response is generated which is stored in the variable of type String called ‘response’. Once the boolean ‘allowResponse’ becomes true, the thread resumes execution and writes the response back to the socket’s OutputStream

Some of these asynchronous operations include connecting and disconnecting from the corporate VPN. Could that be a cause of the error ?

Some Class level variables being used are :

private volatile boolean allowResponse = false;
private String response;

Server Code:

    private void startServer() {
    try {
        ServerSocket serverSocket = new ServerSocket(9200);
        while (true) {
            Socket connectionSocket = serverSocket.accept();
            BufferedInputStream bufInpStream = new BufferedInputStream(connectionSocket.getInputStream());
            BufferedOutputStream bufOutStream = new BufferedOutputStream(connectionSocket.getOutputStream());
            ByteArrayOutputStream contentLengthBaos = new ByteArrayOutputStream();
            int c;
            int count = 0;
            while ((c = bufInpStream.read()) != -1) {
                contentLengthBaos.write(c);
                count++;
                if (count == 4) {
                    int contLen = getMessageLength(contentLengthBaos);
                    String content = getMessageContent(bufInpStream, contLen);
                    parseXmlInputAndExecuteCmd(content);
                    count = 0;
                    while (!allowResponse) {
                        Thread.sleep(1000);
                    }
                    allowResponse = false;
                    byte[] responseDataBytes = response.getBytes();
                    int outputContLen = responseDataBytes.length;
                    byte[] contLengthBytes = ByteBuffer.allocate(4).putInt(outputContLen).array();
                    ByteArrayOutputStream o = new ByteArrayOutputStream();
                    o.write(contLengthBytes);
                    o.write(responseDataBytes);
                    byte finalOutPutBytes[] = o.toByteArray();
                    bufOutStream.write(finalOutPutBytes);
                    bufOutStream.flush();
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

@NonNull
private String getMessageContent(BufferedInputStream inFromClient, int contLen) throws IOException {
    ByteArrayOutputStream contentBaos = new ByteArrayOutputStream();
    byte[] contentBytes = new byte[contLen];
    for (int i = 0; i < contLen; i++) {
        contentBaos.write(inFromClient.read());
        ByteArrayInputStream bais = new ByteArrayInputStream(contentBaos.toByteArray());
        bais.read(contentBytes);
    }
    String content = new String(contentBytes);
    Log.d(TAG, "Content : " + content);
    return content;
}

private int getMessageLength(ByteArrayOutputStream contentLengthBaos) {
    byte[] firstFourBytesArr = contentLengthBaos.toByteArray();
    int contLen = new BigInteger(firstFourBytesArr).intValue();
    contentLengthBaos = new ByteArrayOutputStream();
    Log.d(TAG, "Content length: " + contLen);
    return contLen;
}

The server is started using the following lines of code:

Thread serverThread = new Thread(new Runnable() {
        @Override
        public void run() {
            startServer();
        }
    });
    serverThread.start();

I am getting the following error stacktrace:

W/System.err: java.net.SocketException: Software caused connection abort
                  at java.net.SocketInputStream.socketRead0(Native Method)
                  at java.net.SocketInputStream.socketRead(SocketInputStream.java:114)
W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:170)
W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:139)
W/System.err:     at java.io.BufferedInputStream.fill(BufferedInputStream.java:248)
W/System.err:     at java.io.BufferedInputStream.read(BufferedInputStream.java:267)
                  at com.example.umathur.myapplication.MainActivity.startServer(MainActivity.java:192)
                  at com.example.umathur.myapplication.MainActivity.access$000(MainActivity.java:61)
                  at com.example.umathur.myapplication.MainActivity$1.run(MainActivity.java:139)
                  at java.lang.Thread.run(Thread.java:764)

I am getting an error called: java.net.SocketException: Software caused connection abort

I’m not sure where I’m going wrong in the usage of the inputstream/outputstream. Im getting the error at the following line(Line number 192 as mentioned in the stacktrace) :

while ((c = inputStream.read()) != -1)

In some similar questions on StackOverflow, I saw people stating that it might be a corporate firewall configuration issue ? Is that correct ? If so, how do I get it fixed ?

Could this be an issue with the Client code (To which I don’t have access) not being written correctly ?


Get this bounty!!!

#StackBounty: #android #sqlite #android-room #sqliteopenhelper #android-architecture-components Backup Room database

Bounty: 50

I’m trying to backup a room database programmatically.

For that, I’m simply copying the .sqlite file that contains the whole database

But, before copying, due to the fact that room has “write ahead logging” enabled, we must close the database so that “-shm file” and “-wal file” merge into a single “.sqlite” file. As pointed out here

I run .close() on RoomDatabase object:

Everything works fine with the backup, BUT, later on, when I try to execute an INSERT query, I get this error: android.database.sqlite.SQLiteException: no such table: room_table_modification_log (code 1)

How can I properly re-open room db after I close it?

ps: .isOpen() on RoomDatabase object returns true before INSERT

Room version: 1.1.1-rc1


Get this bounty!!!

#StackBounty: #android #json #gson #android-gson Gson trying to parse fields annotated with @Expose(false) and crashing

Bounty: 50

I’m trying to serialize one very basic object to JSON with Gson.

here is the class

@org.greenrobot.greendao.annotation.Entity
public class Giveaway {

    @Id(autoincrement = true)
    @Expose(serialize = false,deserialize = false)
    private Long id;

    @NotNull
    private String owner;

    private Date raffleDate;
    private String thumbnailUrl;

    @ToMany(referencedJoinProperty = "giveawayId")
    private List<Influencer> mustFollowList;


    @NotNull
    @Convert(converter = GiveawayCommentTypeConverter.class, columnType = Integer.class)
    private GiveawayCommentType tipo;


    private String specifWordValue;
    private Integer amountFriendsToIndicate;

    @NotNull
    @Unique
    private String mediaId;


    //to reflect the relationships
    @ToMany(referencedJoinProperty = "raffle")
    @Expose(deserialize = false, serialize = false)
    private List<UserOnGiveaway> attendantsTickets;
}

As you can see I’ve 2 fields that i DONT WANT to be serialized so I annotated them with expose = false, but even with this gson is trying to serialize them and crashing due OutOfMemory. (UserOnGiveaway has a circular reference with Giveaway and this explains why it crashes)

The gson code is:

        Gson parser = new GsonBuilder().setPrettyPrinting().excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.TRANSIENT).create();
        StringBuilder sb = new StringBuilder(200);
        try {
            for (Giveaway g : this.dao.getGiveawayDao().loadAll())
                sb.append(parser.toJson(g) + "n");
        } catch (Exception e) {
            e.printStackTrace();
        }

I didn’t want to use .excludeFieldsWithoutExposeAnnotation() since it forces me to write way more than necessary and anotate everything just to exclude 1 field…

What am I doing wrong?


Get this bounty!!!

#StackBounty: #android #ssl #openssl #mqtt #paho SSL/TLS certificate pinning in paho-Eclipse mqtt Android

Bounty: 50

I was able to perform MQTT connection to Broker without TLS/SSL certificate using paho{ mqttv3:1.1.0 } Service. However, when I tried pinning SSL certificate in Android it’s not working. Please help me in solving the issue. Attaching code for more insight.

Step 1: Certificate Conversion

Converted certificate.pem file to bouncy castle format and stored in the raw folder in Android project.

D:>"C:Program FilesJavajdk1.8.0_121binkeytool" -import -alias mqtt-broker -file C:UsersabcdDownloadscertificate.pem  -keypass ***** -keystore raw_key_file  -storetype BKS -storepass ***** -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider  -providerpath C:UsersabcdDownloadsbcprov-jdk16-1.45.jar

Step 2: MQTT client Settings

mclientPublisher = new MqttAndroidClient(context, mqttBrokerURL,PublisherClientID, new MemoryPersistence());
    if (null != mclientPublisher) 
       {
        MqttConnectOptions options = null;
        options = new MqttConnectOptions();
        options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
        options.setConnectionTimeout(60);
        options.setKeepAliveInterval(120);
        options.setAutomaticReconnect(true);
        SslUtility.newInstance(context);         
        options.setSocketFactory(SslUtility.getInstance().getSocketFactory
        (R.raw.raw_key_file,"****"));
        options.setCleanSession(true);
       }

Step 3: SSL UTILITY CLASS

 public class SslUtility {

   private static SslUtility     mInstance = null;
   private Context                mContext = null;
   private HashMap<Integer, SSLSocketFactory> mSocketFactoryMap = new 
   HashMap<Integer, SSLSocketFactory>();




   public SslUtility(Context context) {
    mContext = context;
   }

   public static SslUtility getInstance( ) {
    if ( null == mInstance ) {
            throw new RuntimeException("the first call must be to 
                                        SslUtility.newInstance(Context) ");
    }
    return mInstance;
  }


  public static SslUtility newInstance( Context context ) {
    if ( null == mInstance ) {
        mInstance = new SslUtility( context );
    }
    return mInstance;
  }


 public SSLSocketFactory getSocketFactory(int certificateId, String 
                                                      certificatePassword )
    {
     SSLSocketFactory result = mSocketFactoryMap.get(certificateId);
       if ( ( null == result) && ( null != mContext ) ) { 

        try {
          KeyStore keystoreTrust = KeyStore.getInstance("BKS");   
          keystoreTrust.load(mContext.getResources().
          openRawResource(certificateId),certificatePassword.toCharArray());
          TrustManagerFactory trustManagerFactory = 
          TrustManagerFactory.getInstance(TrustManagerFactory
                                              .getDefaultAlgorithm());
          trustManagerFactory.init(keystoreTrust);
          SSLContext sslContext = SSLContext.getInstance("TLS");
          sslContext.init(null, trustManagerFactory.getTrustManagers(), 
                                               new SecureRandom());
          result = sslContext.getSocketFactory();
          mSocketFactoryMap.put( certificateId, result);  
        }
        catch ( Exception ex ) {
        }
    }
    return result;
}

ERROR/LOGCAT:

 05-18 10:18:55.638 20810-20810/: disconnect method -inside catch block- Error is : java.lang.NullPointerException: Attempt to invoke virtual method 'boolean org.eclipse.paho.android.service.MqttAndroidClient.isConnected()' on a null object reference

It seems the MQTT client object is not created.

Reference:

SSL Certificate pinning in Android-MQTT Library[Paho]

Paho-eclipse-Forum

Developers Android-Google

HiveMQ-Mqtt


Get this bounty!!!