opencv implementation with with custom layout (on SurfaceView) - android-layout

I have an openCV application program working, but need to add buttons etc. to the layout. So basically I want to display the opencv camera view on a surfaceView and the add the other stuff underneath.
I've been searching the internet and forums for a while, only seeing the guy with a opencv facial detection application also wanting to add a custom layout... no solution.
I am really desperate for a solution so would hugely appreciate help. For this purpose I used the OpenCV sample 3 application (as a simple example) and tried to bind to a surfaceview on a simple custom layout. I managed it in a normal Camera application, but struggling quite a bit with the opencv example.
So this is the code that I have for the Sample3Native.java, Sample3View.java and SampleViewBase.java (as in example) files respectively:
public class Sample3Native extends Activity {
private Sample3View mView;
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
// Load native library after(!) OpenCV initialization
System.loadLibrary("native_sample");
// Create and set View
mView = new Sample3View(mAppContext);
setContentView(R.layout.main);
//setContentView(mView);
// Check native OpenCV camera
mView.openCamera();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
//constructor
public Sample3Native() {}
#Override
protected void onPause() {
super.onPause();
if (null != mView)
mView.releaseCamera();
}
#Override
protected void onResume() {
super.onResume();
if((null != mView) && !mView.openCamera() ) {
AlertDialog ad = new AlertDialog.Builder(this).create();
ad.setCancelable(false); // This blocks the 'BACK' button
ad.setMessage("Fatal error: can't open camera!");
ad.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
ad.show();
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack);
}
}
class Sample3View extends SampleViewBase {
private int mFrameSize;
private Bitmap mBitmap;
private int[] mRGBA;
public Sample3View(Context context) {
super(context);
}
#Override
protected void onPreviewStarted(int previewWidtd, int previewHeight) {
mFrameSize = previewWidtd * previewHeight;
mRGBA = new int[mFrameSize];
mBitmap = Bitmap.createBitmap(previewWidtd, previewHeight, Bitmap.Config.ARGB_8888);
}
#Override
protected void onPreviewStopped() {
if(mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
mRGBA = null;
}
#Override
protected Bitmap processFrame(byte[] data) {
int[] rgba = mRGBA;
FindFeatures(getFrameWidth(), getFrameHeight(), data, rgba);
Bitmap bmp = mBitmap;
bmp.setPixels(rgba, 0, getFrameWidth(), 0, 0, getFrameWidth(), getFrameHeight());
return bmp;
}
public native void FindFeatures(int width, int height, byte yuv[], int[] rgba);
}
public abstract class SampleViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private Camera mCamera;
private SurfaceHolder mHolder;
private SurfaceView mViewer;
private int mFrameWidth;
private int mFrameHeight;
private byte[] mFrame;
private boolean mThreadRun;
private byte[] mBuffer;
public SampleViewBase(Context context) {
super(context);
mViewer = (SurfaceView)this.findViewById(R.id.camera_view);
mHolder = mViewer.getHolder();
mHolder.addCallback(this);
}
public int getFrameWidth() {
return mFrameWidth;
}
public int getFrameHeight() {
return mFrameHeight;
}
public boolean openCamera() {
releaseCamera();
mCamera = Camera.open();
if(mCamera == null)
return false;
mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
synchronized (SampleViewBase.this) {
System.arraycopy(data, 0, mFrame, 0, data.length);
SampleViewBase.this.notify();
}
camera.addCallbackBuffer(mBuffer);
}
});
return true;
}
public void releaseCamera() {
mThreadRun = false;
synchronized (this) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
onPreviewStopped();
}
public void setupCamera(SurfaceHolder holder,int width, int height) {
synchronized (this) {
if (mCamera != null) {
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
mFrameWidth = width;
mFrameHeight = height;
// selecting optimal camera preview size
{
int minDiff = Integer.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - height) < minDiff) {
mFrameWidth = size.width;
mFrameHeight = size.height;
minDiff = Math.abs(size.height - height);
}
}
}
params.setPreviewSize(getFrameWidth(), getFrameHeight());
List<String> FocusModes = params.getSupportedFocusModes();
if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
{
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
mCamera.setParameters(params);
/* Now allocate the buffer */
params = mCamera.getParameters();
int size = params.getPreviewSize().width * params.getPreviewSize().height;
size = size * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8;
mBuffer = new byte[size];
/* The buffer where the current frame will be copied */
mFrame = new byte [size];
mCamera.addCallbackBuffer(mBuffer);
try {
mCamera.setPreviewDisplay(holder);
//mCamera.setPreviewDisplay(null);
} catch (IOException e) {}
/* Notify that the preview is about to be started and deliver preview size */
onPreviewStarted(params.getPreviewSize().width, params.getPreviewSize().height);
/* Now we can start a preview */
mCamera.startPreview();
}
}
}
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
setupCamera(_holder,width, height);
}
public void surfaceCreated(SurfaceHolder holder) {
(new Thread(this)).start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
}
//abstract functions used by child class
protected abstract Bitmap processFrame(byte[] data);
protected abstract void onPreviewStarted(int previewWidtd, int previewHeight);
protected abstract void onPreviewStopped();
//================================
public void run() {
mThreadRun = true;
while (mThreadRun) {
Bitmap bmp = null;
synchronized (this) {
try {
this.wait();
bmp = processFrame(mFrame);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (bmp != null) {
Canvas canvas = mHolder.lockCanvas();
if (canvas != null) {
canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2, (canvas.getHeight() - getFrameHeight()) / 2, null);
mHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
I know this must be a MAJOR drag to go through my code, but I really need the help. Or even if I could get a link to a working example of this type of implementation. Also, please just don't send me this link (it doesn't help me):openCV in custom applications

This is my acitivity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="#+id/tutorial1_activity_java_surface_view"
opencv:show_fps="true"
opencv:camera_id="any" />
<org.opencv.android.NativeCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="#+id/tutorial1_activity_native_surface_view"
opencv:show_fps="true"
opencv:camera_id="any" />
<Button
android:id="#+id/btnOK"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="105dp"
android:layout_marginTop="139dp"
android:onClick="OKClicked"
android:text="#string/OK" />
<TextView
android:id="#+id/txtDisp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/btnOK"
android:layout_alignBottom="#+id/btnOK"
android:layout_marginLeft="25dp"
android:layout_toRightOf="#+id/btnOK"
android:text="#string/app_name"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
And these code must be edited to MainActivity.java class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (mIsJavaCamera){
mOpenCvCameraView = (CameraBridgeViewBase)findViewById(R.id.tutorial1_activity_java_surface_view);
}else{
mOpenCvCameraView = (CameraBridgeViewBase)findViewById(R.id.tutorial1_activity_native_surface_view);
}
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
ArrayList<View> views = new ArrayList<View>();
views.add(findViewById(R.id.btnOK));
views.add(findViewById(R.id.txtDisp));
mOpenCvCameraView.addTouchables(views);
}
public void OKClicked(View view){
TextView disp = (TextView)findViewById(R.id.txtDisp);
disp.setText("OK Clicked");
}
This code is modified to OpenCV Tutorial 1.
You will see a button and a TextView over the surfaceview. When you click OK button TextView will show "OK Clicked". This is working for me on Samsung Galaxy.

Related

Change ImageView after choosing photo from Gallery

I am trying to change my imageview when its on click and then choose image from gallery then change it. But I don't think its working since when I tried running my project, it just crashes out of the app.
Navigation Drawer
ActivityResult
ActivityResultLauncher<String> mGetContent = registerForActivityResult(
new ActivityResultContracts.GetContent(),
new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(Uri uri) {
// Handle the returned Uri
}
});
ImageView
profileImage = (ImageView) findViewById(R.id.profilepic);
profileImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mGetContent.launch("image/*");
}
});
p.s. The ImageView is inside my navigation drawer. what I wanted to do is that whenever I click or press the ImageView which is the Hamburger Icon, it will redirect to gallery to choose image and then change it once the user chose one.
MapsActivity.java
public class MapsActivity extends AppCompatActivity implements
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener{
private static final String TAG = "";
private DrawerLayout drawer;
LatLng carWash1 = new LatLng(6.106535, 125.187230);
LatLng carWash2 = new LatLng(6.106123, 125.189280);
private ArrayList<LatLng> locationArrayList;
private ImageView profileImage;
final static int Gallery_Pick = 1;
private GoogleMap mMap;
private ActivityMapsBinding binding;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private Location recentLocation;
private Marker currentMark;
private static final int Request_User_Location = 1234;
private List<Polyline> polylines = null;
protected LatLng start = null;
protected LatLng end = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMapsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkUserLocationPermission();
}
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
locationArrayList = new ArrayList<>();
locationArrayList.add(carWash1);
locationArrayList.add(carWash2);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
super.onBackPressed();
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
public boolean checkUserLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case Request_User_Location:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (googleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
Toast.makeText(this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
return;
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
for (int i = 0; i < locationArrayList.size(); i++) {
mMap.addMarker(new MarkerOptions().position(locationArrayList.get(0)).title("Purok 5 Carwashan").icon(BitMapFromVector(getApplication(), R.drawable.ic_baseline_airplanemode_active_24)));
mMap.addMarker(new MarkerOptions().position(locationArrayList.get(1)).title("Stratford Carwashan").icon(BitMapFromVector(getApplication(), R.drawable.ic_baseline_airplanemode_active_24)));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(locationArrayList.get(i), 15));
mMap.moveCamera(CameraUpdateFactory.newLatLng(locationArrayList.get(i)));
}
boolean success = googleMap.setMapStyle(new MapStyleOptions(getResources()
.getString(R.string.style_json)));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
}
private BitmapDescriptor BitMapFromVector(Context context, int vectorResId) {
// below line is use to generate a drawable.
Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorResId);
// below line is use to set bounds to our vector drawable.
vectorDrawable.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight());
// below line is use to create a bitmap for our
// drawable which we have added.
Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
// below line is use to add bitmap in our canvas.
Canvas canvas = new Canvas(bitmap);
// below line is use to draw our
// vector drawable in canvas.
vectorDrawable.draw(canvas);
// after generating our bitmap we are returning our bitmap.
return BitmapDescriptorFactory.fromBitmap(bitmap);
}
protected synchronized void buildGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
#Override
public void onLocationChanged(#NonNull Location location) {
recentLocation = location;
if (currentMark != null) {
currentMark.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Location!");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
currentMark = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(12));
if (googleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1100);
locationRequest.setFastestInterval(1100);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}

Android setAdapter not working extend fragment

I have an issue while working with a tab1 class extend fragment called from a fragment list. I have done research and information on the use of fragment within a class but right now I cannot get my setAdapter to work in the tab1 class. Below are my codes: the tab1 class and the XML.
public class Tab1Fragment extends Fragment implements AdapterView.OnItemClickListener {
private static final int ADD_NEW_FRIEND_ID = Menu.FIRST;
private static final int SHOW_DETAILS = 3;
private static final int EXIT_APP_ID = Menu.FIRST + 1;
public IAppManager imService = null;
private FriendListAdapter friendAdapter;
private class FriendListAdapter extends BaseAdapter
{
class ViewHolder {
TextView text;
ImageView icon;
}
private LayoutInflater mInflater;
private Bitmap mOnlineIcon;
private Bitmap mOfflineIcon;
private ListView list;
private ListView listView;
private FriendInfo[] friends = null;
public FriendListAdapter(Context context) {
super();
mInflater = LayoutInflater.from(context);
mOnlineIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenstar);
mOfflineIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.redstar);
}
public void setFriendList(FriendInfo[] friends)
{
this.friends = friends;
}
public int getCount() {
return friends.length;
}
public FriendInfo getItem(int position) {
return friends[position];
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.friend_list_screen, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(friends[position].userName);
holder.icon.setImageBitmap(friends[position].status == STATUS.ONLINE ? mOnlineIcon : mOfflineIcon);
return convertView;
}
}
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Broadcast receiver ", "received a message");
Bundle extra = intent.getExtras();
if (extra != null)
{
String action = intent.getAction();
if (action.equals(IMService.FRIEND_LIST_UPDATED))
{
Tab1Fragment.this.updateData(FriendController.getFriendsInfo(),
FriendController.getUnapprovedFriendsInfo());
}
}
}
};
public MessageReceiver messageReceiver = new MessageReceiver();
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((IMService.IMBinder)service).getService();
FriendInfo[] friends = FriendController.getFriendsInfo(); //imService.getLastRawFriendList();
if (friends != null) {
Tab1Fragment.this.updateData(friends, null); // parseFriendInfo(friendList);
}
getActivity().setTitle(imService.getUsername() + "'s friend list");
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
}
};
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.tab1fragment, container, false);
ListView list = (ListView) v.findViewById(R.id.lvn);
return v;
}
void updateData(FriendInfo[] friends, FriendInfo[] unApprovedFriends)
{
if (friends != null) {
friendAdapter.setFriendList(friends);
setAdapter(friendAdapter);
}
if (unApprovedFriends != null)
{
NotificationManager NM = (NotificationManager) getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
if (unApprovedFriends.length > 0)
{
String tmp = new String();
for (int j = 0; j < unApprovedFriends.length; j++) {
tmp = tmp.concat(unApprovedFriends[j].userName).concat(",");
}
Notification notification = new Notification(R.drawable.stat_sample,
getText(R.string.new_friend_request_exist),
System.currentTimeMillis());
Intent i = new Intent(Tab1Fragment.this.getActivity(), UnApprovedFriendList.class);
i.putExtra(FriendInfo.FRIEND_LIST, tmp);
PendingIntent contentIntent = PendingIntent.getActivity(this.getActivity(), 0,
i, 0);
notification.setLatestEventInfo(this.getActivity(), getText(R.string.new_friend_request_exist),
"You have new friend request(s)",
contentIntent);
NM.notify(R.string.new_friend_request_exist, notification);
}
else
{
// if any request exists, then cancel it
NM.cancel(R.string.new_friend_request_exist);
}
}
}
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id){
onItemClick(parent, v, position, id);
// Sensor sensor = sensorAdapter.getItem(AdapterView<?> parent
Intent i = new Intent(Tab1Fragment.this.getActivity(), Messaging.class);
FriendInfo friend = friendAdapter.getItem(position);
if (friend.status == STATUS.ONLINE)
{
i.putExtra(FriendInfo.USERNAME, friend.userName);
// i.putExtra(FriendInfo.ID, friend.uid); // Edit //
i.putExtra(FriendInfo.PORT, friend.port);
i.putExtra(FriendInfo.IP, friend.ip);
startActivity(i);
}
else
{
Toast.makeText(Tab1Fragment.this.getActivity(), R.string.user_offline, Toast.LENGTH_SHORT).show();
}
}
}
The XML for the tab:
<?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:orientation="vertical" >
<ListView
android:id="#+id/lvn"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/no_friend"
android:gravity="center_vertical|center_horizontal"/>
</LinearLayout>

Adding button(Imageview) to viewpager within sliding image activity

I am relatively new to Android development, my background being more php, html5 and the likes. I've studied, continue to take tutorials and am working on my first application which I've practically got the way I want it to be, save one particular item. I hope that you can help me, and to some, it is likely a simple response. But, I've tried and tried and cannot get things to work out without errors.
Basically, the application uses ViewPager, and has SlidingImageActivity as a class, so when images are loaded in full size (clicked from thumbnail) the images can be swiped from screen to screen.
I have action bar items, which rather than show in the overflow bar, I've created Image Button and placed in the xml below for the viewpager. It is the file - fullimageslider.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/grid_back_color"
tools:ignore="RtlHardcoded" >
<android.support.v4.view.ViewPager
android:id="#+id/image_slider"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/menu_zoom"
android:background="#color/grid_back_color" >
</android.support.v4.view.ViewPager>
<ImageButton
android:id="#+id/menu_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#color/grid_back_color"
android:padding="10dp"
android:src="#drawable/save"
android:title="#string/menu_save" />
<ImageButton
android:id="#+id/menu_setaswallpaper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#color/grid_back_color"
android:padding="10dp"
android:src="#drawable/set"
android:title="#string/menu_setaswallpaper" />
<ImageButton
android:id="#+id/menu_zoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="43dp"
android:layout_toRightOf="#+id/menu_share"
android:background="#color/grid_back_color"
android:padding="10dp"
android:src="#drawable/zoom"
android:title="#string/menu_zoom" />
<ImageButton
android:id="#+id/menu_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="32dp"
android:layout_toRightOf="#+id/menu_setaswallpaper"
android:background="#color/grid_back_color"
android:padding="10dp"
android:src="#drawable/share"
android:title="#string/menu_share" />
</RelativeLayout>
I've added the buttons as you can see, below the viewpager. So that they remain on the bottom of the layout as the screen swipes.
My problem is, getting the buttons to function in the SlideImageActivity class. I'm not sure where to change the overflow menu tasks to the button tasks. I have removed the items I've created buttons for from the menu. And changed them into the above.
The following is the current SlideImageActivity class.
public class SlideImageActivity extends SherlockActivity
implements sensorEventListener {
int position;
String[] mAllImages,mAllImageCatName;
public DatabaseHandler db;
ImageView vp_imageview;
ViewPager viewpager;
int TOTAL_IMAGE;
private SensorManager sensorManager;
private boolean checkImage = false;
private long lastUpdate;
Handler handler;
Runnable Update;
boolean Play_Flag=false;
private Menu menu;
private DatabaseManager dbManager;
String Image_catName,Image_Url;
Bitmap bgr;
DisplayImageOptions options;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.fullimageslider);
db = new DatabaseHandler(this);
dbManager = DatabaseManager.INSTANCE;
dbManager.init(getApplicationContext());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher)
.resetViewBeforeLoading(true)
.cacheOnDisc(true)
.imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565)
.considerExifParams(true)
.displayer(new FadeInBitmapDisplayer(300))
.build();
setTitle(Constant.CATEGORY_TITLE);
// Look up the AdView as a resource and load a request.
Intent i=getIntent();
position=i.getIntExtra("POSITION_ID", 0);
mAllImages=i.getStringArrayExtra("IMAGE_ARRAY");
mAllImageCatName=i.getStringArrayExtra("IMAGE_CATNAME");
TOTAL_IMAGE=mAllImages.length-1;
viewpager=(ViewPager)findViewById(R.id.image_slider);
handler=new Handler();
ImagePagerAdapter adapter = new ImagePagerAdapter();
viewpager.setAdapter(adapter);
viewpager.setCurrentItem(position);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
lastUpdate = System.currentTimeMillis();
viewpager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
position=viewpager.getCurrentItem();
Image_Url=mAllImages[position];
List<Pojo> pojolist=db.getFavRow(Image_Url);
if(pojolist.size()==0)
{
menu.getItem(3).setIcon(getResources().getDrawable(R.drawable.fav));
}
else
{
if(pojolist.get(0).getImageurl().equals(Image_Url))
{
menu.getItem(3).setIcon(getResources().getDrawable(R.drawable.fav_hover));
}
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int position) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int position) {
// TODO Auto-generated method stub
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.photo_menu, menu);
this.menu = menu;
//for when 1st item of view pager is favorite mode
FirstFav();
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem menuItem)
{
switch (menuItem.getItemId())
{
case android.R.id.home:
onBackPressed();
return true;
case R.id.menu_back:
position=viewpager.getCurrentItem();
position--;
if (position < 0) {
position = 0;
}
viewpager.setCurrentItem(position);
return true;
case R.id.menu_next:
position=viewpager.getCurrentItem();
position++;
if (position == TOTAL_IMAGE) {
position = TOTAL_IMAGE;
}
viewpager.setCurrentItem(position);
return true;
case R.id.menu_play:
if(Play_Flag)
{
handler.removeCallbacks(Update);
menuItem.setIcon(getResources().getDrawable(R.drawable.play));
Play_Flag=false;
ShowMenu();
}
else
{
/*
* when Play_Flag false then Play
* but when image is last not start auto play
* now hide all menu when auto play start
*/
if(viewpager.getCurrentItem()==TOTAL_IMAGE)
{
Toast.LENGTH_SHORT).show();
}
else
{
AutoPlay();
menuItem.setIcon(getResources().getDrawable(R.drawable.stop));
Play_Flag=true;
HideMenu();
}
}
return true;
case R.id.menu_fav:
position=viewpager.getCurrentItem();
Image_Url=mAllImages[position];
List<Pojo> pojolist=db.getFavRow(Image_Url);
if(pojolist.size()==0)
{
AddtoFav(position);//if size is zero i.e means that record not in database show
add to favorite
}
else
{
if(pojolist.get(0).getImageurl().equals(Image_Url))
{
RemoveFav(position);
}
}
return true;
case R.id.menu_overflow:
//just override click
return true;
case R.id.menu_share:
position=viewpager.getCurrentItem();
(new ShareTask(SlideImageActivity.this)).execute
(Constant.SERVER_IMAGE_UPFOLDER_CATEGORY+mAllImageCatName[position]
+"/"+mAllImages[position]);
return true;
case R.id.menu_save:
position=viewpager.getCurrentItem();
(new SaveTask(SlideImageActivity.this)).execute
(Constant.SERVER_IMAGE_UPFOLDER_CATEGORY+mAllImageCatName[position]
+"/"+mAllImages[position]);
return true;
case R.id.menu_setaswallaper:
position=viewpager.getCurrentItem();
Intent intwall=new intent(getApplicationContext(), SetAsWallpaperActivity.class);
intwall.putExtra("WALLPAPER_IMAGE_URL", mAllImages);
intwall.putExtra("WALLPAPER_IMAGE_CATEGORY", mAllImageCatName);
intwall.putExtra("POSITION_ID", position);
startActivity(intwall);
return true;
case R.id.menu_zoom:
position=viewpager.getCurrentItem();
Intent intzoom=new Intent(getApplicationContext(),PinchZoom.class);
intzoom.putExtra("ZOOM_IMAGE_URL", mAllImages);
intzoom.putExtra("ZOOM_IMAGE_CATEGORY", mAllImageCatName);
intzoom.putExtra("POSITION_ID", position);
startActivity(intzoom);
return true;
default:
return super.onOptionsItemSelected(menuItem);
}
}
//add to favorite
public void AddtoFav(int position)
{
Image_catName=mAllImageCatName[position];
Image_Url=mAllImages[position];
db.AddtoFavorite(new Pojo(Image_catName, Image_Url));
Toast.makeText(getApplicationContext(),
"Added to Favorite", Toast.LENGTH_SHORT).show();
menu.getItem(3).setIcon(getResources().getDrawable(R.drawable.fav_hover));
}
//remove from favorite
public void RemoveFav(int position)
{
Image_Url=mAllImages[position];
db.RemoveFav(new Pojo(Image_Url));
Toast.makeText(getApplicationContext(), "Removed from
Favorite",Toast.LENGTH_SHORT).show();
menu.getItem(3).setIcon(getResources().getDrawable(R.drawable.fav));
}
//auto play slide show
public void AutoPlay()
{
Update=new Runnable() {
#Override
public void run() {
AutoPlay();
// TODO Auto-generated method stub
position=viewpager.getCurrentItem();
position++;
if (position == TOTAL_IMAGE) {
position = TOTAL_IMAGE;
handler.removeCallbacks(Update);//when last image play mode goes to Stop
Toast.makeText(getApplicationContext(), "Last Image Auto Play Stoped",
Toast.LENGTH_SHORT).show();
menu.getItem(1).setIcon(getResources().getDrawable(R.drawable.play));
Play_Flag=false;
//Show All Menu when Auto Play Stop
ShowMenu();
}
viewpager.setCurrentItem(position);
}
};
handler.postDelayed(Update, 1500);
}
public void ShowMenu()
{
menu.getItem(0).setVisible(true);
menu.getItem(2).setVisible(true);
menu.getItem(3).setVisible(true);
menu.getItem(4).setVisible(true);
}
public void HideMenu()
{
menu.getItem(0).setVisible(false);
menu.getItem(2).setVisible(false);
menu.getItem(3).setVisible(false);
menu.getItem(4).setVisible(false);
}
public void FirstFav()
{
int first=viewpager.getCurrentItem();
String Image_id=mAllImages[first];
List<Pojo> pojolist=db.getFavRow(Image_id);
if(pojolist.size()==0)
{
menu.getItem(3).setIcon(getResources().getDrawable(R.drawable.fav));
}
else
{
if(pojolist.get(0).getImageurl().equals(Image_id))
{
menu.getItem(3).setIcon(getResources().getDrawable(R.drawable.fav_hover));
}
}
}
private class ImagePagerAdapter extends PagerAdapter {
private LayoutInflater inflater;
public ImagePagerAdapter() {
// TODO Auto-generated constructor stub
inflater = getLayoutInflater();
}
#Override
public int getCount() {
return mAllImages.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View imageLayout = inflater.inflate(R.layout.viewpager_item, container, false);
assert imageLayout != null;
ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image);
final ProgressBar spinner =(ProgressBar)imageLayout.findViewById(R.id.loading);
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault
(getApplicationContext()));
ImageLoader.getInstance().displayImage(Constant.SERVER_IMAGE_UPFOLDER_CATEGORY
+mAllImageCatName[position]+"/"+mAllImages[position], imageView, options, new
SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
spinner.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason
failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
Toast.makeText(SlideImageActivity.this, message,
Toast.LENGTH_SHORT).show();
spinner.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
spinner.setVisibility(View.GONE);
}
});
container.addView(imageLayout, 0);
return imageLayout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
getAccelerometer(event);
}
}
private void getAccelerometer(SensorEvent event) {
float[] values = event.values;
// Movement
float x = values[0];
float y = values[1];
float z = values[2];
float accelationSquareRoot = (x * x + y * y + z * z)
/ (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
long actualTime = System.currentTimeMillis();
if (accelationSquareRoot >= 2) //
{
if (actualTime - lastUpdate < 200) {
return;
}
lastUpdate = actualTime;
// Toast.makeText(this, "Device was shuffed", Toast.LENGTH_SHORT)
// .show();
if (checkImage) {
position=viewpager.getCurrentItem();
viewpager.setCurrentItem(position);
} else {
position=viewpager.getCurrentItem();
position++;
if (position == TOTAL_IMAGE) {
position = TOTAL_IMAGE;
}
viewpager.setCurrentItem(position);
}
checkImage = !checkImage;
}
}
#Override
protected void onResume() {
super.onResume();
// register this class as a listener for the orientation and
// accelerometer sensors
if(dbManager == null){
dbManager = DatabaseManager.INSTANCE;
dbManager.init(getApplicationContext());
}else if(dbManager.isDatabaseClosed()){
dbManager.init(getApplicationContext());
}
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
// unregister listener
super.onPause();
if(!dbManager.isDatabaseClosed())
dbManager.closeDatabase();
sensorManager.unregisterListener(this);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(Update);
sensorManager.unregisterListener(this);
if(dbManager != null)dbManager.closeDatabase();
}
public class SaveTask extends AsyncTask<String , String , String>
{
private Context context;
private ProgressDialog pDialog;
String image_url;
URL myFileUrl;
String myFileUrl1;
Bitmap bmImg = null;
File file ;
public SaveTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pDialog = new ProgressDialog(context);
pDialog.setMessage("Downloading Image ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
// TODO Auto-generated method stub
try {
myFileUrl = new URL(args[0]);
//myFileUrl1 = args[0];
HttpURLConnection conn = (HttpURLConnection)
myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
}
catch (IOException e)
{
e.printStackTrace();
}
try {
String path = myFileUrl.getPath();
String idStr = path.substring(path.lastIndexOf('/') + 1);
File filepath = Environment.getExternalStorageDirectory();
File dir = new File (filepath.getAbsolutePath() + "/EC Images/");
dir.mkdirs();
String fileName = idStr;
file = new File(dir, fileName);
FileOutputStream fos = new FileOutputStream(file);
bmImg.compress(CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String args) {
// TODO Auto-generated method stub
Toast.makeText(SlideImageActivity.this, "Image Saved Succesfully /",
Toast.LENGTH_SHORT).show();
pDialog.dismiss();
}
}
public class ShareTask extends AsyncTask<String , String , String>
{
private Context context;
private ProgressDialog pDialog;
String image_url;
URL myFileUrl;
String myFileUrl1;
Bitmap bmImg = null;
File file ;
public ShareTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pDialog = new ProgressDialog(context);
pDialog.setMessage("Please Wait ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
// TODO Auto-generated method stub
try {
myFileUrl = new URL(args[0]);
//myFileUrl1 = args[0];
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
}
catch (IOException e)
{
e.printStackTrace();
}
try {
String path = myFileUrl.getPath();
String idStr = path.substring(path.lastIndexOf('/') + 1);
File filepath = Environment.getExternalStorageDirectory();
File dir = new File (filepath.getAbsolutePath() + "/HD Wallpaper/");
dir.mkdirs();
String fileName = idStr;
file = new File(dir, fileName);
FileOutputStream fos = new FileOutputStream(file);
bmImg.compress(CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String args) {
// TODO Auto-generated method stub
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/jpeg");
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + file.getAbsolutePath()));
startActivity(Intent.createChooser(share, "Share Image"));
pDialog.dismiss();
}
}
}
As you can see the code implements the menu items, Share, Set as Wallpaper, Save and Zoom. These are the Imagebuttons I -want- to use and have set up on the above xml layout.
This is what I have for the buttons. But I have no idea where or how to add this, implement it into the ImageSliderActivity class.
Button clickButton = (Button) findViewById(R.id.menu_share);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
position=viewpager.getCurrentItem();
(new shareTask(SlideImageActivity.this)).execute(Constant.
SERVER_IMAGE_UPFOLDER_CATEGORY+
mAllImageCatName[position]+"/"+mAllImages[position]);
return true;
Button clickButton = (Button) findViewById(R.id.menu_save);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {position=viewpager.getCurrentItem();
newSaveTask(SlideImageActivity.this)).execute(Constant.SERVER_IMAGE_UPFOLDER_CATEGORY
+mAllImageCatName[position]+"/"+mAllImages[position]);
return true;
Button clickButton = (Button) findViewById(R.id.menu_setaswallpaper);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {position=viewpager.getCurrentItem();
Intent intwall=new Intent(getApplicationContext(),SetAsWallpaperActivity.class);
intwall.putExtra("WALLPAPER_IMAGE_URL", mAllImages);
intwall.putExtra("WALLPAPER_IMAGE_CATEGORY", mAllImageCatName);
intwall.putExtra("POSITION_ID", position);
startActivity(intwall);
return true;
Button clickButton = (Button) findViewById(R.id.menu_zoom);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
position=viewpager.getCurrentItem();
Intent intzoom=new Intent(getApplicationContext(),PinchZoom.class);
intzoom.putExtra("ZOOM_IMAGE_URL", mAllImages);
intzoom.putExtra("ZOOM_IMAGE_CATEGORY", mAllImageCatName);
intzoom.putExtra("POSITION_ID", position);
startActivity(intzoom);
return true;`
I hope I've made sense.If some one could please guide me in the right direction, I would greatly appreciate the help. Basically, I want to remove the overflow menu during the slidingimage activity, and use buttons at the bottom of the layout instead to implement those items. The layout works in the emulator and causes no error, but obviously when the buttons are clicked, nothing happens because I don't know where to add the button portion to the sliding activity class, without causing multiple errors.
Thanks so much for your time in advance!

ActionBar tabs with MapView

I've created app using SherlockActionBar tab. One with my tabs contains MapView (Google Maps v2). Currently I have problem when I change tabs (screen below):
enter link description here
Next tab should contain ListView. Sometimes context second tab loaded correctly. Also I have problem with swiping my MapView. Currently I can only swiping up and down direction. I hope that somebody help me.
My code:
myfragment.xml
<com.google.android.gms.maps.MapView
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
TabFragment_Map.java
public class TabFragment_Map extends SherlockFragment {
MapView mapView;
GoogleMap map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.map_fragment, container, false);
mapView = (MapView) view.findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
map = mapView.getMap();
map.getUiSettings().setMyLocationButtonEnabled(false);
map.setMyLocationEnabled(true);
try {
MapsInitializer.initialize(this.getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
return view;
}
#Override
public void onResume() {
mapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
#Override
public void onLowMemory() {
mapView.onLowMemory();
super.onLowMemory();
}
}
MainActivity.java
public class MainActivity extends SherlockFragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
String TabFragment_Cafes;
String TabFragment_Details;
//Settery & gettery używane w mechanizmie przesyłania informacji pomiędzy fragmentami
public String getTabFragment_Cafes() {
return TabFragment_Cafes;
}
public void setTabFragment_Cafes(String tabFragment_Cafes) {
TabFragment_Cafes = tabFragment_Cafes;
}
public String getTabFragment_Details() {
return TabFragment_Details;
}
public void setTabFragment_Details(String tabFragment_Details) {
TabFragment_Details = tabFragment_Details;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
final ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.DISPLAY_SHOW_HOME);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Mapa"), TabFragment_Map.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Kawiarnie"), TabFragment_Cafes.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Szczegóły"), TabFragment_Details.class, null);
if (savedInstanceState != null)
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
#Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = ((SherlockFragmentActivity)activity).getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
public void onPageScrollStateChanged(int arg0) {}
public void onPageScrolled(int arg0, float arg1, int arg2) {}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag)
mViewPager.setCurrentItem(i);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public int getCount() {
return mTabs.size();
}
}
}
You need a custom viewpager that intercepts the swipes
package com.ecs.google.maps.v2.component;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
// When using Maps V1
// if(v instanceof MapView){
// return true;
// }
// return super.canScroll(v, checkV, dx, x, y);
// When using Maps V2
if (v.getClass().getPackage().getName().startsWith("maps.")) {
return true;
}
return super.canScroll(v, checkV, dx, x, y);
}
}
Put this in your layout :
<com.ecs.google.maps.v2.component.CustomViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tabs"
tools:context=".MainActivity">
And the swiping gestures should work.

Moving ball with accelerometer inside a view on camera preview in android

I have been searching and coding for 3 days now on this problem, no result :(
I made a camera overlay which the code is here + the Accelerometer
public class CameraActivity extends Activity implements SurfaceHolder.Callback, SensorEventListener {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
static String TAG = CameraActivity.class.getSimpleName();
// Accelerometer
private SensorManager mSensorManager;
private Sensor mAccelerometer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.surface_view);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.camera_control,
null);
LayoutParams layoutParamsControl = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.addContentView(viewControl, layoutParamsControl);
// Accelerometer
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent event) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
Then in the camera_control.xml I have this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_holder"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent"
android:gravity="bottom" >
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/camera_red_button"
android:layout_alignLeft="#+id/camera_back_button"
android:layout_marginBottom="27dp"
android:src="#drawable/camera_accelerometer_red" />
</RelativeLayout>
and in the surface_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/camerapreview_holder"
>
<SurfaceView
android:id="#+id/camerapreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
The Image View is a image for spirit level.
The idea is user needs to level the camera before she takes a photo. I have cleared all the un-nessessery code. The above code are working code.
Question:
I need to make a ball for the spirit level. it doesnt need to be the smoothest spirit level. If I can find the way to confine the ball within the spirit level and move it based on the Accelerometer results I will be as happy as Larry :)/
If someone please put me in the right direction regarding these 3 things:
confining the animation within an area
confinement area to be Circle, how to make it
Thanks in advance.
H.
Ok I have got the answer. Hope it can help someone. You need to use calculate the distance from the middle to the corner (radius) the offset the corners.
Also I have change the Accelerometor to Orientation Sensor which then I can get the 3d rotation of the phone in the X and Y Axis.
The following code is working code and I tested them. I am using the Android 2.3.3+
The ball movement is not very smooth as this is not the purpose of the application.
I think in order to smooth the movement you might need to add the timer and collision detection to it too. Please check the android sample.
I haven't refactor the code too yet. So this is not a production level code :)
Codes:
public class CameraActivity extends Activity implements SurfaceHolder.Callback,
SensorEventListener {
// Accelerometer
private SensorManager mSensorManager;
private Sensor mAccelerometer;
/** Called when the activity is first created. */
public static float x;
public static float y;
FrameLayout layout_holder;
FrameLayout ball_holder;
// private float hOriginSize;
float halfOfWidth;
int centerYOnImage;
private Sensor mOrientation;
// float viewInset = 14.0f; // I remove this simply to make the code cleaner. I used this to calculate the radius and the offset later on
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.surface_view);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.camera_control,
null);
LayoutParams layoutParamsControl = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.addContentView(viewControl, layoutParamsControl);
// Accelerometer
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ball);
CustomDrawableView mCustomDrawableView = new CustomDrawableView(this,
bitmap);
ball_holder = (FrameLayout) findViewById(R.id.ball_holder);
ball_holder.addView(mCustomDrawableView);
halfOfWidth = 40; // You can calculate this, I just put this so I can test it. This is the half of the width of target image - attached in the question
centerYOnImage = 40; // Not important :)
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
// This method will update the UI on new sensor events
public void onSensorChanged(SensorEvent event) {
// float azimuth_angle = event.values[0];
x = event.values[1];
y = event.values[2];
// FIXME: Fine tune this for the image taking part
float ratio = 70.0f / 25.0f;
x = x * ratio;
y = y * ratio;
Log.d(TAG, "x and y: " + x + " " + y);
float maxDistance = 35; // To calculate this halfOfWidth - viewInset;
// to calculate between 2 distances
float distance = (float) Math.sqrt(((x) * (x)) + ((y) * (y)));
if (distance > maxDistance) {
float angle = (float) Math.atan2(x, y);
/ Get new point on the edge of the circle
y = (float) (Math.cos(angle) * maxDistance);
x = (float) (Math.sin(angle) * maxDistance);
}
x = x + 40; // 40 is the half od the distance of the full width
y = (y * -1.0f) + 40; // -1.0f is so orientation works like the actual spirit level
canUserTakePhoto(distance);
}
// Change the background
public void canUserTakePhoto(float treshold) {
if (treshold > 10) {
// Not Yet
} else {
// take it
}
}
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mOrientation,
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public class CustomDrawableView extends ImageView {
Bitmap b;
public CustomDrawableView(Context context, Bitmap bitmap) {
super(context);
this.b = bitmap;
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(this.b, x, y, null);
invalidate();
}
}
#Override
public void onDestroy() // main thread stopped
{
super.onDestroy();
// wait for threads to exit before clearing app
System.runFinalizersOnExit(true);
// remove app from memory
android.os.Process.killProcess(android.os.Process.myPid());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
Cheers.

Resources