[APP] Floating Camera [v1.000.00.1r][4.0.+][Tutorial][SourceCode] - Android Apps and Games

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Free to Take Quick Picture Over other Apps​
/*
* This is Camera Application in Overlay Window (Floating View)
* that Allow users to move app around screen & also use another apps in background
*/
Current Feature;
+ Switch (Switch Camera Back/Front)
(There is 3 options in menu)
+ Focus (Apply Auto Focus to Clear View)
+ Torch (Turn On the flash)
+ Close
+ More Feature Coming Soon...
NOTE: There is auto mode bind in capture process; Auto-Focus, Auto-Flash, Auto-Scene
So just need to launch the app and capture...
NOTE: I will release it on Geeks Empire account on Google Play Store asap.
### Let Start Coding ###​
What you need is ability to create Hello World! project
Click to expand...
Click to collapse
& By Reading this Tutorial & Use SourceCode you will learn How to Make;
Camera + Services + Overlay Windows + File I/O + Popup Menu & etc.
Click to expand...
Click to collapse
- from Bottom to Top
* First of All you need to set Permissions & declare classes in Manifest.xml
Code:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<!-- This permission is for Overlay Window -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
* Now you need to declare 2 Services & 2 Classes (Check Source Code)
Services are for Back/Front Camera View
Classes are for controlling as helper
* Then you need to add required components into layouts
To Add Camera View you need to define FrameLayout in layout & some Buttons as Shutter, Switch & Menu. (Check Source Code)
to have more control I made two layouts for Back/Front Camera View.
Code:
...
<FrameLayout
android:id="@+id/previewFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/menumode"
android:layout_width="15dp"
android:layout_height="40dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_marginTop="2dp"
android:layout_marginRight="8dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="@drawable/ic_menu_more" />
<Button
android:id="@+id/capture"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:background="@drawable/capturing" />
<Button
android:id="@+id/sw"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="@drawable/ic_switch" />
...
* After that you should work on classes.
In Main.Class Activity there just few line to perform startService(INTENT);
(I just Set this for future developments.)
Code:
Intent s = new Intent(Main.this, FloatingCamera_Back.class);
s.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(s);
* So we should work on Service Class.
NOTE: Also you need to create class to handle Preview of Camera. (Check Source Code)
Code:
public class FloatingCamera_Back extends Service{
WindowManager windowManager; //WindowManager for adding View to SYSTEM_ALERT_WINDOW
ViewGroup vG; //ViewGroup of layout
Context context;
Camera mCamera;
Preview mPreview;
Button capture, flash, menu, sw;
byte[] pictureBytes; //for captured data from camera lens
String mCurrentPhotoPath;
private static final String TAG = "Floating_Camera";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
[COLOR="Red"]// I set Everything I need for Camera & Capturing process here[/COLOR]
}
}
All these Codes should place in onStartCommand()
Now you need to setup Overlay Window
Code:
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
//Change int Value of size to dp
int H = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 320, this.getResources().getDisplayMetrics());
int w = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 220, this.getResources().getDisplayMetrics());
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
w,
H,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 10;
params.y = 100;
& after this you should add view to WindowManager, So define & find remote ViewGroup
Code:
//Define View
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vG = (ViewGroup)layoutInflater.inflate(R.layout.full_back, null, false);
windowManager.addView(vG, params);
here you can find component inside layout like buttons
Code:
capture = (Button)vG.findViewById(R.id.capture);
menu = (Button)vG.findViewById(R.id.menumode);
sw = (Button)vG.findViewById(R.id.sw);
after setting up the GUI components it s time to work on Camera & add Preview to FrameLayout
Code:
mCamera = getCameraInstance(); //It is function that check & open camera
mPreview = new Preview(this, mCamera);
FrameLayout preview = (FrameLayout) vG.findViewById(R.id.previewFrame);
preview.addView(mPreview);
Up to here Floating Window popped up & showing Camera view
so you need to capture that view
Code:
capture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
//Highly Recommend to [FONT="Impact"](Check Source Code)[/FONT]
}
});
mPicture is PictureCallBack that handle captured data and write it to file. Check out following codes & comments;
Code:
public static final int MEDIA_TYPE_IMAGE = 1;
private File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Floating_Camera");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("CameraW", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String timeStampshort = new SimpleDateFormat("_HHmmss").format(new Date());
File mediaFile = null;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp);
}
else {
return null;
}
mCurrentPhotoPath = mediaFile.getAbsolutePath();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
galleryAddPic();
}
}, 300);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
galleryAddPicPort();
}
}, 300);
return mediaFile;
}
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
//
return;
}
/***/ // NOTE: Handle the image rotation after saving the file.
///////////////////////////////////Portrait
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inSampleSize = 2;
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
int w = bm.getWidth();
int h = bm.getHeight();
Matrix mtx = new Matrix();
mtx.setRotate(90);
bm = Bitmap.createBitmap(bm, 0, 0, w, h, mtx, true);
//byte[] pictureBytes;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bm.compress(CompressFormat.JPEG, 100, bos);
pictureBytes = bos.toByteArray();
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(pictureBytes);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
} finally {
mCamera.startPreview();
}
}
/////////////////////////////////////Landscape
else{
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}finally {
mCamera.startPreview();
}
}
}
};
That's it.
The Captured Data from Camera View in Floating Windows saved into files
Also there is some additional functions that are handling Flash_Torch_Mode, Auto_Focus & etc.
* Also to have real meaning floating window user should be able to move it around screen. so u set touchListener for ViewGroup (to move whole view together)
Code:
vG.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams paramsF = params;
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
System.out.println("Touch ACTION_DOWN");
initialX = paramsF.x;
initialY = paramsF.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
System.out.println("Touch ACTION_UP");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("Touch ACTION_MOVE");
paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(vG, paramsF);
break;
}
return false;
}
});
NOTE: onDestroy >> Do NOT forget to release camera & stop the service
Code:
@Override
public void onDestroy() {
super.onDestroy();
if (vG != null) {
windowManager.removeView(vG);
stopService(new Intent(getApplicationContext(), FloatingCamera_Back.class));
releaseCamera(); //[FONT="Impact"](Check Source Code)[/FONT]
}
}
Download SourceCode & APK & Enjoy
If you find any mistake Or issue in my codes Please inform me.
Click to expand...
Click to collapse
Don't forget to Hit Thanks​
XDA:DevDB Information
Floating Camera, App for all devices (see above for details)
Contributors
Geeks Empire
Source Code: http://forum.xda-developers.com/attachment.php?attachmentid=3327564&stc=1&d=1432386596
Version Information
Status: Stable
Current Stable Version: 1.000.00.1r
Stable Release Date: 2015-05-20
Created 2015-05-23
Last Updated 2017-03-16

Info
Source Code Download
APK file Download
Check out CameraW+ (Voice Command & Floating View)
​
Thanks for Supporting GeeksEmpire projects
​

Info
New Update
Download APK​
Code:
v...2r
+ Switch Camera /Improve Performance
+ GUI Changes
Don't Forget to Hit Thanks​

Info
New Update
CameraW+ [Voice Command]
v1.800.50.6+ ​
Code:
v....6
+ Floating Camera Back/Selfie (for All Android 4.1.+ Devices)
+ GUI Changes
Don't Forget to Hit Thanks​

Info
HOW TO Create Floating Widget
To Add Floating Widget all part should configure as a normal shortcut or better to say a view.
First you define View & Add to WindowManager. But an extra Step for Widgets is defining AppWidgetManager to get WidgetID & WidgetView for attaching.
Check Out the SourceCode of Floating Shortcuts Application.
Thanks for Supporting GeeksEmpire projects
​Don't Forget To Hit Thanks​

how is this done with api 21?

sg87 said:
how is this done with api 21?
Click to expand...
Click to collapse
I don't get your question?
If you have a problem in code of tutorial please, mention code.
:good:

Related

[Q][DEV]Android Development Maps Question

I'm trying to develop (for the liveview) using an SDK and need to get a bitmap of Google Maps.
Code:
//Map Section
public class myMap extends MapActivity {
MapView mapView;
Bitmap bitmap;
boolean created = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
createMap();
}
public void createMap()
{
// build map and mark point
mapView = new MapView(this, "keykeykeykeykeykey");
mapView.setBuiltInZoomControls(false);
GeoPoint point = new GeoPoint(52242730,-884211);
mapView.getController().animateTo(point);
mapView.preLoad();
// copy MapView to canvas
bitmap = Bitmap.createBitmap(400, 800, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
mapView.draw(canvas);
PluginUtils.sendTextBitmap(mLiveViewAdapter, mPluginId, "Loading Map...", 128, 12);
created = true;
}
public void displayMap()
{
if (created == false)
{
createMap();
}
//Display map on device
Bitmap mybit = Bitmap.createBitmap(128, 128, Bitmap.Config.ARGB_8888);
for(int i = 0; i < 128; i++)
{
for(int j = 0; j < 128; j++)
{
mybit.setPixel(i, j, bitmap.getPixel(i, j));
}
}
//white pixel for debugging
mybit.setPixel(64, 64, Color.WHITE);
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
Is what I've got so far, the code in createMap() was in onCreate() but It didn't seem to be called.
Now it just force closes.
Anyone know how to help? Is there a better place to ask development questions?
Thanks.
-=Edit=-
Oh, and here's the routine calling the map thing, every couple of seconds.
Code:
private class Timer implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
myMap theMap = new myMap();
theMap.displayMap();
}
}
Okay, looks like you cant use google street map like this.
Anyone looking for similar solution, I used open street map and downloaded 'slipery tiles' png's. They provide java routines for finding the tile url from lat/lon.
http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

Why my items are not redrawn after invoking `invalidateViews()` ?

Why my items are not redrawn after invoking `invalidateViews()` ?
I ask because i try to refresh `listItems` after a bg-thread notify an image rsc was downloaded.
But nothing is updated. Only after exiting and re-entering the new icons are drawn.
I have an activity with `adapter` of type `SettingValueAdapter extends BaseAdapter`
it has a member:
`private SettingsValue[] values;`
it has two interesting methods:
@override
public View getView(int position, View view, ViewGroup parent) {
AddressItem ai= (AddressItem)getItem(position);
DriveToNativeManager dnm = DriveToNativeManager.getInstance();
if (view == null) {
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.address_item, null);
}
view.setTag(R.id.addressItem,ai);
view.setTag(position);
view.findViewById(R.id.fullAddressItemCol).setVisibility(View.VISIBLE);
view.findViewById(R.id.addressItemTouch).setVisibility(View.GONE);
view.findViewById(R.id.addressItemImage).setVisibility(View.GONE);
if (ai != null) {
...
}
view.findViewById(R.id.addressItemIconLayout).setVisibility(View.VISIBLE);
Drawable icon = ResManager.GetSkinDrawable(ai.getIcon() + ".bin");
((ImageView)view.findViewById(R.id.addressItemIcon)).setImageDrawable(icon);
..
}
I attach a callback to the bg-thread (c language) image downloading process.
The callback switches to the ui-thread and calls this `refreshList`:
public void refreshSearchIconsOnSearchActivity() {
Runnable refreshViewEvent = new Runnable() {
@override
public void run() {
Activity currentActivity = AppService.getActiveActivity();
if (currentActivity instanceof SearchActivity) {
Log.d("w", "refreshSearchIconsOnSearchActivity callback running in thread "
+ Thread.currentThread().getId() );
//results list
((SearchActivity) currentActivity).refreshList();
}
}
};
AppService.Post(refreshViewEvent);
}
However, the images are done downloading and are not refreshed on the activity.
They are refreshed only when I leave an re-enter the activity.
What am I missing?

[TUT] SmartWatch App Development - Part 4 - Beginner

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
In previous article, we looked at Notification API with Hello SmartWatch demo. In this article, we will focus on Control API.
http://forum.xda-developers.com/smartwatch/sony/tut-introduction-smart-watch-t2807896
http://forum.xda-developers.com/smartwatch/sony/tut-smartwatch-app-development-part-2-t2807954
http://forum.xda-developers.com/smartwatch/sony/tut-smartwatch-app-development-part-3-t2807966
Control API is responsible for
Extension lifecycle: It allows you to start and stop extension using Intent. Extension means SmartWatch Host application.
Control.Intents.CONTROL_START_INTENT
Control.Intents.CONTROL_STOP_INTENT.
Controlling the display: Normally we don't require to control the display. Default screen state is "Auto", for the specific need you can change screen state by using Intent.
Control.Intents.SCREEN_STATE_OFF
Control.Intents.SCREEN_STATE_AUTO
Control.Intents.SCREEN_STATE_DIM
Control.Intents.SCREEN_STATE_ON
Controlling the LEDs: It used to switch on /off LEDs based on notification.
Control.Intents.CONTROL_LED_INTENT
Controlling the vibrator: It allows you to vibrate SmartWatch.
Control.Intents.CONTROL_VIBRATE_INTENT
Key event: It is used to capture hardware key i.e. home, back and menu key, which is available in SmartWatch2.
Control.Intents.CONTROL_KEY_EVENT_INTENT
Touch event: It is used to capture touch events.
Control.Intents.CONTROL_TOUCH_EVENT_INTENT
Control.Intents.CONTROL_SWIPE_EVENT_INTENT
Control.Intents.CONTROL_OBJECT_CLICK_EVENT_INTENT
Sony's Add-on SDK version 2.0 supports ListView and GridView but this article focuses on basic controls only. For the demo I will create a simple layout with ImageView and TextView. I will animate ImageView with thread and also capture onClick event of ImageView.
Screen Shots
Open Accessory emulator and select SmartWatch 2
Select Control API
Select Hello SmartWatch Extension
Enjoy dancing android
Click on Android will fire onClick event from host app to extension app
Click on menu hardware button to make menu item visible.
Step 1: Create java class named "HelloControlSmartWatch2.java" and extend with ControlExtension.
Code:
package com.kpbird.hellosmartwatch;
import android.content.Context;
import android.location.Address;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;
import com.sonyericsson.extras.liveware.aef.control.Control;
import com.sonyericsson.extras.liveware.extension.util.control.ControlExtension;
import com.sonyericsson.extras.liveware.extension.util.control.ControlObjectClickEvent;
import com.sonyericsson.extras.liveware.extension.util.control.ControlTouchEvent;
import com.sonyericsson.extras.liveware.extension.util.control.ControlView;
import com.sonyericsson.extras.liveware.extension.util.control.ControlView.OnClickListener;
import com.sonyericsson.extras.liveware.extension.util.control.ControlViewGroup;
public class HelloControlSmartWatch2 extends ControlExtension {
private static final int ANIMATION_DELTA_MS = 500;
private static final int MENU_ITEM_0 = 0;
private static final int MENU_ITEM_1 = 1;
private static final int MENU_ITEM_2 = 2;
private boolean mIsShowingAnimation = false;
private Animation mAnimation = null;
private Handler mHandler;
private ControlViewGroup mLayout = null;
private String TAG = this.getClass().getSimpleName();
private Bundle[] mMenuItemsText = new Bundle[3];
public HelloControlSmartWatch2(Context context, String hostAppPackageName,Handler handler) {
super(context, hostAppPackageName);
if (handler == null) {
throw new IllegalArgumentException("handler == null");
}
mHandler = handler;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.hello_control_2, null);
mLayout = parseLayout(layout);
if(mLayout !=null){
ControlView androidAnim = mLayout.findViewById(R.id.imgHelloControl);
androidAnim.setOnClickListener(new OnClickListener() {
@Override
public void onClick() {
Toast.makeText(mContext, "Button Clicked", Toast.LENGTH_LONG).show();
Log.i(TAG, "Android Button Clicked");
toggleAnimation();
}
});
}
mMenuItemsText[0] = new Bundle();
mMenuItemsText[0].putInt(Control.Intents.EXTRA_MENU_ITEM_ID, MENU_ITEM_0);
mMenuItemsText[0].putString(Control.Intents.EXTRA_MENU_ITEM_TEXT, "Item 1");
mMenuItemsText[1] = new Bundle();
mMenuItemsText[1].putInt(Control.Intents.EXTRA_MENU_ITEM_ID, MENU_ITEM_1);
mMenuItemsText[1].putString(Control.Intents.EXTRA_MENU_ITEM_TEXT, "Item 2");
mMenuItemsText[2] = new Bundle();
mMenuItemsText[2].putInt(Control.Intents.EXTRA_MENU_ITEM_ID, MENU_ITEM_2);
mMenuItemsText[2].putString(Control.Intents.EXTRA_MENU_ITEM_TEXT, "Item 3");
}
@Override
public void onResume() {
super.onResume();
showLayout(R.layout.hello_control_2, null);
startAnimation();
}
@Override
public void onPause() {
super.onPause();
stopAnimation();
}
@Override
public void onDestroy() {
stopAnimation();
mHandler = null;
};
public static int getSupportedControlWidth(Context context) {
return context.getResources().getDimensionPixelSize(R.dimen.smart_watch_2_control_width);
}
public static int getSupportedControlHeight(Context context) {
return context.getResources().getDimensionPixelSize(R.dimen.smart_watch_2_control_height);
}
@Override
public void onTouch(ControlTouchEvent event) {
Log.i(TAG, "onTouch() " + event.getAction());
}
@Override
public void onObjectClick(ControlObjectClickEvent event) {
Log.i(TAG, "onObjectClick() " + event.getClickType());
if (event.getLayoutReference() != -1) {
mLayout.onClick(event.getLayoutReference());
}
}
@Override
public void onKey(int action, int keyCode, long timeStamp) {
Log.i(TAG, "onKey() " + action + "\t" + keyCode + "\t" + timeStamp);
if (action == Control.Intents.KEY_ACTION_RELEASE
&& keyCode == Control.KeyCodes.KEYCODE_OPTIONS) {
showMenu(mMenuItemsText);
}
}
@Override
public void onMenuItemSelected(int menuItem) {
Log.d(TAG, "onMenuItemSelected() - menu item " + menuItem);
if (menuItem == MENU_ITEM_0) {
clearDisplay();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
onResume();
}
}, 1000);
}
}
private void toggleAnimation() {
if (mIsShowingAnimation) {
stopAnimation();
}
else {
startAnimation();
}
}
private void startAnimation() {
if (!mIsShowingAnimation) {
mIsShowingAnimation = true;
mAnimation = new Animation();
mAnimation.run();
}
}
private void stopAnimation() {
if (mIsShowingAnimation) {
// Stop animation on accessory
if (mAnimation != null) {
mAnimation.stop();
mHandler.removeCallbacks(mAnimation);
mAnimation = null;
}
mIsShowingAnimation = false;
}
}
private class Animation implements Runnable {
private int mIndex = 1;
private boolean mIsStopped = false;
Animation() {
mIndex = 1;
}
public void stop() {
mIsStopped = true;
}
@Override
public void run() {
int resourceId;
switch (mIndex) {
case 1:
resourceId = R.drawable.dancing_android_0;
break;
case 2:
resourceId = R.drawable.dancing_android_1;
break;
default:
Log.e(TAG, "mIndex out of bounds: " + mIndex);
resourceId = R.drawable.dancing_android_0;
break;
}
mIndex++;
if (mIndex > 2) {
mIndex = 1;
}
if (!mIsStopped) {
updateAnimation(resourceId);
}
if (mHandler != null && !mIsStopped) {
mHandler.postDelayed(this, ANIMATION_DELTA_MS);
}
}
private void updateAnimation(int resourceId) {
sendImage(R.id.imgHelloControl, resourceId);
}
};
}
Step 2: Open HelloExtensionService.java and override "createExtensionControl" method. In this method we need to identify accessory type before creating object of HelloControlSmartWatch2 class. To identify accessory type ExtensionUtils class has method named "DeviceInfoHealper".
Code:
@Override
public ControlExtension createControlExtension(String hostAppPackageName) {
// First we check if the API level and screen size required for
// SampleControlSmartWatch2 is supported
boolean advancedFeaturesSupported = DeviceInfoHelper.isSmartWatch2ApiAndScreenDetected(this, hostAppPackageName);
if (advancedFeaturesSupported) {
return new HelloControlSmartWatch2(this,hostAppPackageName, new Handler());
} else {
return null;
}
}
Step 3: Open HelloRegistrationInformation.java and change return value from 0 to 2 of "getRequiredControlApiVersion" method, 0 means our example doesn't require Control API, 1 and 2 represent minimum version of API required. We also need to override method named "isDisplaySizeSupported" for the confirmation of Display Size.
Code:
...
...
@Override
public int getRequiredControlApiVersion() {
return 2;
}
....
@Override
public boolean isDisplaySizeSupported(int width, int height) {
return ((width == HelloControlSmartWatch2.getSupportedControlWidth(mContext)
&& height == HelloControlSmartWatch2
.getSupportedControlHeight(mContext) || width == HelloControlSmartWatch2
.getSupportedControlWidth(mContext) && height == HelloControlSmartWatch2
.getSupportedControlHeight(mContext)) );
}
...
...
Step 4: Finally, Open AndroidManiFest.xml and add following action in HelloExtensionReceiver. It will require to capture onClick, onTouch and onObject click event.
Code:
...
...
<action android:name="com.sonyericsson.extras.aef.control.TOUCH_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.SWIPE_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.OBJECT_CLICK_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.MENU_ITEM_SELECTED" />
...
...
Step 5: Compile & Execute HelloSmartWatch example
Download Source Code​Note: 1. Import project in eclipse 2. Make sure that you change SmartExtensionUtils and SmartExtensionAPI path from project properties.

[Q] Android: Why are my images coming in so blurry?

I have a Slideshow for the Home Page of my app looks sorta like the Houzz apps Home Page, were it displays a new image daily. But their is one issue I am having is that all of my images are coming in so blurry. I've checked the Resolution and it shouldn't be that blurry for no reason at all. I've tried changing setScaleType such as switching it too CENTER, CENTER_CROP, and Etc... None of those seemed to work. I have tried everything too my knowledge and now I am stuck, Below are some of my relevant source code in order too successfully help me out on this issue.
This is the Home.java this is linked/runs functions of homebck.xml:
Code:
public class Home extends Fragment {
private final int FileUpload = 100;
public static final String URL =
private Context context;
private ImageView m_imageInformation;
private ImageView m_imageSave;
private ImageView m_imageWallPaper;
private ViewPager m_viewPager;
private ImageAdapter m_imageAdapter;
private ArrayList<ImageView> m_imageViewList;
private int[] m_galleryImages = new int[]{
R.drawable.ic_share,
R.drawable.ic_share,
R.drawable.ic_share
};
public static String popup_status = "";
public static File path = new File(Environment.getExternalStorageDirectory() + "");
public static Item[] fileList;
public static String chosenFile;
public static Boolean firstLvl = true;
ListAdapter adapter;
public static ArrayList<String> str = new ArrayList<String>();
public String dbPath = "/data/data/com.Celebration/";
private AboutPopup m_aboutPopup;
private InformationPopup m_informationPopup;
public static String ss;
public static List<DBManager.ImageModel> m_images;
public ImageLoader imageLoader;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// return super.onCreateView(inflater, container, savedInstanceState);
// super.onCreateView(inflater, container, savedInstanceState);
context = getActivity();
View rootView = inflater.inflate(R.layout.homebck, container, false);
m_viewPager = (ViewPager) rootView.findViewById(R.id.view_pager);
m_imageInformation = (ImageView) rootView.findViewById(R.id.image_information);
m_imageSave = (ImageView) rootView.findViewById(R.id.image_save);
m_imageWallPaper = (ImageView) rootView.findViewById(R.id.image_wallpaper);
initView();
m_imageInformation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Globals.imageNumber = m_viewPager.getCurrentItem();
m_informationPopup.showAtLocation(m_viewPager, 0, 0);
}
});
m_imageSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadFileList();
onCreateDialog(100);
}
});
m_imageWallPaper.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
//sendIntent.setAction(Intent.ACTION_CHOOSER);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "");
sendIntent.putExtra(Intent.EXTRA_EMAIL, "");
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, "Hello, I wanted to invite you to join this app with me! It's a guide about Celebration, FL. Come see ");
sendIntent.setType("text/plain");
//Sipdroid.this.startActivity(sendIntent);*/
context.startActivity(Intent.createChooser(sendIntent, "Tell a friend via..."));
}
});
return rootView;
}
public void initView(){
m_imageViewList = new ArrayList<ImageView>();
m_aboutPopup = new AboutPopup(getActivity());
m_informationPopup = new InformationPopup(getActivity());
Globals.m_dbMan = new DBManager(context);
m_images = Globals.m_dbMan.getImageListData();
m_imageViewList.clear();
if(m_images != null){
for (int i = m_images.size() - 1 ; i >= 0; i--) {
ImageView imageView = new ImageView(context);
setImage(imageView, i);
m_imageViewList.add(imageView);
}
}else{
ImageView imageView = new ImageView(context);
imageLoader = new ImageLoader(context);
imageLoader.DisplayImage(URL, imageView);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
m_imageViewList.add(imageView);
}
m_imageAdapter = new ImageAdapter(m_imageViewList);
m_viewPager.setAdapter(m_imageAdapter);
}
public void setImage(ImageView m_imgView, int currentIndex)
{
File imgFile = new File(m_images.get(currentIndex).imagePath);
//Uri uri = Uri.fromFile(new File(lstImage.get(currentIndex).imagePath));
Bitmap myBitmap = decodeFile(imgFile);
m_imgView.setImageBitmap(myBitmap);
m_imgView.setAdjustViewBounds(true);
m_imgView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
}
public static Bitmap decodeFile(File f){
Bitmap b = null;
int IMAGE_MAX_SIZE = 1000;
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis;
try {
fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
int maxwh = Math.max(o.outWidth,o.outHeight);
while(maxwh / scale > IMAGE_MAX_SIZE)
scale *= 2;
}
Log.d("twinklestar.containerrecog", "width: " + o.outWidth + "height: " + o.outHeight + "scale:" + scale);
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return b;
}
/* @Override
public void onClick(View v) {
Log.d("onclick", "ok");
switch (v.getId()){
case R.id.image_information:
{
Toast.makeText(context, "ok", Toast.LENGTH_SHORT).show();
break;
}
case R.id.image_save:
{
// loadFileList();
onCreateDialog(100);
break;
}
case R.id.image_wallpaper:
{
((Activity)context).finish();
break;
}
default:
break;
}
}*/
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
if (fileList == null) {
Log.e("TAG", "No files loaded");
dialog = builder.create();
return dialog;
}
switch (id) {
case FileUpload:
builder.setTitle("Select a Folder to save");
builder.setPositiveButton("download", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
ImageView image = new ImageView(context);
imageLoader = new ImageLoader(context);
Globals.downloadFlag = true;
Globals.downlaodForSaving = true;
Globals.saveFolder = path.toString();
imageLoader.DisplayImage(URL, image);
}
});
builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
});
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
chosenFile = fileList[which].file;
File sel = new File(path + "/" + chosenFile);
if (sel.isDirectory()) {
firstLvl = false;
// Adds chosen directory to list
str.add(chosenFile);
fileList = null;
path = new File(sel + "");
loadFileList();
dialog.dismiss();
onCreateDialog(FileUpload);
Log.d("TAG", path.getAbsolutePath());
}
// Checks if 'up' was clicked
else if (chosenFile.equalsIgnoreCase("up") && !sel.exists()) {
// present directory removed from list
String s = str.remove(str.size() - 1);
// path modified to exclude present directory
path = new File(path.toString().substring(0,
path.toString().lastIndexOf(s)));
fileList = null;
// if there are no more directories in the list, then
// its the first level
if (str.isEmpty()) {
firstLvl = true;
}
loadFileList();
//UploadFragment.this.getActivity().removeDialog(DIALOG_LOAD_FILE);
dialog.dismiss();
onCreateDialog(FileUpload);
//UploadFragment.this.getActivity().showDialog(DIALOG_LOAD_FILE);
Log.d("TAG", path.getAbsolutePath());
}
// File picked
else {
// Perform action with file picked
//Toast.makeText(UploadFragment.this.getActivity(), chosenFile, Toast.LENGTH_SHORT).show();
ss = path.getAbsolutePath() + "/" + chosenFile;
String extension = chosenFile.substring(chosenFile.indexOf(".") + 1);
if (extension.equals("png") || extension.equals("jpg") || extension.equals("bmp")) {
dialog.dismiss();
m_aboutPopup.showAtLocation(m_viewPager, 0, 0);
// onUpload(ss,chosenFile);
} else
Toast.makeText(getActivity(), "This is not image file!", Toast.LENGTH_SHORT).show();
}
}
});
break;
}
dialog = builder.show();
return dialog;
}
Below this a SNIPPET/part of the MainActivity.java *hint URL1,2,3,4... Grabs the URL that is put into String:
Code:
public static String des;
public String myurl = null;
public class AboutPopup implements View.OnClickListener {
public View parent;
public PopupWindow popupWindow;
public ListView m_listHolder;
public EditText m_editDescription;
public Button m_btnUpload;
public DatePicker dp;
public TimePicker tp;
private PendingIntent pendingIntent;
private Spinner spinner;
private ImageView imageView;
private TextView selectImageurl;
private TextView imageDescription;
public AboutPopup(Context paramContext) {
this.parent = ((LayoutInflater) paramContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.settting_popup, null);
//this.parent.findViewBy)
this.popupWindow = new PopupWindow(this.parent, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT, true);
this.m_editDescription = (EditText) parent.findViewById(R.id.setting_description);
this.m_btnUpload = (Button) parent.findViewById(R.id.btn_setting_show);
m_btnUpload.setOnClickListener(this);
selectImageurl = (TextView) parent.findViewById(R.id.select_imageurl);
imageDescription = (TextView) parent.findViewById(R.id.image_description);
selectImageurl.setTextSize(convertFromDp(24));
imageDescription.setTextSize(convertFromDp(24));
dp = (DatePicker) parent.findViewById(R.id.datePicker);
tp = (TimePicker) parent.findViewById(R.id.timePicker);
dp.setCalendarViewShown(false);
imageView = (ImageView)parent.findViewById(R.id.setting_image);
spinner = (Spinner) parent.findViewById(R.id.setting_spinner);
String[] platforms = paramContext.getResources(). getStringArray(R.array.dev_platforms);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(paramContext, R.layout.spinner_item, platforms);
spinner.setAdapter(adapter);
// If you want to continue on that TimeDateActivity
// If you want to go to new activity that code you can also write here
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch(position){
case 0:
myurl = URL;
break;
case 1:
myurl = URL1;
break;
case 2:
myurl = URL3;
break;
case 3:
myurl = URL4;
break;
case 4:
break;
}
if(myurl != null){
imageLoader = new ImageLoader(MainActivity.this);
imageLoader.DisplayImage(myurl, imageView);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
public void showAtLocation(View pView, int left, int top) {
this.popupWindow.setOutsideTouchable(true);
this.popupWindow.setTouchable(true);
this.popupWindow.update();
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setAnimationStyle(R.style.PopupAnimation);
popupWindow.setWidth((int) (pView.getWidth() * 0.95));
popupWindow.setHeight((int) (pView.getHeight()));
popupWindow.showAtLocation(pView, Gravity.CENTER_VERTICAL, 0, 0);
// this.popupWindow.showAtLocation(pView, Gravity.CENTER, left, top);
}
public void hide() {
this.popupWindow.dismiss();
}
public boolean isVisible() {
return this.popupWindow.isShowing();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_setting_show: {
imageLoader = new ImageLoader(MainActivity.this);
Globals.downloadFlag = true;
imageLoader.DisplayImage(myurl, imageView);
ss = path.getAbsolutePath() + "/" + ImageLoader.fname;
des = this.m_editDescription.getText().toString();
Globals.alarmFileName[Globals.alarmNumber] = ImageLoader.fname;
Globals.alarmDescription[Globals.alarmNumber] = des;
Globals.alarmNumber = Globals.alarmNumber + 1;
String strDateTime = dp.getYear() + "-" + (dp.getMonth() + 1) + "-" + dp.getDayOfMonth();
Intent Intent = new Intent(MainActivity.this, AlarmReceiver.class);
Intent.putExtra("id",Globals.alarmNumber-1);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, Intent, 0);
Calendar cal = Calendar.getInstance();
cal.set(dp.getYear(), dp.getMonth(), dp.getDayOfMonth(),tp.getCurrentHour(), tp.getCurrentMinute());
Calendar current = Calendar.getInstance();
if(current.get(Calendar.YEAR) > cal.get(Calendar.YEAR) && current.get(Calendar.MONTH) > cal.get(Calendar.MONTH) && current.get(Calendar.DATE) > cal.get(Calendar.DATE)){
Toast.makeText(MainActivity.this, "Please select other time", Toast.LENGTH_SHORT).show();
return;
}
// schedule for every 30 seconds
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
if (des == null) {
Toast.makeText(MainActivity.this, "Input description in..", Toast.LENGTH_SHORT).show();
return;
} else {
popupWindow.dismiss();
}
}
break;
}
}
}
homebck.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/homefragment"
android:background="@color/white">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:layout_weight="1">
<ImageView
android:id="@+id/image_information"
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="@drawable/ic_information"
android:layout_weight="1" />
<ImageView
android:id="@+id/image_save"
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="@drawable/ic_save"
android:layout_weight="1"
/>
<ImageView
android:id="@+id/image_wallpaper"
android:layout_width="0dp"
android:layout_height="match_parent"
android:src="@drawable/ic_share"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>

Use HUAWEI Nearby Service to Develop a Business Card Exchange Function for APP [ad]

More articles like this, you can visit HUAWEI Developer Forum and Medium.
Forum link: https://forums.developer.huawei.com/forumPortal/en/home
Medium link: https://medium.com/huawei-developers​
It is a tradition to exchange business cards with new colleges or partners, but keeping physical business cards is not easy at all. To solve this problem, many apps and mini programs providing the electronic business card function have emerged. You must be wondering how to develop such a function for your app.
Try integrating HUAWEI Nearby Service and use its Nearby Message feature to quickly implement the point-to-point business card exchange function. Check out the function demo below.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
If you are interested in the implementation details, download the source code from GitHub. You can optimize the code based on your app requirements.
Github demo link: https://github.com/HMS-Core/hms-nearby-demo/tree/master/NearbyCardExchange
The development procedure is as follows:
1. Getting Started
If you are already a Huawei developer, skip this step. If you are new to Huawei Mobile Services (HMS), you need to configure app information in AppGallery Connect, enable Nearby Service on the HUAWEI Developers console, and integrate the HMS Core SDK. For details, please refer to the documentation.
2. Adding Permissions
Before using Nearby Message, add the network, Bluetooth, and location permissions. Add the following permissions to the AndroidManifest.xml file of your project:
Code:
<uses-permission android:name="android.permission.INTERNET " />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- The location permission is also required in Android 6.0 or later. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
1. Code Development
2.1 Submitting a Dynamic Permission Application
Ensure that the Bluetooth and location functions are enabled and the device has been connected to the Internet properly. Then submit a dynamic permission application for the location permission.
Code:
@Override
public void onStart() {
super.onStart();
getActivity().getApplication().registerActivityLifecycleCallbacks(this);
checkPermission();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
for (int i = 0; i < permissions.length; ++i) {
if (grantResults[i] != 0) {
showWarnDialog(Constants.LOCATION_ERROR);
}
}
}
private void checkPermission() {
if (!BluetoothCheckUtil.isBlueEnabled()) {
showWarnDialog(Constants.BLUETOOTH_ERROR);
return;
}
if (!LocationCheckUtil.isLocationEnabled(this.getActivity())) {
showWarnDialog(Constants.LOCATION_SWITCH_ERROR);
return;
}
if (!NetCheckUtil.isNetworkAvailable(this.getActivity())) {
showWarnDialog(Constants.NETWORK_ERROR);
return;
}
String[] deniedPermission = PermissionUtil.getDeniedPermissions(this.getActivity(), new String[] {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
});
if (deniedPermission.length > 0) {
PermissionUtil.requestPermissions(this.getActivity(), deniedPermission, 10);
}
}
2.2 Encapsulating the Business Card Publishing and Subscription APIs
When a subscribed business card message is detected by the onFound method, display it in the business card searching pop-up; when a business card message is no longer discoverable (onLost), delete it from the business card searching pop-up.
Code:
private MessageHandler mMessageHandler = new MessageHandler() {
@Override
public void onFound(Message message) {
CardInfo cardInfo = JsonUtils.json2Object(new String(message.getContent(), Charset.forName("UTF-8")),
CardInfo.class);
if (cardInfo == null) {
return;
}
mSearchCardDialogFragment.addCardInfo(cardInfo);
}
@Override
public void onLost(Message message) {
CardInfo cardInfo = JsonUtils.json2Object(new String(message.getContent(), Charset.forName("UTF-8")),
CardInfo.class);
if (cardInfo == null) {
return;
}
mSearchCardDialogFragment.removeCardInfo(cardInfo);
}
};
private void publish(String namespace, String type, int ttlSeconds, OnCompleteListener<Void> listener) {
Message message = new Message(JsonUtils.object2Json(mCardInfo).getBytes(Charset.forName("UTF-8")), type,
namespace);
Policy policy = new Policy.Builder().setTtlSeconds(ttlSeconds).build();
PutOption option = new PutOption.Builder().setPolicy(policy).build();
Nearby.getMessageEngine(getActivity()).put(message, option).addOnCompleteListener(listener);
}
private void subscribe(String namespace, String type, int ttlSeconds, OnCompleteListener<Void> listener,
GetCallback callback) {
Policy policy = new Policy.Builder().setTtlSeconds(ttlSeconds).build();
MessagePicker picker = new MessagePicker.Builder().includeNamespaceType(namespace, type).build();
GetOption.Builder builder = new GetOption.Builder().setPolicy(policy).setPicker(picker);
if (callback != null) {
builder.setCallback(callback);
}
Nearby.getMessageEngine(getActivity()).get(mMessageHandler, builder.build()).addOnCompleteListener(listener);
}
2.3 Processing the Business Card Exchange Menu
When two users exchange business cards face to face, exchange the business card exchange codes. When the business card message of the remote endpoint is published, subscribe to it.
Code:
private boolean onExchangeItemSelected() {
PinCodeDialogFragment dialogFragment = new PinCodeDialogFragment(passwrod -> {
MyCardFragment.this.publish(passwrod, passwrod, Policy.POLICY_TTL_SECONDS_MAX, result -> {
if (!result.isSuccessful()) {
String str = "Exchange card fail, because publish my card fail. exception: "
+ result.getException().getMessage();
Log.e(TAG, str);
Toast.makeText(getActivity(), str, Toast.LENGTH_LONG).show();
return;
}
MyCardFragment.this.subscribe(passwrod, passwrod, Policy.POLICY_TTL_SECONDS_INFINITE, ret -> {
if (!ret.isSuccessful()) {
MyCardFragment.this.unpublish(passwrod, passwrod, task -> {
String str = "Exchange card fail, because subscribe is fail, exception("
+ ret.getException().getMessage() + ")";
if (!task.isSuccessful()) {
str = str + " and unpublish fail, exception(" + task.getException().getMessage()
+ ")";
}
Log.e(TAG, str);
Toast.makeText(getActivity(), str, Toast.LENGTH_LONG).show();
});
return;
}
mSearchCardDialogFragment.setOnCloseListener(() -> {
MyCardFragment.this.unpublish(passwrod, passwrod, task -> {
if (!task.isSuccessful()) {
Toast.makeText(getActivity(), "Unpublish my card fail, exception: "
+ task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
});
MyCardFragment.this.unsubscribe(task -> {
if (!task.isSuccessful()) {
Toast.makeText(getActivity(), "Unsubscribe fail, exception: "
+ task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
});
});
mSearchCardDialogFragment.show(getParentFragmentManager(), "Search Card");
}, null);
});
});
dialogFragment.show(getParentFragmentManager(), "pin code");
return true;
}
2.4 Adding a Business Card to Favorites
When a user adds a business card to favorites, add the card to the favorites list; when a user removes a business card from favorites, remote the card from the favorites list. In addition, store related data locally.
Code:
@Override
public void onFavorite(CardInfo cardInfo, boolean isFavorite) {
if (isFavorite) {
mFavoriteMap.put(cardInfo.getId(), cardInfo);
} else {
mFavoriteMap.remove(cardInfo.getId());
}
Set<String> set = new HashSet<>(mFavoriteMap.size());
for (CardInfo card : mFavoriteMap.values()) {
set.add(JsonUtils.object2Json(card));
}
SharedPreferences sharedPreferences = getContext().getSharedPreferences("data", Context.MODE_PRIVATE);
sharedPreferences.edit().putStringSet(Constants.MY_FAVORITES_KEY, set).apply();
}
5. Conclusion
This demo uses Nearby Message feature of HUAWEI Nearby Service. What Nearby Message is capable of is more than just developing functions for exchanging business cards face-to-face. Here are some examples:
1. Face-to-face teaming in multiplayer sports games
2. Face-to-face round joining in board games
3. Near-field go-Dutch payment function
4. Music sharing
If you are interested and want to learn more, check our development guide at
https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/nearby-service-introduction
Find more Huawei HMS development guides in the XDA HMS community forums.

Categories

Resources