Skip to main content
Samsung Developer Program

Get Items Already Purchased by the User

How to retrieve and display information about all or some of in-app items that the user previously purchased

 

The example code in this section demonstrates how the user can click a UI button to see an owned list of in-app items that they purchased (by type: consumable and non-consumable only, subscription only, or all types).  

In the example code, the owned list is constructed in the following way:

 

For more details about the IAP Helper API elements, see:

To get information about in-app items purchased by the user:

  1. Add a UI button that calls doGetOwnedList() to the activity_main.xml layout, below the purchase in-app item UI button.
    <!-- GetOwnedList Button -->
    <Button 
        android:id="@+id/btn_get_owned_list" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/get_owned_list"
        android:onClick="doGetOwnedList" />

 

  1. Add  doGetOwnedList() to the MainActivity.java file in order to: run the OwnedListActivity class and  set the type of purchased in-app items to be retrieved for the intent.
    public void doGetOwnedList(View _view) { 
        Intent intent = new Intent(MainActivity.this, OwnedListActivity.class); 
        intent.putExtra("ProductType", IapHelper.PRODUCT_TYPE_ALL); 
        startActivity(intent);

 

  1. Implement onCreate() and the OnGetOwnedListListener interface by adding the OwnedListActivity class.
    onCate()saves the values passed to the intent (the type of items to be returned), instantiates an IapHelper object, and calls getOwnedList() to request purchased in-app items of the specified type. 
    The OwnedListActivity class also hasonGetOwnedProducts() that will be completed in later steps in order to process the requested in-app item information and the getOwnedList() processing results that are received in the OnOwnedItemsListListener interface.

    Note: If you run the code now, you will not see any results because there is no code in onGetOwnedProducts(). But you will be able see that your application is connected to Samsung IAP, and that the requested results will be passed to onGetOwnedProducts().
     
    public class OwnedListActivity extends AppCompatActivity implements 
    OnGetOwnedListListener { 
    
        private String mProductType = IapHelper.PRODUCT_TYPE_ALL;
        private IapHelper mIapHelper = null; 
    
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
    
            Intent intent = getIntent(); 
    
            if (intent != null && intent.getExtras() != null 
                    && intent.getExtras().containsKey("ProductType")) { 
                Bundle extras = intent.getExtras(); 
                mProductType = extras.getString("ProductType"); 
            } 
            else { 
                Toast.makeText(this, 
                    R.string.invalid_parameter, 
                    Toast.LENGTH_LONG).show(); 
                finish(); 
            } 
    
            mIapHelper = IapHelper.getInstance(this);
            mIapHelper.getOwnedList(mProductType, this); 
        } 
    
        @Override 
        public void onGetOwnedProducts(ErrorVo _errorVO,
                                       ArrayList<OwnedProductVo> _ownedList) { 
        } 
    }

 

  1. Add the OwnedListActivity class to the AndroidManifest.xml file.
    <activity 
        android:name=".OwnedListActivity" 
        android:label="@string/items_owned_list"/>


     
  2. Add views  to  theOwnedListActivity class and initialize the views by adding the following code to onCreate() in the OwnedListActivity class. This enables data to be added to the ListView in onGetOwnedProducts().
    setContentView(R.layout.owned_list_layout); 
    initView();

 

  1. Specify  the layout of the owned item list in to the inbox_list_layout.xmlfile.
    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android" 
        android:orientation="vertical" android:layout_width="match_parent" 
        android:layout_height="match_parent"> 
        
        <!-- Owned List ListView --> 
        <ListView android:id="@+id/itemOwnedList" 
            android:layout_width="match_parent" 
            android:layout_height="0dp"
            android:layout_weight="1"
            android:visibility="gone"/> 
            
        <!-- Owned List NULL --> 
        <TextView android:id="@+id/noDataText" 
            android:layout_width="match_parent" 
            android:layout_height="match_parent" 
            android:gravity="center" 
            android:text="@string/items_owned_list_empty"/> 
            
    </LinearLayout>

 

  1. AddinitView().
    public void initView() { 
        mOwnedListView = (ListView) findViewById(R.id.itemOwnedList); 
        mNoDataTextView = (TextView) findViewById(R.id.noDataText); 
        mNoDataTextView.setVisibility(View.GONE); 
        
        mOwnedListView.setEmptyView(mNoDataTextView); 
        
        mOwnedListAdapter = new OwnedListAdapter(this, 
            R.layout.owned_item_row, 
            mOwnedList); 
        
        mOwnedListView.setAdapter(mOwnedListAdapter);
    }


     
  2. Add the following member variables to the OwnedListActivity class.
    mOwnedListAdapter functions as an AdapterView that provides each row of the ListView with views.
    private ListView mOwnedListView = null; 
    private TextView mNoDataTextView = null; 
    private ArrayList<OwnedProductVo> mOwnedList = new ArrayList<OwnedProductVo>(); 
    private OwnedListAdapter mOwnedListAdapter = null;


     
  3. Extract owned list data from the OwnedProductVo object by adding the OwnedListAdapter class.
    public class OwnedListAdapter extends ArrayAdapter<OwnedProductVo> { 
        private int mResId = 0; 
        private LayoutInflater mInflater = null; 
        private ArrayList<OwnedProductVo> mItems = null; 
        
        public OwnedListAdapter (Context _context, int _resId, 
                                 ArrayList<OwnedProductVo> _items) { 
        
            super(_context, _resId, _items); 
        
            mResId = _resId; 
            mItems = _items; 
            mInflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        } 
        
        public static class ViewHolder { 
            TextView itemName;
            TextView itemPriceString; 
            TextView itemType; TextView itemDesc; 
        } 
            
        @Override 
        public View getView (final int _position, View _convertView, final ViewGroup _parent) { 
        
            final OwnedProductVo vo = mItems.get(_position); 
            ViewHolder vh; 
            View v = _convertView; 
            
            if (v == null) { 
                vh = new ViewHolder(); 
                v = mInflater.inflate(mResId, null); 
                
                vh.itemName = (TextView) v.findViewById(R.id.itemName); 
                vh.itemPriceString = (TextView) v.findViewById(R.id.itemPriceString); 
                vh.itemType = (TextView) v.findViewById(R.id.itemType); 
                vh.itemDesc = (TextView) v.findViewById(R.id.itemDesc); 
                
                v.setTag(vh); 
            } 
            else { 
                vh = (ViewHolder) v.getTag(); 
            } 
            
            vh.itemName.setText(vo.getItemName()); 
            vh.itemPriceString.setText(vo.getItemPriceString()); 
            
            String itemType = "Type : "; 
            
            if ("item".equals(vo.getType())) { 
                itemType += "item"; 
            } 
            else if ("subscription".equals(vo.getType())) { 
                itemType += "subscription"; 
            } 
            else { 
                itemType += "Unsupported type"; 
            } 
            vh.itemType.setText(itemType); 
            vh.itemDesc.setText(vo.getItemDesc()); 
            
            return v; 
        }
    }


     
  4. Specify the row layout for each view ofListView in the owned_item_row.xml file. 
    The layout is passed as an argument toOwnedListAdapter() in initView()(step 7).
    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android" 
        android:orientation="vertical" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content"
        android:paddingBottom="8dp" 
        android:paddingLeft="12dp" 
        android:paddingRight="12dp" 
        android:paddingTop="8dp" > 
        
        <LinearLayout 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content" 
            android:orientation="horizontal" > 
            
            <TextView android:id="@+id/itemName" 
                android:layout_width="0dp" 
                android:layout_height="wrap_content" 
                android:lineSpacingExtra="8dp" 
                android:maxLines="1" 
                android:ellipsize="end" 
                android:textSize="14dp" 
                android:textStyle="bold" 
                android:gravity="center_vertical|start" 
                android:layout_weight="1" /> 
                
            <TextView 
                android:id="@+id/itemPriceString" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:lineSpacingExtra="8dp" 
                android:maxLines="1" 
                android:ellipsize="end" 
                android:textSize="14dp" 
                android:textStyle="bold" 
                android:gravity="center_vertical|end" 
                android:layout_marginStart="10dp" 
                android:layout_marginLeft="10dp" 
                android:layout_weight="0" /> 
                
        </LinearLayout> 
                
            <TextView 
                android:id="@+id/itemType" 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:maxLines="1" 
                android:ellipsize="end" 
                android:textSize="10dp" 
                android:gravity="center_vertical|start"/> 
                
            <TextView android:id="@+id/itemDesc" 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:maxLines="1" 
                android:ellipsize="end" 
                android:textSize="10dp" 
                android:gravity="center_vertical|start"/> 
                
    </LinearLayout>


     
  5. Update ListView with returned owned list data by adding getOwnedList() results toonGetOwnedProducts().
    When getOwnedList() is successful, the returned_ownedList data is added to mOwnedList, and notify themOwnedListAdapter to update the ListView.
    @Override
    public void onGetOwnedProducts(ErrorVo _errorVO,
                                   ArrayList<OwnedProductVo> _ownedList) {
                                   
        if (_errorVO != null
                && _errorVO.getErrorCode() == IapHelper.IAP_ERROR_NONE) {
            if (_ownedList != null && _ownedList.size() > 0) {
                mOwnedList.addAll(_ownedList);
                mOwnedListAdapter.notifyDataSetChanged();
            }
        }
    }

     

To test your code: 

  • We recommend that you run the test in both test modes: Developer Test Mode (Success) and Developer Test Mode (Failed).
  • In your Android app code:
    • Set the IAP operating mode to the appropriate test mode.
    • All item IDs must match the IDs of registered in-app items. 
  • Your Android app and the in-app items must be registered in Seller Office.
     
  1. Run your code.
    Note:  The following steps apply when your code implements getting offered items in a way that is similar to the example code above. 
  2. Verify that an error message is not displayed in AlertDialog that indicates your code failed to run. 
  3. When the operating mode is Developer Test Mode (Success):
    1. Verify that the Owned list screen is displayed.
      InAppItems_Owned_List.png
    2. Review the owned list:
      1. Verify that all purchased items of the requested type are listed.
      2. For each listed item, verify that the item data is correct.
         
  4. When the operating mode is Developer Test Mode (Failed):
    1. Verify that owned list is not displayed.
    2. Review the errorVo object received by OnGetOwnedListListener and verify that it indicates an error status.