I have a gif image (3 dots appearing and disappearing one by one) which I am trying to set on my splash screen. How to do that using just load-animation in xml? The below is the code for my splash screen.
public class MainActivity extends Activity {
private static String TAG = MainActivity.class.getName();
private static long SLEEP_TIME = 5; // Sleep for some time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Start timer and launch main activity
IntentLauncher launcher = new IntentLauncher();
launcher.start();
}
private class IntentLauncher extends Thread {
#Override
/**
* Sleep for some time and than start new activity.
*/
public void run() {
try {
// Sleeping
Thread.sleep(SLEEP_TIME*1000);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
// Start main activity
Intent intent = new Intent(MainActivity.this, Option.class);
MainActivity.this.startActivity(intent);
MainActivity.this.finish();
}
}
}
Android doesn't natively support gifs in that way. To play a gif you can either load it in a WebView or use the Movie class.
There's a helpful Ruby script (original gist here) that will convert a gif to an animation-list xml file.
#!/usr/bin/ruby
require 'fileutils'
require 'RMagick'
require 'slop'
require 'builder'
opts = Slop.new do
banner "gif2animdraw [options]\n"
on :i, :input=, 'path to animated GIF (or directory of GIFs)', :required => true
on :o, :outdir=, 'path to root output directory', :required => true
on :d, :density=, 'density name to use for frames', :required=>true
on :oneshot, 'if set, animation does not repeat', :required => false, :default=>false
help
end
begin
opts.parse
rescue
puts opts.help
exit -1
end
if !['ldpi', 'mdpi', 'tvdpi', 'hdpi', 'xhdpi', 'xxhdpi', 'xxxhdpi'].include?(opts[:d])
puts "Invalid density #{opts[:d]}"
exit -1
end
glob=File.directory?(opts[:i]) ? File.join(opts[:i], '*.gif') : opts[:i]
Dir[glob].each do |gif|
input=Magick::ImageList.new(gif).coalesce
output=File.join(opts[:o], 'drawable')
output_density=File.join(opts[:o], 'drawable-'+opts[:d])
basename=File.basename(gif, '.gif').downcase.gsub(/\W/,'_')
FileUtils.mkdir_p output
FileUtils.mkdir_p output_density
Dir.glob(File.join(output_density, basename+'*.png')).each {|f| File.delete(f) }
input.write File.join(output_density, basename+'_%d.png')
builder = Builder::XmlMarkup.new(:indent=>2)
builder.tag!('animation-list',
'xmlns:android'=>'http://schemas.android.com/apk/res/android',
'android:oneshot'=>opts[:oneshot]) do
i=0
input.each do |frame|
builder.item('android:drawable'=>"#drawable/#{basename}_#{i}",
'android:duration'=>frame.delay*1000/input.ticks_per_second)
i+=1
end
end
open(File.join(output, basename+'.xml'), 'w') do |f|
f.puts builder.target!
end
end
I think using a GIF is a rather heavy solution to your problem. Have you thought about using a library such as WaitingDots.
The author uses a custom textview and text span to achieve the same result. This solution will provide you with must for room for customizing the animation.
Related
How to release foreground to the previous application in Flutter (Dart) ? I mean, how to force to call the onPause or viewWillDisappear to let my app disappear and let the previous app come back to the foreground.
Is there a method thant I can call ?
Edit : I don't wan't to close my app, juste "minimize" it.
You are struggling with a mismatch between Flutter's architecture and Android's. In your previous question you needed a way to bring your flutter app to the foreground, to which the answer is a full-screen intent notification. The problem is that in native Android, you would probably have used the NEW_TASK flag to start a new task. As Flutter only has one activity, it's necessary to use USE_CURRENT instead.
With NEW_TASK, you would use Activity.finish() to close it, closing just the new activity. If you did that with Flutter, that would probably close the whole app (because of the use of USE_CURRENT).
It might be possible to have a native Android app (allowing you to have more direct control of the launch of activities) and to use Add2App to add the Flutter screen(s). If you get that to work, I'd like to know.
I finally got a solution ! I haven't found yet a solution for the IOS side : I'm working on it.
I used MethodChannel to ask to the native side to minimize itself. For Android use this.moveTaskToBack(true); ! If you got an Objectif-C alternative, it will be perfect !
Dart:
class _MyHomePageState extends State<MyHomePage> {
static const MethodChannel actionChannel = MethodChannel('method.channel');
Future<void> _minimize() async{
try{
await actionChannel.invokeMethod('minimize');
} on PlatformException catch(e) {
print('${e.message}');
}
}
}
Android:
public class MainActivity extends FlutterActivity {
private static final String ACTION_CHANNEL = "method.channel";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Action-post-alert method
new MethodChannel(getFlutterView(), ACTION_CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
#Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("minimize")) {
this.moveTaskToBack(true);
result.success(true);
} else {
result.notImplemented();
}
}
}
);
}
}
I'm developing Android app on Android studio using Opencv library and when I try to open my app it opens then right after that it closes and displaying crash message. I'm new on mobile development
Using : OpenCV310, Android Studio 3.0,
public class ScanLicensePlateActivity extends AppCompatActivity {
protected AnylineOcrScanView scanView;
private LicensePlateResultView licensePlateResultView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Set the flag to keep the screen on (otherwise the screen may go dark during scanning)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_anyline_ocr);
String license = getString(R.string.anyline_license_key);
// Get the view from the layout
scanView = (AnylineOcrScanView) findViewById(R.id.scan_view);
// Configure the view (cutout, the camera resolution, etc.) via json
// (can also be done in xml in the layout)
scanView.setConfig(new AnylineViewConfig(this, "license_plate_view_config.json"));
// Copies given traineddata-file to a place where the core can access it.
// This MUST be called for every traineddata file that is used
// (before startScanning() is called).
// The file must be located directly in the assets directory
// (or in tessdata/ but no other folders are allowed)
scanView.copyTrainedData("tessdata/GL-Nummernschild-Mtl7_uml.traineddata",
"8ea050e8f22ba7471df7e18c310430d8");
scanView.copyTrainedData("tessdata/Arial.traineddata", "9a5555eb6ac51c83cbb76d238028c485");
scanView.copyTrainedData("tessdata/Alte.traineddata", "f52e3822cdd5423758ba19ed75b0cc32");
scanView.copyTrainedData("tessdata/deu.traineddata", "2d5190b9b62e28fa6d17b728ca195776");
// Configure the OCR for license plate scanning via a custom script file
// This is how you could add custom scripts optimized by Anyline for your use-case
AnylineOcrConfig anylineOcrConfig = new AnylineOcrConfig();
anylineOcrConfig.setCustomCmdFile("license_plates.ale");
// set the ocr config
scanView.setAnylineOcrConfig(anylineOcrConfig);
// initialize with the license and a listener
scanView.initAnyline(license, new AnylineOcrListener() {
#Override
public void onReport(String identifier, Object value) {
// Called with interesting values, that arise during processing.
// Some possibly reported values:
//
// $brightness - the brightness of the center region of the cutout as a float value
// $confidence - the confidence, an Integer value between 0 and 100
// $thresholdedImage - the current image transformed into black and white
// $sharpness - the detected sharpness value (only reported if minSharpness > 0)
}
#Override
public boolean onTextOutlineDetected(List<PointF> list) {
// Called when the outline of a possible text is detected.
// If false is returned, the outline is drawn automatically.
return false;
}
#Override
public void onResult(AnylineOcrResult result) {
// Called when a valid result is found
String results[] = result.getText().split("-");
String licensePlate = results[1];
licensePlateResultView.setLicensePlate(licensePlate);
licensePlateResultView.setVisibility(View.VISIBLE);
}
#Override
public void onAbortRun(AnylineOcrError code, String message) {
// Is called when no result was found for the current image.
// E.g. if no text was found or the result is not valid.
}
});
// disable the reporting if set to off in preferences
if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
SettingsFragment.KEY_PREF_REPORTING_ON, true)) {
// The reporting of results - including the photo of a scanned meter -
// helps us in improving our product, and the customer experience.
// However, if you wish to turn off this reporting feature, you can do it like this:
scanView.setReportingEnabled(false);
}
addLicensePlateResultView();
}
private void addLicensePlateResultView() {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
licensePlateResultView = new LicensePlateResultView(this);
licensePlateResultView.setVisibility(View.INVISIBLE);
mainLayout.addView(licensePlateResultView, params);
licensePlateResultView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startScanning();
}
});
}
private void startScanning() {
licensePlateResultView.setVisibility(View.INVISIBLE);
// this must be called in onResume, or after a result to start the scanning again
scanView.startScanning();
}
#Override
protected void onResume() {
super.onResume();
startScanning();
}
#Override
protected void onPause() {
super.onPause();
scanView.cancelScanning();
scanView.releaseCameraInBackground();
}
#Override
public void onBackPressed() {
if (licensePlateResultView.getVisibility() == View.VISIBLE) {
startScanning();
} else {
super.onBackPressed();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}}
source code is here.
If possible please help.
Logcat error shown here
Ideally more information regarding the error would be best i.e the opencv library version etc. Given it seems to be an Android issue, I would advise
File and issue or view issues pertaining to this error on their github page. Search for related Android errors to see if they match.
IF you cannot find a related error, file an issue there.
I am building this app, that will recognize painting and will display the info about it with the help of AR.
And I need to call multiple image target but not simultaneously, it will only call the image target if it is detected by AR camera.
*Ive tried creating many scenes with Image target on it but I cant call different imagetarget it keeps on reverting to only 1 imagetarget.
This is wat you can see in menu,
Main menu
Start AR camera(This part should have many image target but not detecting it simultaneously)
Help(how to use the app)
Exit
*Im using vuforia in creating AR
Thanks in advance for those who will help me.
This is the imagetarget and its Database
View post on imgur.com
Run the multi target scene sample. There are three target (stone, wood and road).
Each contains the TrackableBehaviour component.
Grab it and disable it in Start. If you do it in Awake it will be set back to active most likely in the Awake of the component itself or via some other manager.
public class TrackerController:MonoBehaviour
{
private IDictionary<string,TrackableBehaviours> trackers = null;
private void Start()
{
this.trackers = new Dictionary<string,TrackableBehaviour>();
var trackers = FindObjectsOfType<TrackableBehaviour>();
foreach(TrackingBehaviour tb in trackers)
{
this.trackers.Add(tb.TrackableName, tb);
tb.enabled = false;
}
}
public bool SetTracker(string name, bool value)
{
if(string.IsNullOrEmpty(name) == true){ return false; }
if(this.trackers.ContainsKey(name) == false){ return false; }
this.trackers[name].enabled = value;
return true;
}
}
The method finds all TrackableBehaviour and places them in a dictionary for easy access. The setting method return boolean, you can change it to throw exception or else.
I am creating a game in cocos2D android. I need to have an alert at the end of my game.
Can I do this in cocos2D android?
I think you should do this with JNI using the showMessageBoxJNI(const char * pszMsg, const char * pszTitle) method in the MessageJni.cpp class (in /cocos2dx/platform/android/jni). Simply import MessageJni.cpp in the class where you want to add an alert:
#include "./cocos2dx/platform/android/jni/MessageJni.h" // Note: this is a relative path, take care to the beginnin of the path "./" or "././" or etc..
showMessageBoxJNI("My alert message", "My alert title"); //Add this where you want in your class
Hope this helps.
Use menu for that. I think it is better option. on doing this, you can put click even to game over.when your game s over write below code
CCMenuItemFont item6 = CCMenuItemFont.item("Game over", this, "gameover");
CCMenuItemFont.setFontSize(14);
item6.setColor( new ccColor3B(0,0,0));
CCMenu menu = CCMenu.menu(item6);
menu.alignItemsVertically();
addChild(menu);
and onclick of that menu this write below function. it will be called onclick.
public void gameover()
{
try {
CCScene scene = nextlevellayer.scene();
CCDirector.sharedDirector().pushScene(scene);
} catch (Exception e) {
e.printStackTrace();
}
}
I want to extend a common security check to nearly every view of my application. To do this, I have made this class
public class ProtectedActivity extends ActivityBase {
boolean isAuthenticated = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread validationThread = new Thread()
{
#Override
public void run()
{
try
{
isAuthenticated = UserService.validateToken();
}
catch (FTNIServiceException e)
{
//eat it
}
finally
{
if (!isAuthenticated)
{
startActivity(new Intent(ProtectedActivity.this, SignInActivity.class));
finish();
}
}
}
};
validationThread.start();
}
}
The logic is simple. Validate the user against my restful api to make sure they are signed in. If they aren't, show them to the signin page.
This works great, because to add the security check, all I need to do is inherit from my ProtectedActivity.
public class MainMenuActivity extends ProtectedActivity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
The problem is, however, that I periodically receive View not attached to window manager errors. I understand why this is happening. I am starting a new intent in the parent class, and the child lives on. to attempt to alter it's view even though a new intent has started. What is a better way to handle this so that if a user is not authenticated (such as their session expires serverside), it won't error when sending the user to the sign in screen?
Don't you Thread. Use AsyncTask instead which should handle your references to windows correctly.
On a different note, I would change this to a different implementation. Why don't use the Preferences storage on the phone to store some kind token. If the token is not valid then request a new token and all the stuff you are doing currently. This way is better because you don't want to request a REST call every time.
I imagine something like this (pseudo code)
Check if credentials exist in Preference
if(valid) then do nothing
else use AsyncTask and pop up a loader screen "Waiting..."