[Q] Referrer Receiver Not Working - General Questions and Answers

Hi Fellows
I am honestly pretty new to Android development, until recently I have been doing my projects in Phonegap. For two days now I have been trying to figure out why my receiver isn't working. It's a receiver that grabs the referral from the url and sends it to my custom BroadcastReceiver which processes the string and uses that value. When it's on the Play store it doesn't work however running the "test" code from Google in my terminal and then starting the app it works like a charm.
Below is my code.
Android Manifest
Code:
<receiver android:name="com.nett.html6.MyCampaignReceiver" android:exported="true" android:enabled="true">
<intent-filter android:priority="10">
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
and MyCampaignReceiver
Code:
public class MyCampaignReceiver extends BroadcastReceiver {
[user=439709]@override[/user]
public void onReceive(Context context, Intent intent) {
Log.i("Test", "Running");
Bundle extras = intent.getExtras();
String referrerString = extras.getString("referrer").toString();
Log.i("Test", "Referrer : " + referrerString);
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
sanitizer.setAllowUnregisteredParamaters(true);
sanitizer.parseUrl("&"+referrerString);
String utmsource = sanitizer.getValue("utm_source").toString();
Log.i("utm", "utm : " + utmsource);
if (utmsource != null) {
SharedPreferences preferences = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
Editor preferencesEditor = preferences.edit();
preferencesEditor.putString("ref", utmsource);
if(preferencesEditor.commit()){
Log.w("TEST", "Stored Referrer is commited as : " + preferences.getString("ref", "1234333"));
}
}
}
}
Any help would be appreciated!
Thank you.

Related

How To Get Number From Contacts?

How do you get the number back from an implicit call to view the contacts list?
.java file
Code:
package com.grimx.MakeCall;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MakeCall extends Activity implements View.OnClickListener{
private static final int CONTACT_ACTIVITY = 100;
EditText editText;
Button callBtn;
Button contactsBtn;
Button closeBtn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText = (EditText)findViewById(R.id.editText);
callBtn = (Button)findViewById(R.id.callBtn);
callBtn.setOnClickListener(this);
contactsBtn = (Button)findViewById(R.id.contactsBtn);
contactsBtn.setOnClickListener(this);
closeBtn = (Button)findViewById(R.id.closeBtn);
closeBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.callBtn) {
String phn_number = editText.getText().toString();
if(phn_number.equals("")) {
Toast.makeText(MakeCall.this, "Please Enter A Phone Number", Toast.LENGTH_LONG).show();
}
else
{
Intent call_intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phn_number));
startActivity(call_intent);
}
}
else if(v.getId() == R.id.contactsBtn) {
Uri uri = Uri.parse("content://contacts/people");
Intent contacts_intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(contacts_intent, CONTACT_ACTIVITY);
}
else if(v.getId() == R.id.closeBtn) {
Toast.makeText(MakeCall.this, "Exiting MakeCall", Toast.LENGTH_LONG).show();
finish();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case(CONTACT_ACTIVITY): {
if(resultCode == Activity.RESULT_OK) {
Uri my_uri = data.getData();
//Uri.decode(my_uri.toString());
//want to get the number an put it in the editText
editText.setText(Uri.decode(my_uri.toString()));
}
break;
}
}
}
}
how to use a number pulled from contacts
I just figured this out myself yesterday, and it's surprisingly easy:
Code:
package org.nyquil.slydialer;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.Phones;
public class slydialer extends Activity {
private static final int PICK_CONTACT = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
Intent intent = new Intent(Intent.ACTION_PICK, Phones.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (PICK_CONTACT) :
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor c = managedQuery(contactData, null, null, null, null);
if (c.moveToFirst()) {
String number = c.getString(c.getColumnIndexOrThrow(Phones.NUMBER));
// TODO Whatever you want to do with the selected contact name.
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel://2677593425,,,"+number));
startActivity(intent);
finish();
}
}
break;
}
}
}
It's that override to onActivityResult that's the trick. This example is only listing contacts with phone numbers, but if you replace 'Phones' with 'People' it should list them all.
ok i get a force close when i run my app now.
what i'm tring to do is click the contacts_btn and select a contact
and returns it number(putting it in the editText) and then click the
call_btn to make the call.
.java
Code:
package com.grimx.MakeCall;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.Phones;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MakeCall extends Activity implements View.OnClickListener{
private static final int CONTACT_ACTIVITY = 100;
EditText editText;
Button callBtn;
Button contactsBtn;
Button closeBtn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText = (EditText)findViewById(R.id.editText);
callBtn = (Button)findViewById(R.id.callBtn);
callBtn.setOnClickListener(this);
contactsBtn = (Button)findViewById(R.id.contactsBtn);
contactsBtn.setOnClickListener(this);
closeBtn = (Button)findViewById(R.id.closeBtn);
closeBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.callBtn) {
String phn_number = editText.getText().toString();
if(phn_number.equals("")) {
Toast.makeText(MakeCall.this, "Please Enter A Phone Number", Toast.LENGTH_LONG).show();
}
else
{
Intent call_intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phn_number));
startActivity(call_intent);
}
}
else if(v.getId() == R.id.contactsBtn) {
Uri uri = Uri.parse("content://contacts/people");
Intent contacts_intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(contacts_intent, CONTACT_ACTIVITY);
}
else if(v.getId() == R.id.closeBtn) {
Toast.makeText(MakeCall.this, "Exiting MakeCall", Toast.LENGTH_LONG).show();
finish();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case(CONTACT_ACTIVITY): {
if(resultCode == Activity.RESULT_OK) {
Uri contact_data = data.getData();
Cursor c = managedQuery(contact_data, null, null, null, null);
if(c.moveToFirst()){
String number = c.getString(c.getColumnIndexOrThrow(Phones.NUMBER));
editText.setText("tel:" + number);
}
}
break;
}
}
}
}
the force close happens on the return from selecting a contact.
You could atleast say your rom and phone model.
HTC G1 Black, CyanogenMod-4.2.1.1
grimx said:
HTC G1 Black, CyanogenMod-4.2.1.1
Click to expand...
Click to collapse
Did you upgrade from a older version or do a full wipe?
Did you use HTC ADP rom or the Base rom from enom?
HTC G1 Black, CyanogenMod-4.2.11.1
sorry about that mix up
Heres my AndroidManifest.xml, if it helps
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.grimx.MakeCall"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MakeCall"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />
</manifest>
Ok problem solved.
I forgot to add the permission :
<uses-permission android:name="android.permission.READ_CONTACTS" />
to my AndroidManifest.xml file.

GPS: ephemeris and almanac data?

Hi, i'm currently exploring the gps on my device with the java api provided with the Android SDK.
I stumbled upon something that I can't make sense of: I collect the satellites my GPS sees and query those satellites it they are involved in the current fix and if they contain almanac and ephemeris data.
Now, somehow I never get a confirmation that the GPS i query contains eph or alm data? Turning on or off the aGPS don't really like to influence this. (FYI i'm running this on a Galaxy S)
I wonder, can someone try the attached program on his or her Android device and report back to me if the abbreviations "eph" and/or "alm" appear after the listed satellites.
Thanks in advance!
by request: code of the app (be warned this was my very first android app ):
Code:
package com.appelflap.android.location_app;
import java.util.Iterator;
import android.app.Activity;
import android.content.Context;
import android.location.GpsSatellite;
import android.location.Location;
import android.location.GpsStatus;
import android.location.LocationListener;
import android.location.GpsStatus.Listener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class LocationActivity extends Activity implements LocationListener, GpsStatus.Listener {
private static final String TAG = "com.appelflap.android.location_app";
private LocationManager locationManager;
private static final String PROVIDER = "gps";
private TextView output;
private TextView accuracy;
private TextView gpsstatus;
private TextView gpsfix;
private TextView gps_output;
private TextView line;
private TextView maxSatellites;
private TextView maxLocked;
private TextView minSignalNoiseRatio;
private Integer iGpsStatus;
private Integer maxSats;
private Integer maxFix;
private Integer minSnr;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
maxSats = 0;
maxFix = 0; // maximal number of sats constituting a fix. The claim for the SGS is that this is always =< 8
minSnr = 100; // minimal Snr of a sat contained in a fix. The claim for the SGS is that this is always > 20 (Lets start set with an unreal high value)
iGpsStatus = -1 ;
output = (TextView) findViewById(R.id.output);
accuracy = (TextView) findViewById(R.id.accuracy);
line = (TextView) findViewById(R.id.line);
maxSatellites = (TextView) findViewById(R.id.maxSatellites);
maxLocked = (TextView) findViewById(R.id.maxLocked);
minSignalNoiseRatio = (TextView) findViewById(R.id.minSignalNoiseRatio);
gpsfix = (TextView) findViewById(R.id.gpsfix);
gpsstatus = (TextView) findViewById(R.id.gpsstatus);
gps_output = (TextView) findViewById(R.id.gps_output);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(PROVIDER, 0, 0, this);
locationManager.addGpsStatusListener(this);
}
private void registerLocationListeners() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(PROVIDER, 0, 0, this);
locationManager.addGpsStatusListener(this);
}
public void onLocationChanged(Location location) {
String result = String.format(
"Coordinates: latitude: %f, longitude: %f", location
.getLatitude(), location.getLongitude());
Log.d(TAG, "location update received: " + result);
output.setText(result);
accuracy.setText("Accuracy: " + location.getAccuracy());
}
public void onProviderDisabled(String provider) {
Log.d(TAG, "the following provider was disabled: " + provider);
}
public void onProviderEnabled(String provider) {
Log.d(TAG, "the following provider was enabled: " + provider);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, String.format(
"Provider status has changed. provider: %s, status: %d",
provider, status));
}
public void onGpsStatusChanged(int event)
{
Log.v("TEST","LocationActivity - onGpsStatusChange: onGpsStatusChanged: " + Integer.toString(event)) ;
int iSats;
int fix;
int snr;
switch( event )
{
case GpsStatus.GPS_EVENT_STARTED:
iGpsStatus = event ;
break ;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
GpsStatus xGpsStatus = locationManager.getGpsStatus(null) ;
Iterable<GpsSatellite> iSatellites = xGpsStatus.getSatellites() ;
Iterator<GpsSatellite> it = iSatellites.iterator() ;
iSats = 0 ; // Satellite Count
fix = 0 ; // Count satellites used in fix
StringBuilder s = new StringBuilder();
while ( it.hasNext() )
{
iSats++ ;
GpsSatellite oSat = (GpsSatellite) it.next() ;
s.append(oSat.getPrn());
s.append(": ");
snr = (int) oSat.getSnr();
s.append(snr);
s.append(" Snr");
if ( oSat.usedInFix() ) {
s.append(" (*) ");
fix++;
// if snr of this locked sat < minSnr then update minSnr
if (snr < minSnr) {
minSnr = snr;
minSignalNoiseRatio.setText("Min Snr: " + minSnr);
}
// Just testing for ephemeris and almanac data. On the Galaxy S the following GpsSatelite methods
// always return "false". To do: formatting the output..
}
if ( oSat.hasEphemeris() ) {
s.append(" Eph ");
}
if ( oSat.hasAlmanac() ) {
s.append(" Alm ");
}
s.append("\n");
Log.v("TEST","LocationActivity - onGpsStatusChange: Satellites: " + oSat.getSnr() ) ;
}
gpsstatus.setText("Satellites: " + iSats);
gpsfix.setText("Locked: " + fix);
Log.v("TEST","LocationActivity - onGpsStatusChange: Satellites: " + iSats ) ;
if ( s.length() > 0) {
gps_output.setText(s.toString());
}
else { gps_output.setText("Waiting..."); }
if ( iSats > maxSats ) {
maxSats = iSats;
maxSatellites.setText("Max Sats: " + maxSats);
}
if ( fix > maxFix ) {
maxFix = fix;
maxLocked.setText("Max Locked: " + maxFix);
}
break ;
case GpsStatus.GPS_EVENT_FIRST_FIX:
iGpsStatus = event ;
break ;
case GpsStatus.GPS_EVENT_STOPPED:
gpsstatus.setText("Stopped...") ;
iGpsStatus = event ;
break ;
}
}
protected void onPause() {
// Make sure that when the activity goes to
// background, the device stops getting locations
// to save battery life.
locationManager.removeUpdates(this);
super.onPause();
}
protected void onResume() {
// Make sure that when the activity has been
// suspended to background,
// the device starts getting locations again
registerLocationListeners();
super.onResume();
}
}
// Framework for the code based on http://www.hascode.com/2010/05/sensor-fun-location-based-services-and-gps-for-android/
bumperdibump
LocationApp could not be installed on this phone.
System Requirements? I'm running Android 1.6
t-bon3 said:
LocationApp could not be installed on this phone.
System Requirements? I'm running Android 1.6
Click to expand...
Click to collapse
I attached another version for all Android levels. I checked with the api docs and it should run.
Thank you very much for testing!
I get a list of saetllites with a number, 'Snr' then a (*) for the sats that have a lock, but nothing else, no 'Eph' or 'Alm'.
This is on Android 1.6 on an i-mobile i858 device.
Do you have sample code for a simple app that reads data from the GPS. GPS software from the market seems buggy on my device and I would like to investigate by writing my own basic GPS app.
Thanks.
t-bon3 said:
I get a list of saetllites with a number, 'Snr' then a (*) for the sats that have a lock, but nothing else, no 'Eph' or 'Alm'.
This is on Android 1.6 on an i-mobile i858 device.
Do you have sample code for a simple app that reads data from the GPS. GPS software from the market seems buggy on my device and I would like to investigate by writing my own basic GPS app.
Thanks.
Click to expand...
Click to collapse
No problem, I will clean up the code somewhat and will put it up in the first post.
BTW did you activated aGPS while testing the app?
On my device under "My Location" in settings there are only these options:
Use wireless networks
Enable GPS satellites
Share with Google
I had all 3 set to active while testing the app.
t-bon3 said:
On my device under "My Location" in settings there are only these options:
Use wireless networks
Enable GPS satellites
Share with Google
I had all 3 set to active while testing the app.
Click to expand...
Click to collapse
The aGPS function has to be activated in an app delivered with your device. Don't know if it is activated by default. (assuming your GPS chip supports aGPS of course)
Anyway, I put the code up in the first post. (EDIT: included the resource files and the manifest file in a attached zip file)

[Q] Widget OnClick self firing

I don't know of this is the right section, if its not then please move it to the correct one.
I have a service the controls a mediaplayer and updates a widget. I added 3 ImageViews to change song (Prev and Next) and to Play/Pause. I added custom BroadcastReceivers, one for each ImageView. But when i start the app, no mater of the Widget is one the homescreen or not, the Receiver get broadcasts from widget.
Code:
public void SetWidgetListener() {
RemoteViews updateViews = null;
updateViews = new RemoteViews(this.getPackageName(), R.layout.widget);
Intent intent = new Intent(this, GMWidget.class);
intent.setAction(WIDGET_PAUSE_PLAY);
PendingIntent WidgetPausePlay = PendingIntent.getBroadcast(this, 0, intent, 0);
updateViews.setOnClickPendingIntent(R.id.pbWidMediaPlay, WidgetPausePlay);
Intent Widget_Next_intent = new Intent(this, GMWidget.class);
Widget_Next_intent.setAction(WIDGET_NEXT);
PendingIntent WidgetNext = PendingIntent.getBroadcast(this, 0, Widget_Next_intent, 0);
updateViews.setOnClickPendingIntent(R.id.pbWidMediaNext, WidgetNext);
Intent Widget_Prev_intent = new Intent(this, GMWidget.class);
Widget_Prev_intent.setAction(WIDGET_PREV);
PendingIntent WidgetPrev = PendingIntent.getBroadcast(this, 0, Widget_Prev_intent, 0);
updateViews.setOnClickPendingIntent(R.id.pbWidMediaPrev, WidgetPrev);
ComponentName thisWidget = new ComponentName(this, GMWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
And this is where i create my Receiver:
Code:
public void onCreate() {
super.onCreate();
try {
final IntentFilter theFilter = new IntentFilter();
theFilter.addAction(Intent.ACTION_HEADSET_PLUG);
theFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
theFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
theFilter.addAction(AppWidgetManager.ACTION_APPWIDGET_ENABLED);
theFilter.addAction("com.groove.mobile.WIDGET_NEXT");
theFilter.addAction("com.groove.mobile.WIDGET_PREV");
theFilter.addAction("com.groove.mobile.WIDGET_PAUSE_PLAY");
this.yourReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, action);
if(action.contains("PHONE_STATE")) {
String s = intent.getStringExtra("state");
if (s.contains("OFF") && mp.isPlaying()) {
if (mp != null) {
mp.pause();}
} else if (s.contains("RING")) {
if (mp != null && mp.isPlaying()) {
mp.pause();}
} else if (s.contains("IDL")) {
if (mp != null) {
mp.start();}
}
Log.d(TAG, s);
//mp.pause();
} else if (action.contains(WIDGET_PREV)) {
mClient.OnRequestChangeTrack(-1);
// SetWidgetListener();
} else if (action.contains(WIDGET_NEXT)) {
mClient.OnRequestChangeTrack(1);
// SetWidgetListener();
} else if (action.contains(WIDGET_PAUSE_PLAY)) {
if (mp != null) {
try {
if (mp.isPlaying()) {
mp.pause();
} else {
mp.start();
}
} catch (Exception e) {
e.fillInStackTrace();
}
// SetWidgetListener();
}
} else if (action.contains("android.appwidget.action.APPWIDGET_ENABLED")) {
SetWidgetListener();
if (mp!= null) {
updateWidgetText("","");
} else {
updateWidgetText(" ", " ");
}
}
}
};
this.registerReceiver(this.yourReceiver, theFilter);
} catch (Exception e) {
e.fillInStackTrace();
}
}
Here is the code for my widget:
Code:
public class GMWidget extends AppWidgetProvider {
private String TAG = "GMWidget";
@Override
public void onEnabled(Context context) {
}
String LOG = "GMWidget";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.w(LOG, "onUpdate method called");
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
String action = intent.getAction();
//Log.d(TAG,"CLICKK: " + action);
Intent i = new Intent();
i.setAction(action);
context.sendBroadcast(i);
}
}
The reason to why i re-broadcast everything from the widget, is that my service won't receive my custom broadcast otherwise.
This is my service and widget code from the manifest:
Code:
<service android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:permission="android.permission.INTERNET" android:name="com.groove.services.GMService">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.groove.mobile.WIDGET_NEXT" />
<action android:name="com.groove.mobile.WIDGET_PREV" />
<action android:name="com.groove.mobile.WIDGET_PAUSE_PLAY" />
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
</intent-filter>
</service>
<receiver android:name=".specials.GMWidget" android:enabled="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.groove.mobile.WIDGET_NEXT" />
<action android:name="com.groove.mobile.WIDGET_PREV" />
<action android:name="com.groove.mobile.WIDGET_PAUSE_PLAY" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
Thanks in advance!
Anyone? I really can't find any solution for this.

[TUT] SmartWatch App Development - Part 3 - 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 two articles I covered development environment setup and anatomy of SmartWatch. This article will contain deep dive into coding with simple Hello Word example.
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
This demo will cover Notification API only. We will develop a single Android project named "Hello SmartWatch" which acts as a Host application and Extension application both. It means I will use single codebase for both things. Hello SmartWatch project has an Activity to send and clear notification to SmartWatch.
I assume that you have already imported SmartExtensionAPI and SmartExtensionUtils libraries in workspace.
Let's jump to the code.
List of Classes and purpose
MainActivity.java: It is use to generate and clear notification.
HelloExtensionReceiver.java: It receives input event generated by SmartWatch and forward control to the Extension Service.
HelloExtensionService.java: core logic of Host application needs to be written in ExtensionService. It is also responsible to register a host application to SmartWatch.
HelloRegistrationInformation.java: It provides essential information to register host application and API requirement.
This demo application contains only above four classes but actual application may have more classes. In above classes MainActivity acts as a Smart Extension application and rest of classes acts as a Host application.
Step 1: Create new Android project in eclipse named "HelloSmartWatch".
Step 2: Let's create UI first. Open activity_main.xml and put two EditText box for Title and Message respectively and two buttons for Send and Clear notification respectively.
Code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Send Notification"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/etTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Title" >
</EditText>
<EditText
android:id="@+id/etMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Message" >
</EditText>
<Button
android:id="@+id/btnSend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="buttonClicked"
android:text="Send Notification" />
<Button
android:id="@+id/btnClearn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="buttonClicked"
android:text="Clear Notification" />
</LinearLayout>
Step 3: Let's make button alive by writing action in MainActivity.java. I am using onClick property of buttons, so I don't require to find object of button and setOnClickListener. I can write code in "buttonClicked" method which is defined. When a user click on "Send Notification" button I am simply firing ExtensionService with INTENT_ACTION_ADD action and other required data and same for "Clear Notification" but with INTENT_ACTION_CLEAR action.
Code:
package com.kpbird.hellosmartwatch;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void buttonClicked(View v){
if(v.getId() == R.id.btnSend){
Intent serviceIntent = new Intent(this, HelloExtensionService.class);
serviceIntent.setAction(HelloExtensionService.INTENT_ACTION_ADD);
EditText etName = (EditText) findViewById(R.id.etTitle);
EditText etMsg = (EditText) findViewById(R.id.etMessage);
serviceIntent.putExtra("name", etName.getText().toString());
serviceIntent.putExtra("message", etMsg.getText().toString());
startService(serviceIntent);
}
else if(v.getId() == R.id.btnClearn){
Intent serviceIntent = new Intent(this, HelloExtensionService.class);
serviceIntent.setAction(HelloExtensionService.INTENT_ACTION_CLEAR);
startService(serviceIntent);
}
}
}
Step 4: Create HelloExtensionReceiver.java, It extends BroadcastReceiver. It works as bridge between SmartWatch and Host application, It will receive event generated in SmartWatch and forward it to HelloExtensionService.java
Code:
package com.kpbird.hellosmartwatch;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class HelloExtensionReceiver extends BroadcastReceiver{
private String TAG = this.getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "HelloExtensionReceiver onReceiver: " + intent.getAction());
intent.setClass(context, HelloExtensionService.class);
context.startService(intent);
}
}
Step 5: Create HelloRegistrationInformation.java and extends with RegistrationInformation class. As the name suggests, It will use to register host application in Smart Connect. It has six methods that we need to override, among these four methods are used to declare required APIs and two methods used for extension registration and source registration. You can have multiple sources in a host application.
Code:
package com.kpbird.hellosmartwatch;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import com.sonyericsson.extras.liveware.aef.notification.Notification;
import com.sonyericsson.extras.liveware.aef.registration.Registration;
import com.sonyericsson.extras.liveware.extension.util.ExtensionUtils;
import com.sonyericsson.extras.liveware.extension.util.registration.RegistrationInformation;
public class HelloRegistrationInformation extends RegistrationInformation{
private Context mContext;
public HelloRegistrationInformation(Context ctx){
if (ctx == null) {
throw new IllegalArgumentException("context == null");
}
mContext = ctx;
}
@Override
public int getRequiredNotificationApiVersion() {
return 1;
}
@Override
public int getRequiredWidgetApiVersion() {
return 0;
}
@Override
public int getRequiredControlApiVersion() {
return 0;
}
@Override
public int getRequiredSensorApiVersion() {
return 0;
}
@Override
public ContentValues getExtensionRegistrationConfiguration() {
String extensionIcon = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher);
String iconHostapp = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher);
String extensionIcon48 = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_48);
String configurationText = "Hello SmartWatch";
String extensionName = "Hello SmartWatch";
ContentValues values = new ContentValues();
values.put(Registration.ExtensionColumns.CONFIGURATION_ACTIVITY,MainActivity.class.getName());
values.put(Registration.ExtensionColumns.CONFIGURATION_TEXT, configurationText);
values.put(Registration.ExtensionColumns.EXTENSION_ICON_URI, extensionIcon);
values.put(Registration.ExtensionColumns.EXTENSION_48PX_ICON_URI, extensionIcon48);
values.put(Registration.ExtensionColumns.EXTENSION_KEY,HelloExtensionService.EXTENSION_KEY);
values.put(Registration.ExtensionColumns.HOST_APP_ICON_URI, iconHostapp);
values.put(Registration.ExtensionColumns.NAME, extensionName);
values.put(Registration.ExtensionColumns.NOTIFICATION_API_VERSION,getRequiredNotificationApiVersion());
values.put(Registration.ExtensionColumns.PACKAGE_NAME, mContext.getPackageName());
return values;
}
@Override
public ContentValues[] getSourceRegistrationConfigurations() {
ContentValues sourceValues = null;
String iconSource1 = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_30);
String iconSource2 = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_18);
String iconBw = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_18_bw);
String textToSpeech = "Notification from Hello SmartWatch Application";
sourceValues = new ContentValues();
sourceValues.put(Notification.SourceColumns.ENABLED, true);
sourceValues.put(Notification.SourceColumns.ICON_URI_1, iconSource1);
sourceValues.put(Notification.SourceColumns.ICON_URI_2, iconSource2);
sourceValues.put(Notification.SourceColumns.ICON_URI_BLACK_WHITE, iconBw);
sourceValues.put(Notification.SourceColumns.UPDATE_TIME, System.currentTimeMillis());
sourceValues.put(Notification.SourceColumns.NAME, mContext.getString(R.string.app_name));
sourceValues.put(Notification.SourceColumns.EXTENSION_SPECIFIC_ID, HelloExtensionService.EXTENSION_SPECIFIC_ID);
sourceValues.put(Notification.SourceColumns.PACKAGE_NAME, mContext.getPackageName());
sourceValues.put(Notification.SourceColumns.TEXT_TO_SPEECH, textToSpeech);
sourceValues.put(Notification.SourceColumns.ACTION_1,"Hello");
sourceValues.put(Notification.SourceColumns.ACTION_ICON_1,ExtensionUtils.getUriString(mContext, R.drawable.ic_launcher));
List<ContentValues> bulkValues = new ArrayList<ContentValues>();
bulkValues.add(sourceValues);
return bulkValues.toArray(new ContentValues[bulkValues.size()]);
}
}
Step 6: Create HelloExtensionService.java and extends with ExtensionService. It will contain main logic of SmartWatch host application. We need to implement two abstract methods named "getRegistrationInformation()", which sends object of HelloRegistrationInformation class and "keepRunningWhenConnected()",return true if you want to keep ExtensionService running as long as SmartWatch is connected with Smart Phone. For notification example we need to create two methods named "addData" and "clearData". It will generate and clear notification in SmartWatch respectively. We also need to implement onStartCommand to interact with Service.
Code:
package com.kpbird.hellosmartwatch;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.util.Log;
import android.widget.Toast;
import com.sonyericsson.extras.liveware.aef.notification.Notification;
import com.sonyericsson.extras.liveware.aef.registration.Registration;
import com.sonyericsson.extras.liveware.extension.util.ExtensionService;
import com.sonyericsson.extras.liveware.extension.util.ExtensionUtils;
import com.sonyericsson.extras.liveware.extension.util.notification.NotificationUtil;
import com.sonyericsson.extras.liveware.extension.util.registration.DeviceInfoHelper;
import com.sonyericsson.extras.liveware.extension.util.registration.RegistrationInformation;
public class HelloExtensionService extends ExtensionService {
public static final String EXTENSION_SPECIFIC_ID = "EXTENSION_SPECIFIC_ID_HELLO_NOTIFICATION";
public static final String EXTENSION_KEY = "com.kpbird.hellosmartwatch.key";
public static final String INTENT_ACTION_ADD = "com.kpbird.hellosmartwatch.action.add";
public static final String INTENT_ACTION_CLEAR = "com.kpbird.hellosmartwatch.action.clear";
private String TAG = this.getClass().getSimpleName();
public HelloExtensionService() {
super(EXTENSION_KEY);
Log.i(TAG, "Constructor");
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int retVal = super.onStartCommand(intent, flags, startId);
if (intent != null) {
if (INTENT_ACTION_CLEAR.equals(intent.getAction())) {
Log.d(TAG, "onStart action: INTENT_ACTION_CLEAR");
clearData(intent);
stopSelfCheck();
} else if (INTENT_ACTION_ADD.equals(intent.getAction())) {
Log.d(TAG, "onStart action: INTENT_ACTION_ADD");
addData(intent);
stopSelfCheck();
}
}
return retVal;
}
@Override
protected RegistrationInformation getRegistrationInformation() {
return new HelloRegistrationInformation(this);
}
@Override
protected boolean keepRunningWhenConnected() {
return false;
}
private void clearData(Intent intent) {
NotificationUtil.deleteAllEvents(this);
}
private void addData(Intent intent) {
String name = "Name";
String message = "Message";
if (intent.getExtras().containsKey("name"))
name = intent.getExtras().getString("name");
if (intent.getExtras().containsKey("message"))
message = intent.getExtras().getString("message");
long time = System.currentTimeMillis();
long sourceId = NotificationUtil.getSourceId(this,
EXTENSION_SPECIFIC_ID);
Log.i(TAG, "Source ID :" + sourceId);
if (sourceId == NotificationUtil.INVALID_ID) {
Log.e(TAG, "Failed to insert data");
return;
}
String profileImage = ExtensionUtils.getUriString(this,R.drawable.ic_launcher);
ContentValues eventValues = new ContentValues();
eventValues.put(Notification.EventColumns.EVENT_READ_STATUS, false);
eventValues.put(Notification.EventColumns.DISPLAY_NAME, name);
eventValues.put(Notification.EventColumns.MESSAGE, message);
eventValues.put(Notification.EventColumns.PERSONAL, 1);
eventValues.put(Notification.EventColumns.PROFILE_IMAGE_URI,profileImage);
eventValues.put(Notification.EventColumns.PUBLISHED_TIME, time);
eventValues.put(Notification.EventColumns.SOURCE_ID, sourceId);
try {
getContentResolver().insert(Notification.Event.URI, eventValues);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Failed to insert event", e);
} catch (SecurityException e) {
Log.e(TAG,
"Failed to insert event, is Live Ware Manager installed?",
e);
} catch (SQLException e) {
Log.e(TAG, "Failed to insert event", e);
}
}
@Override
protected void onViewEvent(Intent intent) {
String action = intent.getStringExtra(Notification.Intents.EXTRA_ACTION);
Log.i(TAG, "Action : " + action);
String hostAppPackageName = intent.getStringExtra(Registration.Intents.EXTRA_AHA_PACKAGE_NAME);
Log.i(TAG, "HostAppPackageName: " + hostAppPackageName);
boolean advancedFeaturesSupported = DeviceInfoHelper.isSmartWatch2ApiAndScreenDetected(this, hostAppPackageName);
Log.i(TAG, "Advanced Features Supported: " + advancedFeaturesSupported);
int eventId = intent.getIntExtra(Notification.Intents.EXTRA_EVENT_ID,-1);
try {
Cursor cursor = getContentResolver().query(Notification.Event.URI,null, Notification.EventColumns._ID + " = " + eventId,null, null);
if (cursor != null && cursor.moveToFirst()) {
String name = cursor.getString(cursor.getColumnIndex(Notification.EventColumns.DISPLAY_NAME));
String message = cursor.getString(cursor.getColumnIndex(Notification.EventColumns.MESSAGE));
Toast.makeText(this,"Notification: Name: " + name + " Message: " + message,Toast.LENGTH_LONG).show();
Log.i(TAG, "Name: " + name);
Log.i(TAG, "Message: "+ message);
}
cursor.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public void onRegisterResult(boolean success) {
super.onRegisterResult(success);
Log.d(TAG, "onRegisterResult :" + success);
}
}
Step 7: Finally we need to register HelloExtensionReceiver and HelloExtensionService in AndroidManifest.xml like following. We also need to provide user permission "EXTENSION_PERMISSION".
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kpbird.hellosmartwatch"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="16" />
<uses-permission android:name="com.sonyericsson.extras.liveware.aef.EXTENSION_PERMISSION" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.kpbird.hellosmartwatch.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".HelloExtensionService" />
<receiver
android:name=".HelloExtensionReceiver"
android:permission="com.sonyericsson.extras.liveware.aef.HOSTAPP_PERMISSION" >
<intent-filter>
<!-- Generic extension intents. -->
<action android:name="com.sonyericsson.extras.liveware.aef.registration.EXTENSION_REGISTER_REQUEST" />
<action android:name="com.sonyericsson.extras.liveware.aef.registration.ACCESSORY_CONNECTION" />
<action android:name="android.intent.action.LOCALE_CHANGED" />
<!-- Notification intents -->
<action android:name="com.sonyericsson.extras.liveware.aef.notification.VIEW_EVENT_DETAIL" />
<action android:name="com.sonyericsson.extras.liveware.aef.notification.REFRESH_REQUEST" />
<!-- Widget intents -->
<action android:name="com.sonyericsson.extras.aef.widget.START_REFRESH_IMAGE_REQUEST" />
<action android:name="com.sonyericsson.extras.aef.widget.STOP_REFRESH_IMAGE_REQUEST" />
<action android:name="com.sonyericsson.extras.aef.widget.ONTOUCH" />
<action android:name="com.sonyericsson.extras.liveware.extension.util.widget.scheduled.refresh" />
<!-- Control intents -->
<action android:name="com.sonyericsson.extras.aef.control.START" />
<action android:name="com.sonyericsson.extras.aef.control.STOP" />
<action android:name="com.sonyericsson.extras.aef.control.PAUSE" />
<action android:name="com.sonyericsson.extras.aef.control.RESUME" />
<action android:name="com.sonyericsson.extras.aef.control.ERROR" />
<action android:name="com.sonyericsson.extras.aef.control.KEY_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.TOUCH_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.SWIPE_EVENT" />
</intent-filter>
</receiver>
</application>
</manifest>
Step 8: Connect your SmartPhone and run this example. It will display MainActivity. Before jumping to "Send Notification", open Accessory Emulator and select Extension to verify that our HelloExtension is installed or not. Click on extension menu and it will display the registration details. If extension gets registered successfully then you can go back to Hello SmartWatch application and play with Send and Clear Notification functionality.
Screen Shots
Download Source Code​Note: 1. Import project in eclipse 2. Make sure that you change SmartExtensionUtils and SmartExtensionAPI path from project properties.

[APP] Floating Camera [v1.000.00.1r][4.0.+][Tutorial][SourceCode]

{
"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:

Categories

Resources