android project compiles but doesn't run correctly - android

this is the main activity file That I have:
package de.project.packagelist;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import de.project.packagelist.models.Pkg;
public class MainActivity extends AppCompatActivity {
public static MainActivity instance;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
setContentView(R.layout.activity_main);
populatePackages();
}
public void onPackageUninstalled(String pkgName) {
Toast.makeText(this, pkgName + " is uninstalled", Toast.LENGTH_SHORT).show();
populatePackages();
}
public void onPackageInstalled(String pkgName) {
Toast.makeText(this, pkgName + " is installed", Toast.LENGTH_SHORT).show();
populatePackages();
}
public void onPackageChanged(String pkgName) {
Toast.makeText(this, pkgName + " is changed", Toast.LENGTH_SHORT).show();
populatePackages();
}
public void populatePackages() {
ArrayList<Pkg> pkgList = new ArrayList<>();
PackageListAdapter packageListAdapter = new PackageListAdapter(this, pkgList);
ListView listView = (ListView) findViewById(R.id.package_list);
listView.setAdapter(packageListAdapter);
pkgList.clear();
PackageManager pm = getPackageManager();
List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_META_DATA);
for (PackageInfo packageInfo : packages) {
pkgList.add(new Pkg(packageInfo.packageName, packageInfo.packageName, packageInfo.versionName, packageInfo.versionCode));
}
}
class PackageListAdapter extends ArrayAdapter<Pkg> {
public PackageListAdapter(Context context, List<Pkg> packages) {
super(context, R.layout.list_item_package, packages);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.list_item_package, null);
}
final Pkg p = getItem(position);
if (p != null) {
TextView tt1 = (TextView)v.findViewById(R.id.pkg_label);
tt1.setText(p.getLabel());
TextView tt2 = (TextView)v.findViewById(R.id.pkg_name);
tt2.setText(p.getName());
TextView tt3 = (TextView)v.findViewById(R.id.pkg_version);
tt3.setText(p.getVersionName());
Button btn1 = (Button)v.findViewById(R.id.pkg_uninstall);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Uninstalling package: " + p.getName(), Toast.LENGTH_SHORT).show();
}
});
Button btn2 = (Button)v.findViewById(R.id.pkg_launch);
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Launching package: " + p.getName(), Toast.LENGTH_SHORT).show();
}
});
ImageView imageView = (ImageView)v.findViewById(R.id.pkg_icon);
// imageView.setImageDrawable(p.get);
}
return v;
}
}
}
and this is the receiver's code:
import android.net.Uri;
import de.project.packagelist.MainActivity;
public class PackageChangedBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//triggered whenever any change happens to any package
//should inform activity
Uri data = intent.getData();
String pkgName = data.toString().substring(data.getScheme().length() + 1); //remove 'package:'
if(MainActivity.instance != null) {
if(intent.getAction() == "android.intent.action.PACKAGE_ADDED") {
MainActivity.instance.onPackageInstalled(pkgName);
} else if(intent.getAction() == "android.intent.action.PACKAGE_REMOVED") {
MainActivity.instance.onPackageUninstalled(pkgName);
} else if(intent.getAction() == "android.intent.action.PACKAGE_CHANGED") {
MainActivity.instance.onPackageChanged(pkgName);
}
}
}
}
MY code compiles without errors but when I run it, it takes too long to launch and the buttons are irresponsive. I know I am using older versions and libraries but do you see anything I can improve within my code. in my XML files(manifest and layouts, I have the launch icon and 2 buttons one to launch the package and the other one is to uninstall it.
What am I doing wrong?

I think you have to change your populatePackages function. You create your adapter and set your list view again and again on each brodcast process.
I think you should create a function which is initAdapter
InitAdapter function :
public void initAdapter(){
//not set list here and PackageListAdapter define as global
packageListAdapter = new PackageListAdapter(this);
ListView listView = (ListView) findViewById(R.id.package_list);
listView.setAdapter(packageListAdapter);
}
change the constructor of adapter class and create a setItems function
public PackageListAdapter(Context context) {
super(context, R.layout.list_item_package);
}
public setItems(List<Pkg> packages) {
this.packages = packages
}
and in your populatePackages function:
public void populatePackages() {
ArrayList<Pkg> pkgList = new ArrayList<>();
PackageManager pm = getPackageManager();
List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_META_DATA);
for (PackageInfo packageInfo : packages) {
pkgList.add(new Pkg(packageInfo.packageName, packageInfo.packageName, packageInfo.versionName, packageInfo.versionCode));
}
packageListAdapter.setItems(pkgList);
}

Related

E/RecyclerView: No adapter attached; skipping layout (Using Fragment)

I have been reading the different answers here on stackoverflow and on this blog post and tried to implement their solutions but I am still getting the error: No adapter attached; skipping layout.
RecyclerAdapter:
package vn.jupviec.frontend.android.monitor.app.ui.candidate;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.w3c.dom.Text;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import butterknife.BindView;
import vn.jupviec.frontend.android.monitor.app.R;
import vn.jupviec.frontend.android.monitor.app.domain.candidate.TrainingDTO;
import vn.jupviec.frontend.android.monitor.app.util.Utils;
/**
* Created by Windows 10 Gamer on 16/12/2016.
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder> {
private static final String TAG = "RecyclerView";
private List<TrainingDTO> mTrainingDTOs;
private Context mContext;
private LayoutInflater mLayoutInflater;
private String today;
private static final DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
AdapterInterface buttonListener;
public RecyclerAdapter(Context context, List<TrainingDTO> datas, AdapterInterface buttonListener) {
mContext = context;
mTrainingDTOs = datas;
this.mLayoutInflater = LayoutInflater.from(mContext);
this.buttonListener = buttonListener;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.candidate_item, parent, false);
// View itemView = mLayoutInflater.inflate(R.layout.candidate_item, parent, false);
return new RecyclerViewHolder(itemView);
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
final ObjectMapper mapper = new ObjectMapper();
final TrainingDTO trainingDTO = mapper.convertValue(mTrainingDTOs.get(position), TrainingDTO.class);
holder.tvName.setText(trainingDTO.getMaidName());
holder.status.setVisibility(View.GONE);
Date date = new Date();
String currentDate = sdf.format(date);
for (TrainingDTO.TrainingDetailDto td : trainingDTO.getListTrain()) {
today = Utils.formatDate((long) td.getTrainingDate(),"dd/MM/yyyy");
break;
}
if(currentDate.equals(today)) {
holder.status.setVisibility(View.VISIBLE);
holder.status.setText("(Mới)");
}
holder.btnHistory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext,R.string.msg_no_candidate_history,Toast.LENGTH_SHORT).show();
}
});
holder.btnTest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonListener.showComment(trainingDTO);
}
});
}
#Override
public int getItemCount() {
int size ;
if(mTrainingDTOs != null && !mTrainingDTOs.isEmpty()) {
size = mTrainingDTOs.size();
}
else {
size = 0;
}
return size;
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView tvName;
private Button btnTest;
private Button btnHistory;
private TextView status;
public RecyclerViewHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.txtName);
btnTest = (Button) itemView.findViewById(R.id.btnTest);
btnHistory = (Button) itemView.findViewById(R.id.btnHistory);
status = (TextView)itemView.findViewById(R.id.status);
}
}
public boolean removeItem(int position) {
if (mTrainingDTOs.size() >= position + 1) {
mTrainingDTOs.remove(position);
return true;
}
return false;
}
public interface AdapterInterface {
void showComment(TrainingDTO trainingDTO);
void showHistory(TrainingDTO trainingDTO);
}
}
FragmentTapNew:
package vn.jupviec.frontend.android.monitor.app.ui.candidate;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
import vn.jupviec.frontend.android.monitor.app.R;
import vn.jupviec.frontend.android.monitor.app.domain.ResultDTO;
import vn.jupviec.frontend.android.monitor.app.domain.candidate.TrainingDTO;
import vn.jupviec.frontend.android.monitor.app.domain.training.CandidateService;
import vn.jupviec.frontend.android.monitor.app.util.Constants;
import vn.jupviec.frontend.android.monitor.app.util.Utils;
/**
* Created by Windows 10 Gamer on 09/12/2016.
*/
public class FragmentTapNew extends Fragment implements RecyclerAdapter.AdapterInterface {
private static final String TAG = FragmentTapNew.class.getSimpleName();
Activity myContext = null;
private OnItemSelectedListener listener;
ShapeDrawable shapeDrawable;
#BindView(R.id.lvToday)
RecyclerView lvToday;
#BindView(R.id.textView)
TextView textView;
#BindView(R.id.pb_loading)
ProgressBar pbLoading;
private Unbinder unbinder;
private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
ArrayList<TrainingDTO> mTrainingDTO ;
RecyclerAdapter mTrainingDTOAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_candidate_training, container, false);
unbinder = ButterKnife.bind(this, v);
initViews();
return v;
}
private void initViews() {
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
lvToday.setHasFixedSize(true);
lvToday.setNestedScrollingEnabled(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
today();
}
});
t.start();
}
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
Toast.makeText(getActivity(), R.string.err_cannot_establish_connection, Toast.LENGTH_SHORT).show();
return false;
} else
return true;
}
private void today() {
if(isNetworkConnected()){
String token = "a";
Integer date = 0;
setLoadingVisible(true);
CandidateService.getApiDummyClient(getContext()).getCandidate(
token,
date,
Constants.TRAINING,
Arrays.asList(Constants.TRAINING_DAY_NEW),
new Callback<ResultDTO>() {
#Override
public void success(ResultDTO resultDTO, Response response) {
setLoadingVisible(false);
mTrainingDTO = (ArrayList<TrainingDTO>) resultDTO.getData();
if (mTrainingDTO.size() == 0) {
if(textView!=null) {
textView.setVisibility(View.VISIBLE);
textView.setTextColor(Color.RED);
textView.setGravity(Gravity.CENTER | Gravity.BOTTOM);
}
} else {
if(textView!=null) {
textView.setVisibility(View.GONE);
}
if(null==mTrainingDTOAdapter) {
mTrainingDTOAdapter = new RecyclerAdapter(getActivity(), mTrainingDTO, FragmentTapNew.this);
lvToday.setAdapter(mTrainingDTOAdapter);
} else {
lvToday.setAdapter(mTrainingDTOAdapter);
mTrainingDTOAdapter.notifyDataSetChanged();
}
lvToday.invalidate();
}
}
#Override
public void failure(RetrofitError error) {
Log.e(TAG, "JV-ERROR: " + error.getMessage());
Log.e(TAG, "JV-ERROR: " + error.getSuccessType());
}
});
}
}
#Override
public void onResume() {
setLoadingVisible(false);
initViews();
lvToday.setAdapter(mTrainingDTOAdapter);
super.onResume();
}
#Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
private void setLoadingVisible(boolean visible) {
// pbLoading.getIndeterminateDrawable().setColorFilter(0xFFFF0000, android.graphics.PorterDuff.Mode.MULTIPLY);
if(pbLoading!=null) {
pbLoading.setVisibility(visible ? View.VISIBLE : View.GONE);
lvToday.setVisibility(visible ? View.GONE : View.VISIBLE);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnItemSelectedListener) {
listener = (OnItemSelectedListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " phải implemenet MyListFragment.OnItemSelectedListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
#Override
public void showComment(TrainingDTO trainingDTO) {
Intent intent = new Intent(getContext(), CommentActivity.class);
intent.putExtra(Constants.ARG_NAME_DETAIL, trainingDTO);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
}
#Override
public void showHistory(TrainingDTO trainingDTO) {
Intent intent = new Intent(getContext(), HistoryActivity.class);
intent.putExtra(Constants.ARG_CANDIDATE_HISTORY_DETAIL, trainingDTO);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
}
public interface OnItemSelectedListener {
void showComment(TrainingDTO trainingDTO);
void showHistory(TrainingDTO trainingDTO);
}
}
The first, you don't need to set adapter multiple time, only set adapter at the first time in your method initView().
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
lvToday.setHasFixedSize(true);
lvToday.setNestedScrollingEnabled(false);
if(mTrainingDTO == null) {
mTrainingDTO = new ArrayList<>();
}
if(null == mTrainingDTOAdapter ) {
mTrainingDTOAdapter = new RecyclerAdapter(getActivity(), mTrainingDTO, FragmentTapNew.this);
}
lvToday.setAdapter(mTrainingDTOAdapter);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
today();
}
});
t.start();
After that, you don't need to call lvToday.setAdapter(mTrainingDTOAdapter);
many times. Just call mTrainingDTOAdapter.notifyDataSetChanged(); if having any changes in your data mTrainingDTO.
The errorlog - error:No adapter attached; skipping layout indicates that you've attached LayoutManager but you haven't attached an adapter yet, so recyclerview will skip layout. I'm not sure but, in other words recyclerView will skip layout measuring at the moment.
to prevent this errorLog Try to set an adapter with an empty dataSet i.e. ArrayList or
Attach LayoutManager just before you are setting your adapter.
Try this,
private void initViews() {
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(getActivity());
lvToday.setLayoutManager(mLinearLayoutManager);
lvToday.setHasFixedSize(true);
lvToday.setNestedScrollingEnabled(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
today();
}
});
t.start();
}

Listview not displaying the right image in android

In my app I have a listview. Each listview item contains an image view and several textviews. To display the image I use Drawable. But the images are displayed in the wrong row when scrolling. The image in a row changes several times until the right image appears. I have searched the web but I found nothing working for me. I am posting my code below. Please help me! Thanks in advance!
MainActivity.java
package com.makemyandroidapp.example.stacksites;
import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private SitesAdapter mAdapter;
private ListView sitesList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("StackSites", "OnCreate()");
setContentView(R.layout.activity_main);
//Get reference to our ListView
sitesList = (ListView)findViewById(R.id.sitesList);
//Set the click listener to launch the browser when a row is clicked.
sitesList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int pos,long id) {
String posID = mAdapter.getItem(pos).getID();
Intent i = new Intent(getApplicationContext(), PositionDesc.class);
i.putExtra("posID", posID);
startActivity(i);
}
});
/*
* If network is available download the xml from the Internet.
* If not then try to use the local file from last time.
*/
if(isNetworkAvailable()){
Log.i("StackSites", "starting download Task");
SitesDownloadTask download = new SitesDownloadTask();
download.execute();
}else{
mAdapter = new SitesAdapter(getApplicationContext(), -1, SitesXmlPullParser.getStackSitesFromFile(MainActivity.this, "StackSites.xml"));
sitesList.setAdapter(mAdapter);
}
}
//Helper method to determine if Internet connection is available.
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
/*
* AsyncTask that will download the xml file for us and store it locally.
* After the download is done we'll parse the local file.
*/
private class SitesDownloadTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
//Download the file
try {
Downloader.DownloadFromUrl("https://duapune.com/mobile/listaeplote.php", openFileOutput("StackSites.xml", Context.MODE_PRIVATE));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result){
//setup our Adapter and set it to the ListView.
mAdapter = new SitesAdapter(MainActivity.this, -1, SitesXmlPullParser.getStackSitesFromFile(MainActivity.this, "StackSites.xml"));
sitesList.setAdapter(mAdapter);
Log.i("StackSites", "adapter size = "+ mAdapter.getCount());
}
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
Intent objIntent = new Intent(getApplication(), TabActivity.class);
finish();
startActivity(objIntent);
}
}
SitesAdapter.java
package com.makemyandroidapp.example.stacksites;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.view.View.OnClickListener;
/*
* Custom Adapter class that is responsible for holding the list of sites after they
* get parsed out of XML and building row views to display them on the screen.
*/
public class SitesAdapter extends ArrayAdapter<StackSite> {
//ImageLoader imageLoader;
//DisplayImageOptions options;
Context c;
String url1;
String url2;
Drawable backgr;
ImageView iconImg;
int posi;
RelativeLayout row;
public SitesAdapter(Context ctx, int textViewResourceId, List<StackSite> sites) {
super(ctx, textViewResourceId, sites);
c=ctx;
}
#Override
public View getView(int pos, View convertView, ViewGroup parent){
posi=pos;
row = (RelativeLayout)convertView;
Log.i("StackSites", "getView pos = " + pos);
if(null == row){
//No recycled View, we have to inflate one.
LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = (RelativeLayout)inflater.inflate(R.layout.row_site, null);
}
//Get our View References
final TextView kompaniaTxt = (TextView)row.findViewById(R.id.nameTxt);
TextView pozicioniTxt = (TextView)row.findViewById(R.id.aboutTxt);
final TextView kategoriaTxt = (TextView)row.findViewById(R.id.kategoriaTxt);
TextView qytetiTxt = (TextView)row.findViewById(R.id.qytetiTxt);
//final ProgressBar indicator = (ProgressBar)row.findViewById(R.id.progress);
kompaniaTxt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//String emri_komp=kompaniaTxt.getText().toString().replaceAll("\\s+","%20");
String emri_komp=kompaniaTxt.getText().toString();
Intent intent=new Intent(c,CompanyDesc.class);
intent.putExtra("emri_komp", emri_komp);
intent.putExtra("url1", url1);
c.startActivity(intent);
}
});
kategoriaTxt.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
String idKateg=getItem(posi).getIdKategoria();
Intent intent=new Intent(c,CategoryList.class);
intent.putExtra("idKateg", idKateg);
intent.putExtra("url2", url2);
c.startActivity(intent);
}
});
//Set the relavent text in our TextViews
kompaniaTxt.setText(getItem(pos).getKompania());
pozicioniTxt.setText(getItem(pos).getPozicioni());
kategoriaTxt.setText(getItem(pos).getKategoria());
qytetiTxt.setText(getItem(pos).getQyteti());
url1=getItem(pos).getImgUrl();
SitesDownloadTask download=new SitesDownloadTask();
download.execute();
return row;
}
private class SitesDownloadTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
try { iconImg = (ImageView)row.findViewById(R.id.iconImg);
backgr=drawable_from_url(url1,"kot");
//backgr=drawable_from_url("https://duapune.com/photos/duapune#duapune.com1349707357.png","kot");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result){
iconImg.setBackground(backgr);
}
Drawable drawable_from_url(String url, String src_name) throws
java.net.MalformedURLException, java.io.IOException
{System.out.println("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu");
return Drawable.createFromStream(((java.io.InputStream)
new java.net.URL(url.trim()).getContent()), src_name);
}
}
}
Try this..
You have to use ViewHolder for that issue
private class ViewHolder {
ImageView iconImg;
TextView kompaniaTxt,pozicioniTxt,kategoriaTxt,qytetiTxt;
}
EDIT
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
view = getActivity().getLayoutInflater().inflate(R.layout.row_site, parent, false);
holder = new ViewHolder();
holder.iconImg = (ImageView) view.findViewById(R.id.iconImg);
holder.kompaniaTxt = (TextView) view.findViewById(R.id.nameTxt);
holder.pozicioniTxt = (TextView) view.findViewById(R.id.aboutTxt);
//holder.kategoriaTxt = (TextView) view.findViewById(R.id.kategoriaTxt);
holder.qytetiTxt = (TextView) view.findViewById(R.id.qytetiTxt);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.kompaniaTxt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//String emri_komp=kompaniaTxt.getText().toString().replaceAll("\\s+","%20");
String emri_komp=holder.kompaniaTxt.getText().toString();
Intent intent=new Intent(c,CompanyDesc.class);
intent.putExtra("emri_komp", emri_komp);
intent.putExtra("url1", url1);
c.startActivity(intent);
}
});
holder.kategoriaTxt.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
String idKateg=getItem(posi).getIdKategoria();
Intent intent=new Intent(c,CategoryList.class);
intent.putExtra("idKateg", idKateg);
intent.putExtra("url2", url2);
c.startActivity(intent);
}
});
//Set the relavent text in our TextViews
holder.kompaniaTxt.setText(getItem(pos).getKompania());
holder.pozicioniTxt.setText(getItem(pos).getPozicioni());
holder.kategoriaTxt.setText(getItem(pos).getKategoria());
holder.qytetiTxt.setText(getItem(pos).getQyteti());
url1=getItem(pos).getImgUrl();
SitesDownloadTask download=new SitesDownloadTask();
download.execute();
return view;
}
and onPostExecute
#Override
protected void onPostExecute(Void result){
holder.iconImg.setBackground(backgr);
}
EDIT
Instead of using SitesDownloadTask AsyncTask use Universal Image Loader lib
https://github.com/nostra13/Android-Universal-Image-Loader
lazy image loader
https://github.com/thest1/LazyList

How do I maintain ListView state between activity loads in android

I'm doing some background processing in my activity and have a ListView that shows the progress. I 'update' the listView with
adapter.notifyDataSetChanged();
However when I leave the activity and then come back, the background processes are still running, but the list view isn't updated. This is presumably because it's a new object, not the previous one. How do I maintain my list view object between activity loads?
This is my activity. I think the issue is that the 'adapter' variable that the download uses to bind to to show updates, is recreated in the onCreate method of the activity, and the 'adapter' variable that the download originally bound to is not in the activity anymore.
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.model.ProgressEvent;
import com.amazonaws.services.s3.model.ProgressListener;
import com.amazonaws.services.s3.transfer.TransferManager;
//import com.amazonaws.auth.AWSCredentials;
//import com.amazonaws.auth.BasicAWSCredentials;
public class VideosActivity extends Activity {
ListView video_list;
CustomList adapter;
File storage_dir;
SharedPreferences completed_downloads; //http://developer.android.com/guide/topics/data/data-storage.html
SharedPreferences downloaded_data; //maps position to percent downloaded
SharedPreferences queue; //holds which fiiles are awaiting download
String images[]; //holds references to all thumnails for vids
String volume; //something like vol1 or vol2
String s3_dir; //the directory after the boucket that the files are stored in (do not add first slash)
String s3_bucket = "com--apps";
Handler handler = new Handler(); //'tunnel' through whci other threads communicate with main thread
Map<String, String[][]> video_config = new HashMap<String, String[][]>(); //holds info about video thumbs and filenames for all apps
ArrayList<String> arr_videos = new ArrayList<String>(); //holds video names
DownloadQueue queue_manager = new DownloadQueue();
#Override
public void onCreate(Bundle savedInstanceState) {
Log.v("dev", "onCreateCalled");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
volume = getPackageName().split("\\.")[2]; //something like vol1 or vol2
s3_dir = "android/" + volume + "/"; //the directory after the boucket that the files are stored in (do not add first slash)
completed_downloads = getSharedPreferences("completed_downloads", 0);
downloaded_data = getSharedPreferences("downloaded_data", 0);
queue = getSharedPreferences("queue", 0);
storage_dir = getApplicationContext().getExternalFilesDir(null); //private to app, removed with uninstall
adapter = new CustomList(this, R.layout.customlist, arr_videos);
video_list = (ListView)findViewById(R.id.list);
video_list.setAdapter(adapter); //set adapter that specifies list contents
ensureStorageDirExists( storage_dir ); //make sure storage dir exists
set_video_data(); //store vid dat in array
ensure_connection_or_warn();
}
public boolean ensure_connection_or_warn()
{
if(have_connection())
{
return true;
}
else
{
Toast.makeText(this, "No Internet connection", Toast.LENGTH_LONG).show();
return false;
}
}
protected void ensureStorageDirExists( File dir )
{
if (!dir.exists())
{
dir.mkdirs();
}
}
public void set_video_data()
{
config_video_data(); //run config
images = video_config.get(getPackageName())[0]; //set images
for (String name : video_config.get(getPackageName())[1] ) { //set video info, this should be streamlined but is due to legacy code and my crap Java skills, consider doing like this: http://developer.android.com/guide/topics/resources/more-resources.html#TypedArray
arr_videos.add(name);
}
}
public SharedPreferences stored_vals()
{
return PreferenceManager.getDefaultSharedPreferences(this);
}
public boolean have_connection()
{
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm.getActiveNetworkInfo()!=null && cm.getActiveNetworkInfo().isConnected() && cm.getActiveNetworkInfo().isAvailable())
{
Log.v("dev", "have internet connection");
return true;
}
else
{
Log.v("dev", "No internet connection");
return false;
}
}
public class DownloadQueue
{
protected void process()
{
if (queue.size() > 0 && queue.get(0).download_status == "queued") //this is meant to force one download at a time
{
queue.get(0).start();
adapter.notifyDataSetChanged();
}
}
protected void add(Integer position)
{
queue.edit.putInt(position+"");
d.download_status = "queued";
adapter.notifyDataSetChanged();
}
protected boolean position_is_queued(Integer position)
{
for (Download d : queue ) {
if(d.position == position)
{
return true;
}
}
return false;
}
protected void remove(Download d)
{
queue.remove(d);
adapter.notifyDataSetChanged();
}
}
public class CustomList extends ArrayAdapter<String>
{
View view;
int position;
Button btn;
public CustomList(Context context, int layout_id, ArrayList<String> objects)
{
super(context, layout_id, objects);
}
#Override
public View getView(final int position, View convertView, ViewGroup view_group)
{
set_view(convertView);
this.position = position;
TextView text_view = (TextView) view.findViewById(R.id.name);
ImageView image = (ImageView) view.findViewById(R.id.img);
btn = (Button) view.findViewById(R.id.play);
prepare_btn();
text_view.setText( list_text() );
image.setImageResource(
getResources().getIdentifier(images[position], "drawable", getPackageName())
);
return view;
}
public String list_text()
{
String s = arr_videos.get( position ).replace("_", " ").replace(".m4v", "");
s = s.substring(2, s.length());
return s;
}
public void set_view(View convertView)
{
if(convertView == null)
{
LayoutInflater inflater = getLayoutInflater();
view = inflater.inflate(R.layout.customlist, null);
}
else
{
view = convertView;
}
}
public Boolean is_downloaded()
{
return completed_downloads.getBoolean(position + "", false);
}
public void prepare_btn()
{
btn.setTag((Integer) position);
if(is_downloaded() == true)
{
btn.setText("Play ");
btn.setEnabled(true);
btn.setOnClickListener( new OnClickListener()
{
public void onClick(View btn)
{
int position = (Integer) btn.getTag();
Intent i = new Intent(VideosActivity.this, PlayVideoActivity.class);
String video_path = storage_dir + "/" + arr_videos.get(position);
Log.v("video_path", video_path);
i.putExtra("video_path", video_path);
startActivity(i);
}
});
}
else if( downloaded_data.contains(position+"") ) //it it's currently being downloaded
{
btn.setText(downloaded_data.getInt(position+"", 0) + "%");
btn.setEnabled(false);
}
else if( queue_manager.position_is_queued(position) ) //it's in the queue
{
btn.setText("Queued");
btn.setEnabled(false);
}
else
{
btn.setText("Download");
btn.setEnabled(true);
btn.setOnClickListener( new OnClickListener()
{
public void onClick(View btn)
{
int position = (Integer) btn.getTag();
btn.setEnabled(false);
queue_manager.add(position);
}
});
}
}
}
public class Download
{
File new_video_file;
int position;
String download_status;
com.amazonaws.services.s3.transfer.Download download;
protected void queue(int position)
{
this.position = position;
queue_manager.add(this);
queue_manager.process();
//put this download in the queue
//start downloading if it's the only one in the queue
}
protected void start()
{
if(!ensure_connection_or_warn())
{
return;
}
this.download_status = "started";
this.new_video_file = new File(storage_dir, arr_videos.get(position)); //local file to be writtent to
TransferManager tx = new TransferManager(credentials);
//http://stackoverflow.com/questions/6976317/android-http-connection-exception
this.download = tx.download(s3_bucket, s3_dir + arr_videos.get(position), new_video_file);
download.addProgressListener(new ProgressListener()
{
public void progressChanged(final ProgressEvent pe)
{
handler.post( new Runnable()
{
#Override
public void run()
{
if ( pe.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE )
{
Download.this.onComplete();
}
else
{
Download.this.onProgressUpdate();
}
}
});
}
});
}
//protected void onProgressUpdate(Double progress)
protected void onProgressUpdate()
{
this.download_status = "downloading";
Double progress = this.download.getProgress().getPercentTransfered();
Integer percent = progress.intValue();
//Log.v("runnable", percent + "");
downloaded_data.edit().putInt(position+"", percent).commit();
adapter.notifyDataSetChanged();
}
protected void onComplete()
{
Log.v("dev", "download complete!!!");
//downloaded_data.remove(position);
this.download_status = "complete";
completed_downloads.edit().putBoolean(position + "", true).commit();
queue_manager.remove(this);
queue_manager.process();
adapter.notifyDataSetChanged();
// this.download.abort();
}
}
}
Not exactly sure what happens during background processing and what do you mean by ListView state, but my suggestion would be:
try the following:
#Override
protected void onResume() {
super.onResume();
yourAdapter.clear();
yourAdapter.addAll(yourData); // API level [1..10] use for(..){ yourAdapter.add(yourData.get(index)) }
yourAdapter.notifyDataSetChanged();
}
Reason:
An adapter keeps a copy of all the elements, so when you call notifyDataSetChanged, it checks its own copy of the elements

Calling activitygroup from customlistadapter

I am working on an android app which is having functionality of tabs.
Everything is working fine but I am not able to call activtygroup from listadapter.
Here is my code for list adapter:
import java.util.ArrayList;
import android.app.Activity;
import android.app.ActivityGroup;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.tv.socialgoal.R;
import com.tv.socialgoal.imageloader.ImageLoader;
public class AllyListAdapter extends BaseAdapter{
Activity ctx;
ArrayList<Object> alist;
private ImageLoader imageLoader;
AllyBean allyBean;
private String photoPath;
public AllyListAdapter(Activity ctx, ArrayList<Object> alist) {
super();
this.ctx = ctx;
this.alist = alist;
imageLoader=new ImageLoader(ctx);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return alist.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View arg1, ViewGroup arg2) {
LayoutInflater linf=(LayoutInflater) ctx.getSystemService(ctx.LAYOUT_INFLATER_SERVICE);
View v=linf.inflate(R.layout.ally_list_row, null);
TextView tv=(TextView)v.findViewById(R.id.allyName);
ImageView profileImage=(ImageView)v.findViewById(R.id.ally_image);
Button inviteBtn=(Button)v.findViewById(R.id.invite_btn);
//SHOW DATA FROM LIST
allyBean=(AllyBean)alist.get(position);
tv.setText(allyBean.getName());
photoPath=allyBean.getAvatar();
profileImage.setTag(photoPath);
imageLoader.displayImage(photoPath, ctx, profileImage, false);
inviteBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent=new Intent(ctx,AddRemoveFriendScreen.class);
//intent.putExtra("friendId", allyBean.getUserId());
ctx.startActivity(intent);
}
});
return v;
}
/*public void replaceContentView(String id, Intent newIntent) {
View view =getLocalActivityManager().startActivity(id,
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
this.setContentView(view);
}*/
}
Now I have to call AddRemoveFriends activtygroup.
Here is the code for activtygroup:
import java.util.ArrayList;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ActivityGroup;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.tv.servercommunication.IServerResponse;
import com.tv.servercommunication.WebServiceCommunicator;
import com.tv.socialgoal.Constant;
import com.tv.socialgoal.R;
import com.tv.socialgoal.network.NetworkAvailablity;
import com.tv.task.TabViewActivity;
public class AddRemoveFriendScreen extends ActivityGroup implements OnClickListener, IServerResponse{
Button backBtn;
Button addRemoveFriendBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.friends_profile_screen);
backBtn=(Button)findViewById(R.id.back_button);
addRemoveFriendBtn=(Button)findViewById(R.id.add_remove_frnd_btn);
backBtn.setOnClickListener(this);
addRemoveFriendBtn.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back_button:
break;
case R.id.add_remove_frnd_btn:
callAddFriend_WS();
break;
default:
break;
}
}
private Handler _handler = new Handler() {
public void dispatchMessage(Message msg) {
switch (msg.arg1) {
case Constant.PID_ADD_REMOVE_FRIEND:
if (parseResponse(msg.obj.toString()) == true) {
Intent intent = new Intent(getParent(),
TabViewActivity.class);
startActivity(intent);
} else {
runOnUiThread(new Runnable() {
public void run() {
Constant.showAlertDialog(
Constant.DIALOG_TITLE_ERROR,
"Invalid username or password.",
getParent(), false);
}
});
}
break;
default:
break;
}
}
};
// GET USER ACCESSTOCKEN AND USER ID
private boolean parseResponse(String response) {
String message = null;
JSONObject post;
boolean isUserInfoAvail = false;
try {
JSONObject postjsonObject = new JSONObject(response);
JSONObject posts = postjsonObject.getJSONObject("posts");
post = posts.getJSONObject("post");
message = post.getString("message");
if (message.equalsIgnoreCase("failure")) {
isUserInfoAvail = false;
} else {
isUserInfoAvail = true;
}
} catch (JSONException e1) {
e1.printStackTrace();
}
return isUserInfoAvail;
}
public void callAddFriend_WS() {
if (NetworkAvailablity.checkNetworkStatus(AddRemoveFriendScreen.this)) {
// PREPARE URL
Constant.methodURL = "http://admin.tvdevphp.com/goalmachine/add_friend.php";
// PREPARE REQUEST PARAMETER
ArrayList<NameValuePair> requestParaList = new ArrayList<NameValuePair>();
requestParaList.add(new BasicNameValuePair("self_user_id", "1"));
requestParaList.add(new BasicNameValuePair("user_friend_id", "2"));
// CALL WEBSERVICE
WebServiceCommunicator.getInstance().registerForServerResponse(
AddRemoveFriendScreen.this);
WebServiceCommunicator.getInstance().callGetAppWebService(
Constant.showDialog, getParent(),
Constant.methodURL, getParent(), Constant.PID_ADD_REMOVE_FRIEND,
false, requestParaList);
} else {
Constant.showAlertDialog(Constant.errorTitle,
Constant.MSG_CHECK_INTERNET_SETTING, getParent(),
false);
}
}
// SERVER RESPONSE METHOD
public void serverResponse(String response, int processid) {
Message msg = new Message();
msg.arg1 = processid;
msg.obj = response;
_handler.dispatchMessage(msg);
}
}
Please suggest me how to call activtygroup from listadapter.
Make it like this you can access everything by doing like this.
public class AddRemoveFriendScreen extends ActivityGroup implements OnClickListener, IServerResponse
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
.......
}
class AllyListAdapter extends BaseAdapter
{
//Now you can call everything from ActivityGroup
}
}
Hope this will help you.
According to the android developper reference, you may use Fragments.
ActivityGroup is deprecated. Use the new Fragment and FragmentManager APIs instead; these are also available on older platforms through the Android compatibility package.
You can try this trick.
inviteBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(ctx instanceof ActivityGroup){
Intent intent = new Intent(ctx.getParent(),AddRemoveFriendScreen.class);
//intent.putExtra("friendId", allyBean.getUserId());
ctx.getParent().startActivity(intent);
}
else{
Intent intent = new Intent(ctx,AddRemoveFriendScreen.class);
//intent.putExtra("friendId", allyBean.getUserId());
ctx.startActivity(intent);
}
}
});
If it doesn't work just use internal class for your adapter in your AddRemoveFriendScreen class.

Making a call when button pressed on Arduino

Hi I'm trying to combine 2 projects
1. that tells me wen button on arduino pressed
2. make a call on android
what im trying to do is when button pressed on arduino make a call..
but with no luck :(
Call
package net.mitchtech.adb;
import net.mitchtech.adb.simpledigitalinput.R;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
public class phonecalls extends Activity {
private void call() {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:048598077"));
startActivity(callIntent);
} catch (ActivityNotFoundException activityException) {
Log.e("dialing-example", "Call failed", activityException);
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.input);
}
}
buttons
package net.mitchtech.adb;
import net.mitchtech.adb.simpledigitalinput.R;
import net.mitchtech.adb.phonecalls;
import org.microbridge.server.AbstractServerListener;
import org.microbridge.server.Server;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
public class ButtonView extends FrameLayout {
private static final String TAG = ButtonView.class.getSimpleName();
private final View mButtonView;
private Server mServer;
private final int BUTTON1 = 2;
private final int BUTTON2 = 3;
public ButtonView(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mButtonView = inflater.inflate(R.layout.input, this);
}
public void setServer(Server server) {
mServer = server;
mServer.addListener(new AbstractServerListener() {
#Override
public void onReceive(org.microbridge.server.Client client, byte[] data) {
if (data.length < 2)
return;
final int pinNumber = data[0];
final int pinState = data[1];
Log.i(TAG, "data[0]:" + pinNumber + " data[1]:" + pinState);
final TextView positionText = (TextView) findViewById(R.id.activeText);
class InputAction implements Runnable {
public void run() {
switch (pinNumber) {
case BUTTON1:
if (pinState == 1) {
call();
positionText.setText("Button 1 Active");
} else {
positionText.setText("");
}
break;
case BUTTON2:
if (pinState == 1) {
positionText.setText("Button 2 Active");
} else {
positionText.setText("");
}
break;
default:
break;
}
}
};
InputAction action = new InputAction();
post(action);
}
});
}
public View getmButtonView() {
return mButtonView;
}
}
and another activity
package net.mitchtech.adb;
import java.io.IOException;
import net.mitchtech.adb.simpledigitalinput.R;
import org.microbridge.server.Server;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class SimpleDigitalInputActivity extends Activity {
private final static String TAG = SimpleDigitalInputActivity.class.getSimpleName();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Server server = null;
try
{
server = new Server(4567);
server.start();
ButtonView buttonView = (ButtonView) findViewById(R.id.inputView);
buttonView.setServer(server);
} catch (IOException e)
{
Log.e(TAG, "Unable to start TCP server", e);
System.exit(-1);
}
}
}
Your call() function is declared in your activity, but you're trying to access it in your ButtonView class. Try moving it into ButtonView (copy & paste).

Categories

Resources