Sony Small App SDK - android

So i've just started to use the new Sony Xperia Tablet S Small App SDK. I'm no realy noob, developed many personal apps before but this has got me stumped.
I've loaded up the Sample project in Eclipse (all correctly configured), sorted some of the errors out, compiled to my device and when I launch the Small App from the launcher at the bottom of the device, it force closes - it's the same with every sample/app that I tried making with the SDK.
I'm attached below my MainApplication.java and AndroidManifest.xml in the hope that someone may be able to see where the issue lies. Don't understand as it's created as per the book. Any help really is appreciated please.
MainApplication.java:
package com.sony.thirdtest;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.view.View;
import android.widget.Toast;
import com.small.sonyapptest.R;
import com.sony.smallapp.SmallAppWindow;
import com.sony.smallapp.SmallApplication;
public class MainApplication extends SmallApplication {
private Configuration mConfig;
#Override
public void onCreate() {
super.onCreate();
mConfig = new Configuration(getResources().getConfiguration());
setContentView(R.layout.activity_main);
setTitle(R.string.app_name);
SmallAppWindow.Attributes attr = getWindow().getAttributes();
attr.minWidth = 200;
attr.minHeight = 200;
attr.width = 400;
attr.height = 300;
attr.flags |= SmallAppWindow.Attributes.FLAG_RESIZABLE;
getWindow().setAttributes(attr);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainApplication.this, R.string.hello, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
#Override
protected boolean onSmallAppConfigurationChanged(Configuration newConfig) {
int diff = newConfig.diff(mConfig);
mConfig = new Configuration(getResources().getConfiguration());
// Avoid application from restarting when orientation changed
if ((diff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
return true;
}
return super.onSmallAppConfigurationChanged(newConfig);
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.small.sonyapptest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="com.sony.smallapp.permission.SMALLAPP" />
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name">
<uses-library android:name="com.sony.smallapp.framework" />
<service
android:name="com.small.sonyapptest.MainApplication"
android:exported="true" >
<intent-filter>
<action android:name="com.sony.smallapp.intent.action.MAIN" />
<category
android:name="com.sony.smallapp.intent.category.LAUNCHER" />
</intent-filter>
</service>
</application>
</manifest>

It seems that there is nothing wrong with your code. So I think the problem is with how you build the project. More exactly, how the small apps framework is included: it shouldn't be!
If you simply add the jar (from the Sony SDK) via "Java build path" -> "Add external Jar", then the classes of the api jar will be included with the application. The problem is those are only stub classes, so you can get one of two possible exceptions.
A simple and quick way to get around this (and still using the standard android sdk, and not switch to the Sony SDK) is the following:
Create a java project, and call it "SmallAppApi" for example
Inside the java project add the small app jar via "Add external jar"
In the last tab in the "Java build path" screen, called "Order and Export" make sure the small app jar is exported.
In the android project, in the "Java build path" screen, in "Projects" tab simply add the java project SmallAppApi (and remove the small app jar).
With this setup the small app jar will be used only when building. This worked fine for me.

In the service tag change android:name="com.small.sonyapptest.MainApplication" to android:name="MainApplication"

Thanks for the responses, all working now after chaning the service tag to just MainApplication.

Related

Using accessibility

I want to create an android app which will "scan" other applications'layouts and find out if there are buttons etc.
Some apps, like whatsapp, doesn't allow third parts to move into the app, so I though that using accessibility could be the solution.
Now the problem is that I've never used Accessibility, so can someone of you can please show me how to "scan" an app's layout to find buttons?
Thanks a lot
What you're looking for is an Accessibility Service. Configuring an accessibility service is somewhat complicated. I have set up a repository of accessibility boilerplate code that sets up an AccessibilityService that logs the node heirarchy to LogCat, and has the default project settings activity set up as it's settings activity. Here are some of the highlights, as I dislike just posting github repos as answers. Note that I use a lot of my own libraries. CLog is a logging library and AndroidAccessibilityUtils wraps node infos with some common utility functions. You can find references to the dependencies in the build.gradle file on the github repo at the bottom. Here are some code highlights.
Your manifest.xml file is going to be significantly different from an Activity, and should contain an entry like this in your Application element:
<application .... >
...
<service
android:name="com.moba11y.basicaccessibilityservice.BasicAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/service_config" />
</service>
...
</application>
First you need to create a subclass of Accessibility Service:
public class BasicAccessibilityService extends AccessibilityService {
static {
CLog.initialize(BasicAccessibilityService.class.getSimpleName(), BuildConfig.DEBUG);
}
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
CLog.d(event.toString());
switch (event.getEventType()) {
//On Gesture events print out the entire view heirarchy!
case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
CLog.d(A11yNodeInfo.wrap(getRootInActiveWindow()).toViewHeirarchy());
default: {
//If the event has a source, let's print it out separately.
if (event.getSource() != null) {
CLog.d(A11yNodeInfo.wrap(event.getSource()).toViewHeirarchy());
}
}
}
}
#Override
public void onInterrupt() {
CLog.e("Service Interrupted: Have never actually had this happen.");
}
}
That is the bulk of the highlights. You also should have a "service_config" XML with properties, as is referenced in the changes to the Manifest XML file. More details, and a reasonable starer point can be found in the open source repo on GitHub.
https://github.com/chriscm2006/Android-Accessibility-Service-Boilerplate

How to implement an Assistant with Google Assist API

I have been checking out and reading about Google Now on Tap (from http://developer.android.com/training/articles/assistant.html).
It was very interesting to find from that article that Now on Tap is based on Google's Assist API bundled with Marshmallow and it seems possible for us to develop our own assistant (the term Google used in the article to refer to app like Now on Tap) using the API.
However, the mentioned article only very briefly discusses how to use Assist API and I couldn't find any additional information about how to use it to develop a custom assistant even after spending a few days searching for it on the Internet. No documentation and no example.
I was wondering if any of you have experience with Assist API that you could share? Any help appreciated.
Thanks
You can definitely implement a personal assistant just like the Google Now on Tap using the Assist API starting Android 6.0. The official developer (http://developer.android.com/training/articles/assistant.html) guide tells exactly how you should implement it.
Some developers may wish to implement their own assistant. As shown in Figure 2, the active assistant app can be selected by the Android user. The assistant app must provide an implementation of VoiceInteractionSessionService and VoiceInteractionSession as shown in this example and it requires the BIND_VOICE_INTERACTION permission. It can then receive the text and view hierarchy represented as an instance of the AssistStructure in onHandleAssist(). The assistant receives the screenshot through onHandleScreenshot().
Commonsware has four demos for basic Assist API usage. The TapOffNow (https://github.com/commonsguy/cw-omnibus/tree/master/Assist/TapOffNow) should be enough to get you started.
You don't have to use the onHandleScreenshot() to get the relevant textual data, the AssistStructure in onHandleAssist() will give you a root ViewNode which usually contains all you can see on the screen.
You probably need to also implement some sorts of function to quickly locate the specific ViewNode that you want to focus on using recursive search on the children from this root ViewNode.
There is a complete example here but it's too complicated to start.
This is my example works on android 7.1.1
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eaydin79.voiceinteraction">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:theme="#style/AppTheme" >
<service
android:name="voiceInteractionService"
android:permission="android.permission.BIND_VOICE_INTERACTION" >
<meta-data
android:name="android.voice_interaction"
android:resource="#xml/interaction_service" />
<intent-filter>
<action android:name="android.service.voice.VoiceInteractionService" />
</intent-filter>
</service>
<service
android:name="voiceInteractionSessionService"
android:permission="android.permission.BIND_VOICE_INTERACTION" >
</service>
</application>
</manifest>
this is interaction_service.xml file stored in res\xml folder
<?xml version="1.0" encoding="utf-8"?>
<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
android:sessionService="com.eaydin79.voiceinteraction.voiceInteractionSessionService"
android:recognitionService="com.eaydin79.voiceinteraction.voiceInteractionService"
android:supportsAssist="true" />
voiceInteractionService.java
package com.eaydin79.voiceinteraction;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionSession;
public class voiceInteractionService extends VoiceInteractionService {
#Override
public void onReady() {
super.onReady();
}
}
voiceInteractionSessionService.java
package com.eaydin79.voiceinteraction;
import android.os.Bundle;
import android.service.voice.VoiceInteractionSession;
import android.service.voice.VoiceInteractionSessionService;
public class voiceInteractionSessionService extends VoiceInteractionSessionService {
#Override
public VoiceInteractionSession onNewSession(Bundle bundle) {
return new voiceInteractionSession(this);
}
}
voiceInteractionSession.java
package com.eaydin79.voiceinteraction;
import android.app.VoiceInteractor;
import android.content.Context;
import android.os.Bundle;
import android.service.voice.VoiceInteractionSession;
import android.media.AudioManager;
public class voiceInteractionSession extends VoiceInteractionSession {
voiceInteractionSession(Context context) {
super(context);
}
#Override
public void onShow(Bundle args, int showFlags) {
super.onShow(args, showFlags);
//whatever you want to do when you hold the home button
//i am using it to show volume control slider
AudioManager audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
if (audioManager != null) audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
hide();
}
}

AdActivity leak on AdMob (SDK 7.0) for Android

I have memory leaks regarding Interstitial ads of AdMob with AdActivity object. Whenever an ad is shown, AdActivity object count in the memory increments by 1. I inspect all changes via MAT after explicit GC calls. I use the latest versions of everything.
At first, I thought that this is related to how I implemented my UI or project, but creating a fresh and empty project shows the same leak.
This leak has also existed in the previous Admob SDK (Google Play Services) and now it exists in version 7.0 too.
I see that people try to solve these kinds of issues by creating a SingleInstance empty activity just to show and set as the context of the interstitial ads. I tried them all and they did not work for my case. Some did help but I even couldn't use it because of the flow of my app. launchMode in Android has limitations and it does not help me on my case.
I already notified the AdMob team but even they fix it, it doesn't seem to happen in a short time as they have just released the version 7.0 SDK.
I do not understand how others do not report leaks like this. It cannot be a special case just for me as it happens on even samples or default templates. If anyone somehow solved this issue (including ugly reflection hacks) please share your experience. I have been working on this for months! Really!
AndroidManifest:
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name="MyApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".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>
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
</application>
MainActivity:
package com.example.leaktest1;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
private InterstitialAd interstitial=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
interstitial= new InterstitialAd(getApplicationContext());
interstitial.setAdUnitId("YOUR-ADD-ID");
AdRequest adRequest2 = new AdRequest.Builder()
// .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitial.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
if(interstitial.isLoaded()){
interstitial.show();
}
}
});
interstitial.loadAd(adRequest2);
}
#Override
protected void onDestroy() {
if(interstitial!=null){
interstitial.setAdListener(null);
interstitial=null;
}
super.onDestroy();
}
}
Layout:
<RelativeLayout 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: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="com.example.leaktest1.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
Start the app. When the ad is shown, close it with backpress and hit back button again to exit app.
App will still be in memory, but the activity is gone. Now touch the app icon to start the activity again, it will show the ad again, exit like you did before.
Cause GC multiple times and get heap dump. You will see that there are 2 AdActivity objects (and also many other related objects). It will continue to grow according to the number of shown ads.
The following did not work too (it still leaks):
/*
interstitial.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
}
});*/
interstitial.loadAd(adRequest2);
Runnable r=new Runnable() {
#Override
public void run() {
if(interstitial.isLoaded()){
interstitial.show();
}
}};
new Handler().postDelayed(r,10000);
And putting code inside a button did not work too (it still leaks):
Button b = new Button(this);
b.setText("Touch me");
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(interstitial.isLoaded()){
interstitial.show();
}
}
});
ViewGroup v = (ViewGroup) this.findViewById(android.R.id.content);
v.addView(b);
Leak platform and exceptions:
This leak happens on various devices from Samsung and Asus with various un-modded (original firmware) Androis systems from 2.3 to 4.4. It also happens on any setup of android simulator.
(This leak does not show up on rooted Cyanogenmod (Galaxy S3) Android 4.4.4)
UPDATE
The leak does not vanish if I use Activity context instead of Application context. It also causes Activity leak too.

Android emulator rotates but app doesn't redraw

I've seen pictures of this elsewhere, but from some time back where the answer is generally "this is a known issue with Android 2.3" I'm using 4.4, so that's definitely not the answer.
I have about the simplest program ever: "Hello, Android". When I launch the emulator, it load up in portrait mode. Using Fn-Ctrl-F11 (Mac), the emulator rotates to landscape mode. But the application and the phone controls do not redraw - the whole thing just looks sideways.
Here's the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.helloandroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="18"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.test.helloandroid.Hello"
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>
</manifest>
and the Activity XML file:
<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"
tools:context=".Hello" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</LinearLayout>
I'm building with Eclipse, the ADT bundle build v22.3.0-887826, although I can't imagine that matters for something this trivial.
My emulator is for device Galaxy Nexus, Android 4.4 API level 19. I've tried this with Hardware keyboard present marked and unmarked. I found reference to a "keyboard lid support" setting which I haven't seen anywhere - this comment is from 3/12 & so may be outdated.
This is my first Android app, so I'm a complete novice at debugging in this environment. TIA for any suggestions on what I'm missing.
EDIT: Adding code for hello.java
package com.test.helloandroid;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class Hello extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.hello, menu);
return true;
}
}
If you are beginner,you should go through this reference document to know about Activity lifecycle.
Here,I'm including few Log and Toast to make it easier to understand the process happens when you rotate the screen.
Example:
package com.test.helloandroid;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class Hello extends Activity {
private static final String TAG = "Hello";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello);
Log.d(TAG, "onCreate");
Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.hello, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
Toast.makeText(this, "onResume", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
Toast.makeText(this, "onPause", Toast.LENGTH_SHORT).show();
}
}
I hope it will be helpful !!
Apparently,everything old is new again: orientation change bug in 4.4
"The more they overthink the plumbing, the easier it is to stop up the drain."
It's good to know that I've not missed something obvious; OTOH this is a pretty obvious FAIL on the part of google's quality assurance... did bill gates sneak in there while no one was looking? Or are they greedy & trying to sell phones for testing by mucking up the emulators? Looks like there's a device in my future.
Edit :
Reference : Answered by CommonsWare,the Framework Engineer of Android.
Impossible to rotate the emulator with android 4.4

Application behaves two different ways when user chose open and done at the time of installation in android.so what is the resion?

NOTE: PLEASE DO NOT TEST IT DIRECTLY DEVICE WITH ECLIPSE. PLEASE GENERATE .APK FILE FIRST LATER COPY THAT .APK INTO YOUR DEVICE MEMORY THEN INSTALL FROM THERE
Application flow
1)open Loading screen(appear 5 sec)----->open News title screen
2)from News screen when user click on back button i override
public void onBackPressed() {
moveTaskToBack(true);
}
3)when user again open his application he directly open his news title screen
this is my requirement and i done this successfully when user chose case1 at the time of installation which is specified in following cases
I build apk then upload it to server. Then on my galaxy 2.2 I type in url in a browser and download apk. After its finished downloading I install it. When Install is finished I have two options
Case 1 :- Done
case 2 :- Open
when I press Open application open successfully first time. when i click on application again(Second time) it again open Loading screen.
But when I choose Done and later access it through Application menu it works ok! so this choice determines how app behaves later? why? how? I'm puzzled
now i am upload some simple sample code
Activity 1: HelloWorldActivity.java
this contain simple button named as "first screen"
package com.hb.Screens;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class HelloWorldActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button tv=(Button) findViewById(R.id.btn);
tv.setText("First screen");
tv.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(HelloWorldActivity.this, secondScreen.class));
HelloWorldActivity.this.finish();
}
});
}
}
Activity 2:secondScreen.java
This contain simple button named as "Second screen"
package com.hb.Screens;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
public class secondScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button tv = (Button) findViewById(R.id.btn);
tv.setText("Second screen");
}
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
#Override
protected void onResume() {
super.onResume();
}
}
This is my manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hb.Screens"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".HelloWorldActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".secondScreen"></activity>
</application>
</manifest>
If you have declare more than one activity as a launcher activity then remove it. If you have two launcher activities in the manifest then it may issue. I had issue to crash when I have declared more than one activity as a launcher activity.
Open is the facility to directly open the application when it finish the installation.
Done is the option if you have no plan to open the application after installation.
Open is simply, launch the newly installed app
and
Done is, simply return to where your last location is.
It both doesn't have anything to do with how app behaves.

Categories

Resources