battle programmers alliance
Would you like to react to this message? Create an account in a few clicks or log in to continue.

battle programmers allianceLog in

the LivinGrimoire Artificial General Intelligence software design pattern forum

android mobile app development grimoire

power_settings_newLogin to reply
3 posters

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid bound services and binders

more_horiz
android mobile app development grimoire - Page 3 2eutll

main xml :

Code:

<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:background="#FFFFFF"
    android:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    tools:context="com.justforum.yotamarker.mytimeservice.MainActivity" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="-80dp"
        android:src="@mipmap/ic_launcher" />

    <Button
        android:id="@+id/print_timestamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="130dp"
        android:text="Print Timestamp" />

    <TextView
        android:id="@+id/timestamp_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/print_timestamp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="120dp"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/print_timestamp"
        android:layout_centerHorizontal="true"
        android:text="Stop Service" />

</RelativeLayout>




BoundService.java


Code:

package com.justforum.yotamarker.mytimeservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Chronometer;

public class BoundService extends Service {
    private static String LOG_TAG = "BoundService";
    private IBinder mBinder = new MyBinder();
    private Chronometer mChronometer;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.v(LOG_TAG, "in onCreate");
        mChronometer = new Chronometer(this);
        mChronometer.setBase(SystemClock.elapsedRealtime());
        mChronometer.start();
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.v(LOG_TAG, "in onBind");
        return mBinder;
    }

    @Override
    public void onRebind(Intent intent) {
        Log.v(LOG_TAG, "in onRebind");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.v(LOG_TAG, "in onUnbind");
        return true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v(LOG_TAG, "in onDestroy");
        mChronometer.stop();
    }

    public String getTimestamp() {
        long elapsedMillis = SystemClock.elapsedRealtime()
                - mChronometer.getBase();
        int hours = (int) (elapsedMillis / 3600000);
        int minutes = (int) (elapsedMillis - hours * 3600000) / 60000;
        int seconds = (int) (elapsedMillis - hours * 3600000 - minutes * 60000) / 1000;
        int millis = (int) (elapsedMillis - hours * 3600000 - minutes * 60000 - seconds * 1000);
        return hours + ":" + minutes + ":" + seconds + ":" + millis;
    }

    public class MyBinder extends Binder {
        BoundService getService() {
            return BoundService.this;
        }
    }
}


add :
<service android:name="com.justforum.yotamarker.mytimeservice.BoundService">
       </service>

like this :

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.justforum.yotamarker.mytimeservice">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.justforum.yotamarker.mytimeservice.BoundService">
        </service>
    </application>

</manifest>

(package name varies for you)

MainActivity.java

Code:

package com.justforum.yotamarker.mytimeservice;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.justforum.yotamarker.mytimeservice.BoundService;

public class MainActivity extends AppCompatActivity {
    BoundService mBoundService;
    boolean mServiceBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView timestampText = (TextView) findViewById(R.id.timestamp_text);
        Button printTimestampButton = (Button) findViewById(R.id.print_timestamp);
        Button stopServiceButon = (Button) findViewById(R.id.stop_service);
        printTimestampButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mServiceBound) {
                    timestampText.setText(mBoundService.getTimestamp());
                }
            }
        });

        stopServiceButon.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mServiceBound) {
                    unbindService(mServiceConnection);
                    mServiceBound = false;
                }
                Intent intent = new Intent(MainActivity.this,
                        BoundService.class);
                stopService(intent);
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent(this, BoundService.class);
        startService(intent);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mServiceBound) {
            unbindService(mServiceConnection);
            mServiceBound = false;
        }
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServiceBound = false;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            BoundService.MyBinder myBinder = (BoundService.MyBinder) service;
            mBoundService = myBinder.getService();
            mServiceBound = true;
        }
    };
}


hadouken.




example 2 : police siren service : displays police lights on main activity layout upon screen click event :

activity_main.xml :

Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llyBack"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvLight1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:textSize="50sp" />

    <TextView
        android:id="@+id/tvLight2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:textSize="50sp" />
</LinearLayout>


MyService.java

Code:

package com.justforum.yotamarker.serviceviews;

import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;

public class MyService extends Service {
    //create binder
    private final IBinder myBinder = new MyBinder();
    //set state to 0
    private int state = 0;
    //set activity to null to avoid exception
    private Activity myActivity = null;
    //set two views for our text view
    private View light1, light2;
    //hold sequence of light
    private State[] myStates;
    //set mode to 0
    private int mode = 0;


    //since when services is created, he run it's default c'tor, we override it with our c'tor
    public MyService() {
        //get the first sequence
        myStates = setPolice();
        //create new thread, which run separated from our main thread
        new Thread(new Runnable() {
            @Override
            public void run() {
                //will run until we set the activity to nu
                while (true) {
                    //get state
                    state = (state + 1) % myStates.length;
                    Log.d("TESTING", "state=" + state);
                    if (myActivity != null) {
                        //since we are inside a thread, and we can not access to other thread, we run it on ui thre
                        myActivity.runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                //set the colour
                                light1.setBackgroundColor(myStates[state].color1);
                                light2.setBackgroundColor(myStates[state].color2);
                            }
                        });
                    }
                    try {
                        //make thread some sleep, for biker effect
                        Thread.sleep(myStates[state].delay);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    //our sequence builders
    public State[] setPolice() {
        State[] police = new State[12];
        police[0] = new State(Color.RED, Color.BLACK, 120);
        police[1] = new State(Color.BLACK, Color.BLACK, 50);
        police[2] = new State(Color.RED, Color.BLACK, 120);
        police[3] = new State(Color.BLACK, Color.BLACK, 50);
        police[4] = new State(Color.RED, Color.BLACK, 120);
        police[5] = new State(Color.BLACK, Color.BLACK, 70);

        police[6] = new State(Color.BLACK, Color.BLUE, 120);
        police[7] = new State(Color.BLACK, Color.BLACK, 50);
        police[8] = new State(Color.BLACK, Color.BLUE, 120);
        police[9] = new State(Color.BLACK, Color.BLACK, 50);
        police[10] = new State(Color.BLACK, Color.BLUE, 120);
        police[11] = new State(Color.BLACK, Color.BLACK, 70);

        return police;
    }

    public State[] setPolice1() {
        State[] police = new State[12];
        police[0] = new State(Color.BLUE, Color.BLACK, 120);
        police[1] = new State(Color.BLACK, Color.BLACK, 50);
        police[2] = new State(Color.BLUE, Color.BLACK, 120);
        police[3] = new State(Color.BLACK, Color.BLACK, 50);
        police[4] = new State(Color.BLUE, Color.BLACK, 120);
        police[5] = new State(Color.BLACK, Color.BLACK, 70);

        police[6] = new State(Color.BLACK, Color.BLUE, 120);
        police[7] = new State(Color.BLACK, Color.BLACK, 50);
        police[8] = new State(Color.BLACK, Color.BLUE, 120);
        police[9] = new State(Color.BLACK, Color.BLACK, 50);
        police[10] = new State(Color.BLACK, Color.BLUE, 120);
        police[11] = new State(Color.BLACK, Color.BLACK, 70);

        return police;
    }

    public State[] setFire() {
        State[] fire = new State[12];
        fire[0] = new State(Color.RED, Color.BLACK, 120);
        fire[1] = new State(Color.BLACK, Color.BLACK, 50);
        fire[2] = new State(Color.RED, Color.BLACK, 120);
        fire[3] = new State(Color.BLACK, Color.BLACK, 50);
        fire[4] = new State(Color.RED, Color.BLACK, 120);
        fire[5] = new State(Color.BLACK, Color.BLACK, 70);

        fire[6] = new State(Color.BLACK, Color.RED, 120);
        fire[7] = new State(Color.BLACK, Color.BLACK, 50);
        fire[8] = new State(Color.BLACK, Color.RED, 120);
        fire[9] = new State(Color.BLACK, Color.BLACK, 50);
        fire[10] = new State(Color.BLACK, Color.RED, 120);
        fire[11] = new State(Color.BLACK, Color.BLACK, 70);

        return fire;
    }

    //handle our binder
    @Nullable
    @Override

    public IBinder onBind(Intent intent) {
        return myBinder;
    }

    //we use inner class for less coding
    public class MyBinder extends Binder {
        public MyService getService() {
            return MyService.this;
        }

    }

    //return activity
    public Activity getActivity() {
        return myActivity;
    }

    //set pointers to activity xml, which we provide from main activity
    public void setActivity(Activity activity, View light1, View light2) {
        this.myActivity = activity;
        this.light1 = light1;
        this.light2 = light2;
    }

    //clear activity and pointers for garbage collector
    public void setNoActivity() {
        this.myActivity = null;
        this.light1 = null;
        this.light2 = null;
    }

    //inner class for better sequance builder
    private class State {
        int color1;
        int color2;
        int delay;

        public State(int color1, int color2, int delay) {
            this.color1 = color1;
            this.color2 = color2;
            this.delay = delay;
        }
    }

    //changeing modes....
    public void changeMode() {
        mode = (mode + 1) % 3;
        switch (mode) {
            case 0:
                myStates = setPolice();
                break;
            case 1:
                myStates = setFire();
                break;
            case 2:
                myStates = setPolice1();
                break;
        }
    }
}


AndroidManifest.xml

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.justforum.yotamarker.serviceviews">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.justforum.yotamarker.serviceviews.MyService">
        </service>
    </application>

</manifest>


MainActivity.java :

Code:

package com.justforum.yotamarker.serviceviews;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

//we use onclick & onLonclick listener for implementing the methods here
public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnLongClickListener {
    //declare of our bounded services
    private MyService myService;
    //a boolean which indicates if the service is bounded or not
    private boolean isBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setPointer();
    }

    private void setPointer() {
        //since we need only declare of click events, we don't need to create an instanc
        findViewById(R.id.llyBack).setOnClickListener(this);
        findViewById(R.id.llyBack).setOnLongClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //if service is null, we will create it, else, we set null so garbage collector will clean the memory
        if (myService.getActivity() == null) {
            //we send here the activity, and pointers to our layout elements
            myService.setActivity(this, findViewById(R.id.tvLight1), findViewById(R.id.tvLight2));
        } else {
            myService.setNoActivity();
        }
    }

    @Override
    protected void onStart() {
        //when activity is started, bound the service
        super.onStart();
        bind();
    }

    private void bind() {
        // Bind to LocalService
        Intent intent = new Intent(this, MyService.class);
        //create the service automatic by the connection and send the intent
        bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
    }

    /**
     * Defines callbacks for service binding, passed to bindService()
     */
    private ServiceConnection myConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            // We've bound to MyService, cast the IBinder and get MyService instance
            MyService.MyBinder myBinder = (MyService.MyBinder) service;
            myService = myBinder.getService();
            isBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            isBound = false;
        }
    };

    @Override
    protected void onStop() {
        //when our app is stopped, clear the service
        super.onStop();
        myService.setNoActivity();
    }

    @Override
    public boolean onLongClick(View v) {
        //if we use long click , change mode
        myService.changeMode();
        return true;
    }
}



siren service

in MyService :
@Override
public int onStartCommand (Intent intent, int flags, int startId){

   // several lines of awesome code

   return START_STICKY;
}

or

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
   startForeground(ONGOING_NOTIFICATION_ID, notification);

   return  super.onStartCommand(intent, flags, startId);
}

will make it sticky to run even if the device was restarted as long as it's app is installed


android mobile app development grimoire - Page 3 2f3yqf

Last edited by Moti Barski on Wed Oct 10, 2018 1:54 am; edited 5 times in total

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid notifications step by step walkthrough

more_horiz
android mobile app development grimoire - Page 3 2ex0dm

activity_main.xml :

Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="16dp">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#009fff"
        android:text="client msg"
        android:textColor="#fff"
        android:textSize="22sp"
        android:textStyle="bold"
        android:id="@+id/btnSnackBar"
        />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#009fff"
        android:text="display smart notification"
        android:textColor="#fff"
        android:textSize="22sp"
        android:textStyle="bold"
        android:id="@+id/btnSimpleNotAdv"
        android:layout_marginTop="20dp"
        />
</LinearLayout>



note above #009fff is FB color.

res/layout/activitybuf.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="test working summoned with notification"/>
</android.support.constraint.ConstraintLayout>


the above activity will be displayed by clicking the notification.


buf.java (said activity):

Code:

package com.justforum.yotamarker.notification3;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class buf extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_buf);
    }
}


MainActivity.java :

Code:

package com.justforum.yotamarker.notification3;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.support.design.widget.Snackbar;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Button btnSnack,btnNot,btnNotAdv;
    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
    }

    private void setPointer() {
        this.context=this;
        this.btnSnack=findViewById(R.id.btnSnackBar);
        this.btnNotAdv=findViewById(R.id.btnSimpleNotAdv);
        btnSnack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String message = "sale on red pills";
                int myDuration = 5000;
                Snackbar.make(v,message,Snackbar.LENGTH_LONG) //create the snack bar
                        .setAction("got ya", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Toast.makeText(MainActivity.this, "red pill vendor on his way to you", Toast.LENGTH_SHORT).show();
                            }
                        })
                        .setDuration(myDuration)
                        .setActionTextColor(Color.GREEN)
                        .show();
            }
        });
        btnNotAdv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createNotificationWithAction(70,R.drawable.pill,"red pill party", "order now");
            }
        });
    }

    private void createNotificationWithAction(int nId, int icon, String title, String msg) {
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context.getApplicationContext(), "notify_001");
        Intent ii = new Intent(context.getApplicationContext(), buf.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, ii, 0);

        NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
        bigText.bigText("hadouken");
        bigText.setBigContentTitle("Today's red pill");
        bigText.setSummaryText("Text in detail");

        mBuilder.setContentIntent(pendingIntent);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher_round);
        mBuilder.setContentTitle("Your Title");
        mBuilder.setContentText("Your text");
        mBuilder.setPriority(Notification.PRIORITY_MAX);
        mBuilder.setStyle(bigText);

        NotificationManager mNotificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("notify_001",
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            mNotificationManager.createNotificationChannel(channel);
        }

        mNotificationManager.notify(0, mBuilder.build());


    }
}



notice the above can summon regular smart activity using btnSimpleNotAdv

or new style notification( Snack Bar ) using
using btnSnackBar but for that go to gradle(module) and add :

implementation 'com.android.support:design:27.1.1'

if your phone has APK < 27 change the gradle like this :


Code:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.justforum.yotamarker.notification3"
        minSdkVersion 26
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    implementation 'com.android.support:design:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


notice the 26 ? that's below my phone's APK so the app can run on it and still use the snack bar.

finally in manifest add :


<activity
           android:name=".buf"
           android:launchMode="singleTask"
           android:taskAffinity=""
           android:excludeFromRecents="true">
       </activity>

so said AndroidManifest.xml looks like :

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.justforum.yotamarker.notification3">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".buf"
            android:launchMode="singleTask"
            android:taskAffinity=""
            android:excludeFromRecents="true">
        </activity>
    </application>

</manifest>



shinra tensei !

descriptionandroid mobile app development grimoire - Page 3 Emptybtn on long click ed

more_horiz
main xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/editText"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ShowData"
        android:id="@+id/b1"
        android:layout_below="@+id/editText"
        android:layout_marginTop="62dp" />

</android.support.constraint.ConstraintLayout>


main java:

Code:

package com.justforum.yotamarker.mylongclick;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button)findViewById(R.id.b1);
        button.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Toast.makeText(getApplicationContext(),"You have pressed it long :)", Toast.LENGTH_LONG).show();
                return true;
            }
        });
    }
}


btn

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio dynamic BroadcastReceiver

more_horiz
android mobile app development grimoire - Page 3 2f9l6w

see explanation in code comments (main activity)


activity_main.xml :


Code:

<LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android" >

    <!--<Button-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:text="Custom reciver"-->
        <!--android:background="#009fff"-->
        <!--android:layout_marginTop="30dp"-->
        <!--android:textColor="#fff"-->
        <!--android:textSize="22sp"-->
        <!--android:id="@+id/btnCustom"/>-->

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Dynamic reciver"
        android:background="#009fff"
        android:layout_marginTop="30dp"
        android:textColor="#fff"
        android:textSize="22sp"
        android:id="@+id/btnDynamic"/>

</LinearLayout>


receivers :
1
Eng.java :

Code:

package com.justforum.yotamarker.testreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class Eng extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("buf", "onReceive: all you need is Buf!!" );
    }
}


2 Heb.java :

Code:

package com.justforum.yotamarker.testreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class heb extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("heb", "onReceive: מה קורה אח שלו?" );
        Toast.makeText(context, "shalom", Toast.LENGTH_LONG).show();
    }
}


3 Rus.java :

Code:

package com.justforum.yotamarker.testreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class rus extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("rus", "onReceive: HE TPOHb 3APA3A !!!!" );
    }
}


4 Arabic.java :

Code:

package com.justforum.yotamarker.testreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class Arabic extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("Faouda", "onReceive: في والدتك ، دعني وشأني" );
        MainActivity.btnDynamic.setText("كيف الحال؟");
        Toast.makeText(context, "custom receiver", Toast.LENGTH_LONG).show();
    }
}


MainActivity.java :

Code:

package com.justforum.yotamarker.testreceiver;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Context context;
    private String myLng="ar"; // all receiver classes set to this channel will activate
    public static Button btnDynamic;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
        setRecivers();
    }

    private void setRecivers() {
        registerReceiver(new Eng(), new IntentFilter("en")); // broadcast channel = en
        registerReceiver(new heb(), new IntentFilter("he"));
        registerReceiver(new rus(), new IntentFilter("ru"));
        registerReceiver(new Arabic(), new IntentFilter("ar"));
    }

    private void setPointer() {
        this.context = this;
        findViewById(R.id.btnDynamic).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                sendBroadcast(new Intent(myLng)); // activate all receivers set to myLng channel
            }
        });
        btnDynamic=findViewById(R.id.btnDynamic);
    }
}


BroadcastReceivers

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio backendless sereis login and register user

more_horiz
android mobile app development grimoire - Page 3 2fbwyl
backendless is a 3rd party service that enables you to perform server style jutsus such as login, registration, use DBs, send
push notifications and more

go to https://backendless.com/
and register.

BE series 1 : login and register walkthrough :

it will open a popup asking to name the app (that will be created on the BE site) give it a name

at the top you have a btn : download project template, DL and open in android studio.


change the main activity code to :

Code:

package com.mbass.examples;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.backendless.Backendless;
import com.backendless.BackendlessUser;
import com.backendless.IDataStore;
import com.backendless.async.callback.AsyncCallback;
import com.backendless.exceptions.BackendlessFault;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends Activity {
    BackendlessUser user = new BackendlessUser();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        Backendless.setUrl(Defaults.SERVER_URL);
        Backendless.initApp(getApplicationContext(), Defaults.APPLICATION_ID, Defaults.API_KEY);
        user.setProperty("email","Angrymadman@yahoo.com");
        user.setPassword("12345");
        registerUser();
        loginUser();
    }

    private void loginUser() {

        Backendless.UserService.login(user.getEmail(),user.getPassword(), new AsyncCallback<BackendlessUser>() {
            @Override
            public void handleResponse(BackendlessUser response) {
                Toast.makeText(MainActivity.this, "Hello logged in m'k", Toast.LENGTH_LONG).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                Log.e("err", "handleFault: "+fault.getCode());
                Toast.makeText(MainActivity.this, "login err m'Kay", Toast.LENGTH_SHORT).show();

            }
        });

    }

    private void registerUser() {
        //let do some registration.....

        Backendless.UserService.register(user, new AsyncCallback<BackendlessUser>() {
            @Override
            public void handleResponse(BackendlessUser response) {
                Toast.makeText(MainActivity.this, "user registered", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                Toast.makeText(MainActivity.this, "Error in registration", Toast.LENGTH_SHORT).show();
                Log.e("err", "handleFault: "+fault.getCode());
            }
        });
    }
}
                                   



yes when it fires up the main activity has all sorts of codes but as a start of you can leave only

super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);

Backendless.setUrl(Defaults.SERVER_URL);
Backendless.initApp(getApplicationContext(), Defaults.APPLICATION_ID, Defaults.API_KEY);

in the main on creat from there I added the above prev code that registers and logs in a user.

key note : in the BE site click : help, documentation to see more of the available jutsus/

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid backendless database

more_horiz
android mobile app development grimoire - Page 3 2fdvsx

in the data tab you can see the registered users and manage them,
also to create a new DB table :
+ to create new DB table , new (in schema tab ) to add columns.

dl the DB java class at :

code generation tab, java classes for defined data tables, dl and take out the dbname.java and
add it to the project


in this example I created a dic table with keyer and content string columns.


main activity code :


Code:

package com.mbass.examples;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.backendless.Backendless;
import com.backendless.BackendlessUser;
import com.backendless.IDataStore;
import com.backendless.async.callback.AsyncCallback;
import com.backendless.exceptions.BackendlessFault;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends Activity {
    BackendlessUser user = new BackendlessUser();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        Backendless.setUrl(Defaults.SERVER_URL);
        Backendless.initApp(getApplicationContext(), Defaults.APPLICATION_ID, Defaults.API_KEY);
//        user.setProperty("email","Angrymadman@yahoo.com");
//        user.setPassword("12345");
        //registerUser();
        //loginUser();
        saveDate();
    }

    private void saveDate() {


        dic dictest = new dic();
        dictest.setKeyer("hadouken");
        dictest.setContent("shouryuken");

        Backendless.Persistence.save(dictest, new AsyncCallback<dic>() {
            @Override
            public void handleResponse(dic response) {
                Toast.makeText(MainActivity.this, "data saved", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                Toast.makeText(MainActivity.this, "Motti ?!?!?!?!?", Toast.LENGTH_SHORT).show();
                Log.e("data", "handleFault: "+fault.getMessage() );
            }
        });
    }

//    private void loginUser() {
//
//        Backendless.UserService.login(user.getEmail(),user.getPassword(), new AsyncCallback<BackendlessUser>() {
//            @Override
//            public void handleResponse(BackendlessUser response) {
//                Toast.makeText(MainActivity.this, "Hello logged in m'k", Toast.LENGTH_LONG).show();
//            }
//
//            @Override
//            public void handleFault(BackendlessFault fault) {
//                Log.e("err", "handleFault: "+fault.getCode());
//                Toast.makeText(MainActivity.this, "login err m'Kay", Toast.LENGTH_SHORT).show();
//
//            }
//        });
//
//    }
//
//    private void registerUser() {
//        //let do some registration.....
//
//        Backendless.UserService.register(user, new AsyncCallback<BackendlessUser>() {
//            @Override
//            public void handleResponse(BackendlessUser response) {
//                Toast.makeText(MainActivity.this, "user registered", Toast.LENGTH_SHORT).show();
//            }
//
//            @Override
//            public void handleFault(BackendlessFault fault) {
//                Toast.makeText(MainActivity.this, "Error in registration", Toast.LENGTH_SHORT).show();
//                Log.e("err", "handleFault: "+fault.getCode());
//            }
//        });
//    }
}
                                    


make sure you put the dic java in the folder with the main java

android mobile app development grimoire - Page 3 2frzr9

the following was built as the above example with the fields :

Code:

private String ownerId;
  private String name;
  private Boolean gender;
  private Integer age;
  private String objectId;
  private String city;
  private java.util.Date bd;
  private java.util.Date updated;
  private String email;
  private java.util.Date created;
  private boolean hasCar;


(also you can add fields from the java code of the class not only from the backendless site)

the table name is people


the main exemplifies relavent CRUD techniques for backendless data base

main java :

Code:

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.backendless.Backendless;
import com.backendless.BackendlessUser;
import com.backendless.DeviceRegistration;
import com.backendless.async.callback.AsyncCallback;
import com.backendless.exceptions.BackendlessFault;
import com.backendless.persistence.DataQueryBuilder;

import java.util.Date;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    //sender key:850560054609

    Context context;
    EditText txtUser,txtPass;
    ProgressBar pb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
        //setPushPush();
    }

    private void setPushPush() {
        //register the device to receive push push notification
       Backendless.Messaging.registerDevice("850560054609", "channelstring", new AsyncCallback<Void>() {
           @Override
           public void handleResponse(Void response) {
               Backendless.Messaging.getDeviceRegistration(new AsyncCallback<DeviceRegistration>() {
                   @Override
                   public void handleResponse(DeviceRegistration response) {
                       Log.e("push", "handleResponse: "+response.getDeviceId() );
                   }

                   @Override
                   public void handleFault(BackendlessFault fault) {

                   }
               });
           }

           @Override
           public void handleFault(BackendlessFault fault) {

           }
       });
    }

    private void setPointer() {
        this.context=this;
        pb=findViewById(R.id.pb);
        Backendless.initApp(this,getString(R.string.app_id),getString(R.string.app_key));
        txtUser=findViewById(R.id.uName);
        txtPass=findViewById(R.id.uPass);
        findViewById(R.id.btnLogin).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pb.setVisibility(View.VISIBLE);
                makeLogin();
            }
        });
        findViewById(R.id.btnRegister).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pb.setVisibility(View.VISIBLE);
                register();
            }
        });
        findViewById(R.id.btnData).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pb.setVisibility(View.VISIBLE);
                insertData();
            }
        });
        findViewById(R.id.btnRet).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pb.setVisibility(View.VISIBLE);
                getData();
            }
        });
        findViewById(R.id.btnAdult).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pb.setVisibility(View.VISIBLE);
                getAdult();
            }
        });
        findViewById(R.id.btnAdultCar).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pb.setVisibility(View.VISIBLE);
                getAdultCar();
            }
        });
    }

    private void getAdultCar() {
        String clause="age >= 18 AND hasCar=true";
        DataQueryBuilder queryBuilder = DataQueryBuilder.create();
        queryBuilder.setWhereClause(clause);
        queryBuilder.setPageSize(100);

        Backendless.Data.of(people.class).find(queryBuilder, new AsyncCallback<List<people>>() {
            @Override
            public void handleResponse(List<people> response) {
                pb.setVisibility(View.INVISIBLE);
                String msg="";
                for (people item:response)
                {
                    msg+=item.getName()+" ";
                }
                Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, fault.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }

    private void getAdult() {
        String clause="age >= 18";
        DataQueryBuilder queryBuilder = DataQueryBuilder.create();
        queryBuilder.setWhereClause(clause);
        queryBuilder.setPageSize(100);

        Backendless.Data.of(people.class).find(queryBuilder, new AsyncCallback<List<people>>() {
            @Override
            public void handleResponse(List<people> response) {
                pb.setVisibility(View.INVISIBLE);
                String msg="";
                for (people item:response)
                {
                    msg+=item.getName()+" ";
                }
                Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, fault.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }

    private void getData() {
        /*
        //get count of objects
        Backendless.Data.of(people.class).getObjectCount(new AsyncCallback<Integer>() {
            @Override
            public void handleResponse(Integer response) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, "total of:"+response, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, fault.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
        */
        Backendless.Data.of(people.class).find(new AsyncCallback<List<people>>() {
            @Override
            public void handleResponse(List<people> response) {
                pb.setVisibility(View.INVISIBLE);
                String msg="";
                for (people item:response)
                {
                    msg+=item.getName()+" ";
                }
                Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, fault.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void insertData() {
        people ppl = new people();
        ppl.setAge(24);
        ppl.setBd(new Date());
        ppl.setCity("Savyon");
        ppl.setEmail("assaf@hotmail.com");
        ppl.setGender(false); //false-male, true-female
        ppl.setName("assaf");
        ppl.setHasCar(true);

        Backendless.Persistence.of(people.class).save(ppl, new AsyncCallback<people>() {
            @Override
            public void handleResponse(people response) {
                Toast.makeText(context, "data saved", Toast.LENGTH_SHORT).show();
                pb.setVisibility(View.INVISIBLE);
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                Toast.makeText(context, fault.getMessage(), Toast.LENGTH_LONG).show();
                pb.setVisibility(View.INVISIBLE);
            }
        });
    }

    private void register() {
        BackendlessUser user = new BackendlessUser();
        user.setProperty("email",txtUser.getText().toString());
        String userName[] = txtUser.getText().toString().split("@");
        user.setProperty("name",userName[0]);
        user.setPassword(txtPass.getText().toString());

        Backendless.UserService.register(user, new AsyncCallback<BackendlessUser>() {
            @Override
            public void handleResponse(BackendlessUser response) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, "all is OK", Toast.LENGTH_LONG).show();
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, fault.getMessage(), Toast.LENGTH_LONG).show();
                Log.e("register", "handleFault: "+fault.getMessage());
            }
        });
        txtUser.setText("");
        txtPass.setText("");
    }

    private void makeLogin() {
        Backendless.UserService.login(txtUser.getText().toString(), txtPass.getText().toString(), new AsyncCallback<BackendlessUser>() {
            @Override
            public void handleResponse(BackendlessUser response) {
                Toast.makeText(context, "user logged", Toast.LENGTH_SHORT).show();
                pb.setVisibility(View.INVISIBLE);
            }

            @Override
            public void handleFault(BackendlessFault fault) {
                pb.setVisibility(View.INVISIBLE);
                Toast.makeText(context, "error in details", Toast.LENGTH_LONG).show();
                Log.e("immanual", "handleFault: "+fault.getMessage());
            }
        });
        txtUser.setText("");
        txtPass.setText("");
    }
}

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio : collapsable regions

more_horiz
android mobile app development grimoire - Page 3 2fgais

Code:

//region VARIABLES
private String _sMyVar1;
private String _sMyVar2;
//endregion


//region region name
stuff (code or comments)
//endregion


and so the stuff is conveniently collapsable

Open Region Shortcut:
control+shift+ (plus +)
Close Region Shortcut:
control+shift+ (minus -)

descriptionandroid mobile app development grimoire - Page 3 Emptybackendless android studio almighty push notifications with action no jutsu

more_horiz
android mobile app development grimoire - Page 3 2fvc7w



1 Gradle Setup
If your project uses Gradle, you can add the following configuration to your build.gradle file:
dependencies {
  implementation group: 'com.backendless', name: 'backendless', version: '5.0.+'
 
  // required for real-time database and real-time messaging
  implementation ('io.socket:socket.io-client:1.0.0') {
    // excluding org.json which is provided by Android
    exclude group: 'org.json', module: 'json'
  }
}

2 main java :

Code:

package com.yotamarker.notifire1;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.backendless.Backendless;
import com.backendless.async.callback.AsyncCallback;
import com.backendless.exceptions.BackendlessFault;

import static weborb.util.ThreadContext.context;

public class MainActivity extends AppCompatActivity {
    Context context;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
    }

    private void setPointer() {
        context=this;
        // from develop.backendless.com dashboard (home tab)Application ID , secret key = Android API key
        Backendless.initApp(this,
                "p1",
                "p2");


        Backendless.Messaging.registerDevice("p3","hadouken", new AsyncCallback<Void>() {
            @Override
            public void handleResponse(Void response) {
                Log.e("push", "handleResponse: device connected" );

            }

            @Override
            public void handleFault(BackendlessFault fault) {
                Log.e("push", "handleFault: "+fault.getMessage() );
            }
        });



    }
}



key notes for main java :
// from develop.backendless.com dashboard (home tab)Application ID  p1, secret key = Android API key p2
// see where you get these key vars after java classes in this tutorial
// respective vars parameters:
       Backendless.initApp(this,
               "p1",
               "p2");

// p3 = sender id you got from firebase
       Backendless.Messaging.registerDevice("p3","hadouken", new AsyncCallback<Void>() {

MyPushService.java :

Code:

package com.yotamarker.notifire1;

import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Looper;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import android.os.Handler;

import com.backendless.push.BackendlessPushService;

public class MyPushService extends BackendlessPushService {

    @Override
    public void onRegistered(Context context, String registrationId) {
        /*
        Toast.makeText( context,
                "device registered" + registrationId,
                Toast.LENGTH_SHORT).show();
                */

    }

    @Override
    public void onUnregistered(Context context, Boolean unregistered) {
        Toast.makeText(context,
                "device unregistered",
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onMessage(final Context context, Intent intent) {
        final String message = intent.getStringExtra("message");
        Log.e("msg", "onMessage: " + message);
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {

//                AlertDialog alertDialog = new AlertDialog.Builder(context)
//                        .setTitle("New Push")
//                        .setMessage(message)
//                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
//                            @Override
//                            public void onClick(DialogInterface dialog, int which) {
//                                dialog.dismiss();
//                            }
//                        })
//                        .create();
//
//                alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//                alertDialog.show();

                createNotification(69,R.drawable.moti,message,"motis notification",context);
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();

            }
        });
        return false;
    }

    @Override
    public void onError(Context context, String message) {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }

    private void createNotification(int nId, int icon, String msg, String title, Context context) {
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context.getApplicationContext(), "notify_001");
        Intent ii = new Intent(context.getApplicationContext(), buf.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, ii, 0);

        NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
        bigText.bigText(msg);
        bigText.setBigContentTitle(msg);
        bigText.setSummaryText("Text in detail");

        mBuilder.setContentIntent(pendingIntent);
        mBuilder.setSmallIcon(icon);
        mBuilder.setContentTitle("Your Title");
        mBuilder.setContentText(msg);
        mBuilder.setPriority(Notification.PRIORITY_MAX);
        mBuilder.setStyle(bigText);

        NotificationManager mNotificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("notify_001",
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            mNotificationManager.createNotificationChannel(channel);
        }

        mNotificationManager.notify(0, mBuilder.build());


    }
}



MyPushReceiver.java :

Code:

package com.yotamarker.notifire1;

import com.backendless.push.BackendlessBroadcastReceiver;
import com.backendless.push.BackendlessPushService;

public class MyPushReceiver extends BackendlessBroadcastReceiver
{
    @Override
    public Class<? extends BackendlessPushService> getServiceClass()
    {
        return MyPushService.class;
    }
}



console firebase
console.firebase.google.com
add project, cog wheel, project settings, cloud messaging
save sender key, server key.
go to backendless, manage tab, app settings, mobile settings (scroll down)
android, add keys paste server key, check all channelsm save

manifest :
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="[APP PACKAGE NAME].permission.C2D_MESSAGE"/>
<permission android:name="[APP PACKAGE NAME].permission.C2D_MESSAGE"
             android:protectionLevel="signature"/>
+
into <application> (under </activity>):

<receiver android:name="com.backendless.push.BackendlessBroadcastReceiver"
           android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
  <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
  <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
  <category android:name="[APP PACKAGE NAME]"/>
</intent-filter>
</receiver>
<service android:name="com.backendless.push.BackendlessPushService" />

and paste package name from the manifest at package="your package name"
over [APP PACKAGE NAME]

o the manifest under <service add :
<receiver android:name=".MyPushReceiver"
           android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
  <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
  <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
  <category android:name="com.myPackage"/>
</intent-filter>
</receiver>
<service android:name=".MyPushService" />

final manifest looks like :

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yotamarker.notifire1">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="com.yotamarker.notifire1.permission.C2D_MESSAGE"/>
    <permission android:name="com.yotamarker.notifire1.permission.C2D_MESSAGE"
        android:protectionLevel="signature"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name="com.backendless.push.BackendlessBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
                <category android:name="com.yotamarker.notifire1"/>
            </intent-filter>
        </receiver>
        <service android:name="com.backendless.push.BackendlessPushService"
            android:permission="android.permission.BIND_JOB_SERVICE"
            />
        <receiver android:name=".MyPushReceiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
                <category android:name="com.myPackage"/>
            </intent-filter>
        </receiver>
        <service android:name=".MyPushService" android:permission="android.permission.BIND_JOB_SERVICE"/>
    </application>

</manifest>


key note : in the manifest notice : android:permission="android.permission.BIND_JOB_SERVICE"
and "android.permission.BIND_JOB_SERVICE"



running the app at this stage you should see the hadouken channel at backendless messaging tab
under channels

to send messages :
backendless, messaging, channels, +

business logic tab, API service +, codeless, new service, give it a name sendPush

REST operation : GET
methode parameters :
channel String
title String
msg String
save.

click the now appeared service name under deployed services still in the business logic tab.
click edit, click messaging API, drag publish push notification into
API service "yourServiceName", and drag the methode Arguments into
the corresponding slots in said publish push notification block.
deploy, continue, done.

to send messages :
at the right side of the just build API you will have the url for sending
messages.
go to that url but add methode params at the end of the url :
?channel=channelName&title=title&msg=message

as a device works the app a channel will be added at backendless, messages tab
you can send push notis from there to selected channels or
from business logic tab.

msg at :
public boolean onMessage( Context context, Intent intent ) from its java class

src : https://backendless.com/docs/android/doc.html#dynanchor20

shinra TENSEI !!!


descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio full transformation layout into fragmant

more_horiz
android mobile app development grimoire - Page 3 2g62yu

activity_main.xml :

Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="I Am vertical Fragment"
        android:gravity="center"
        android:textSize="32sp"
        android:id="@+id/txtFv"/>

</LinearLayout>



layout_horzintal.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="I am Horzintal Layout"
        android:gravity="center"
        android:background="#ff9e5e"
        android:textSize="32sp"
        android:id="@+id/txtHr"/>

</LinearLayout>



Fragment1.java

Code:

package com.yotamarker.flip_fragment;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by zeevm on 31/10/2016.
 */

public class Fragment1 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //return my view as inflated view to the fragment
        return inflater.inflate(R.layout.activity_main, container, false);
    }
}


Fragment2.java :

Code:

package com.yotamarker.flip_fragment;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by zeevm on 31/10/2016.
 */

public class Fragment2 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.layout_horzintal,container,false);
    }
}



MainActivity.java :


Code:

package com.yotamarker.flip_fragment;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //we don't need to set view, our fragment will handle it
        //setContentView(R.layout.activity_main);

        //Create instance of Fragment manager to handle our fragments
        FragmentManager fm = getFragmentManager();
        //create instance of Fragment transaction to handle fragment replace and animation
        FragmentTransaction ft = fm.beginTransaction();

        int displayMode = getResources().getConfiguration().orientation;

        if (displayMode==1)
        {
            //create instance of first fragment
            Fragment1 f1 = new Fragment1();
            //change content of the whole screen to our new fragment
            ft.replace(android.R.id.content,f1);
        }
        else
        {
            //create instance of second fragment
            Fragment2 f2 = new Fragment2();
            //change content of the entire screen to our new fragment
            ft.replace(android.R.id.content,f2);
        }
        //choose animation
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        //commit all changes to screen fragments
        ft.commit();
    }
}


run the app and flip the device   :nice:

Last edited by Moti Barski on Mon Aug 20, 2018 2:33 pm; edited 1 time in total

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio dynamic fragment

more_horiz
android mobile app development grimoire - Page 3 2g74ia

all xml 1st :

activity_main.xml :

Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Fragment 1"
            android:id="@+id/btnFrag1"
            android:textColor="#fff"
            android:background="#009fff"
            android:layout_margin="10dp"/>
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Fragment 2"
            android:id="@+id/btnFrag2"
            android:textColor="#fff"
            android:background="#009fff"
            android:layout_margin="10dp"/>
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Fragment 3"
            android:id="@+id/btnFrag3"
            android:textColor="#fff"
            android:background="#009fff"
            android:layout_margin="10dp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container"
        android:orientation="vertical"
        android:layout_weight="1"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:background="#009fff"
        android:text="next screen"
        android:id="@+id/nextScreen"/>
</LinearLayout>


frag1.xml

Code:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/bufon" />


frag2.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/victimList"/>
</LinearLayout>


frag3.xml :

Code:

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_margin="40dp">
    <ProgressBar
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/pb"
        android:layout_weight="1"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="32dp"
        android:text="Danny is loading...."
        android:gravity="center"/>
</LinearLayout>



activity_main2.xml :

Code:

<LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:id="@+id/f1"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:id="@+id/f2"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:id="@+id/f3"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:id="@+id/f4"/>
    </LinearLayout>
</LinearLayout>


javas :


Code:

package com.example.hackeru.myfragment;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.zip.Inflater;

public class Frag1 extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.frag1,container,false);
    }
    public Frag1(){}
}


frag2 :

Code:

package com.example.hackeru.myfragment;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class Frag2 extends Fragment {
    public ListView vicList;
    String victimName;
    List<String> myList;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        //inflate view for our fragment
        View rootView = inflater.inflate(R.layout.frag2, container, false);
        //pointer to our list view
        vicList = rootView.findViewById(R.id.victimList);
        //create adapter, getActivity()-> return the context of the calling activity
        VictimAdapter adapter = new VictimAdapter(createList(), getActivity());
        //attach the adapter
        vicList.setAdapter(adapter);
        vicList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                victimName=myList.get(position);
            }
        });
        return rootView;
    }

    private List<String> createList() {
        myList = new ArrayList<>();
        myList.add("Zeev");
        myList.add("Nipo");
        myList.add("Moti");
        myList.add("Arial");
        myList.add("Danny");
        myList.add("Mordechi");
        myList.add("Michal mor");
        myList.add("Domain");
        myList.add("Imanual");
        myList.add("Ivgany");
        myList.add("BUFON");
        myList.add("Daniel");
        myList.add("Assaf");
        myList.add("Dekel");
        myList.add("Adi");
        myList.add("Artur");
        myList.add("Shimon Mizrachi");
        return myList;
    }

    public String getVictimName()
    {
        return victimName;
    }

}


frag3 :

Code:

package com.example.hackeru.myfragment;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Frag3 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.frag3,container,false);
    }
    public Frag3(){}
}


VictimAdapter (for the list) :

Code:

package com.example.hackeru.myfragment;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

public class VictimAdapter extends BaseAdapter {
    private List<String> victimList;
    private Context context;

    public VictimAdapter(List<String> victimList, Context context) {
        this.victimList = victimList;
        this.context = context;
    }

    @Override
    public int getCount() {
        return victimList.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView txt = new TextView(context);
        txt.setText(victimList.get(position));
        txt.setTextSize(42);

        return txt;
    }


}


MainActivity :

Code:

package com.example.hackeru.myfragment;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    //Fragment Manager
    FragmentManager fm;
    //Fragment Transaction
    FragmentTransaction ft;
    Frag2 fg2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //create fragment manager
        fm = getFragmentManager();
        //create fragment transaction
        //ft = fm.beginTransaction();
        fg2=new Frag2();
        findViewById(R.id.btnFrag1).setOnClickListener(this);
        findViewById(R.id.btnFrag2).setOnClickListener(this);
        findViewById(R.id.btnFrag3).setOnClickListener(this);
        findViewById(R.id.nextScreen).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Log.e("frag", "onClick: me here" );
        switch (v.getId())
        {
            case R.id.btnFrag1:
                setMyFrag(new Frag1());
                break;
            case R.id.btnFrag2:
                setMyFrag(fg2);
                break;
            case R.id.btnFrag3:
                setMyFrag(new Frag3());
                break;
            case R.id.nextScreen:
                startActivity(new Intent(this,Main2Activity.class));
                break;
        }
    }

    private void setMyFrag(Fragment myFrag) {
        //load the specific fragment
        ft = fm.beginTransaction();
        //set transition animation
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        //replace the fragment
        ft.replace(R.id.container,myFrag);
        //commit the change
        ft.commit();
    }
}



Main2Activity :


Code:

package com.example.hackeru.myfragment;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class Main2Activity extends AppCompatActivity {
    FragmentManager fm;
    FragmentTransaction ft;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        //create FragmentManager
        fm=getFragmentManager();
        //create Fragment Transaction
        ft=fm.beginTransaction();
        //add to our container our fragments
        ft.add(R.id.f1,new Frag1());
        ft.add(R.id.f2,new Frag3());
        ft.add(R.id.f3, new Frag3());
        ft.add(R.id.f4, new Frag2());
        //commit our change
        ft.commit();
    }
}


so it loads on to the empty linear layouts in the main, main2 xml.

:clr:

descriptionandroid mobile app development grimoire - Page 3 Emptyupdating android studio

more_horiz
help, check for updates 🇵🇷

descriptionandroid mobile app development grimoire - Page 3 Emptydisable screenshot

more_horiz
https://stackandroid.com/tutorial/disabling-screen-shot-capture-in-android-application/
:android:

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio GPS google map get coordinates of your location and street name no jutsu

more_horiz
android mobile app development grimoire - Page 3 2gali3

when you open a new project choose google map instead of empty activity
in the now opened google_maps_api.xml the first link will get you an app key from google which you paste
at  google_maps_api.xml at <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">app key here</string>


add manifest permissions to
AndroidManifest.xml :

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
   <uses-permission android:name="android.permission.INTERNET"/>

on api 6 and above you have to turn on GPS permissions by code see MapsActivity , getGPSPermission methode

activity_maps.xml ( already in the app by default):

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="10dp"
        >
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#009fff"
            android:textColor="#fff"
            android:text="Home"
            android:textAllCaps="false"
            android:layout_margin="16dp"
            android:id="@+id/btnHome"
            />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#009fff"
            android:textColor="#fff"
            android:text="Work"
            android:textAllCaps="false"
            android:layout_margin="16dp"
            android:id="@+id/btnWork"/>
    </LinearLayout>
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MapsActivity" />

</LinearLayout>


MapsActivity.java (there by default) : (explanation in java doc) :

Code:

package com.yotamarker.gps1;

import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Switch;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, View.OnClickListener {
    final int ACCESS_FINE_LOCATION =1;
    final int ACCESS_COARSE_LOCATION =1;
    private GoogleMap mMap;
    Location myLocation;
    LocationManager locationManager;
    final LatLng PRIPYAT = new LatLng(51.405556, 30.056944);
    final LatLng HOME = PRIPYAT;
    final LatLng WORK = new LatLng(51.261926,30.236045);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        setPointer();
    }

    private void setPointer() {
        //get location service (system service)
        getGPSPermission(); // ask for permission by code for API 6 and above
        locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        //set location updates
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        locationManager.requestLocationUpdates(getCriteria(), 10, 50, this);
        //locationManager.getLastKnownLocation(getCriteria()); //get the last known location
        findViewById(R.id.btnHome).setOnClickListener(this); // btn listeners
        findViewById(R.id.btnWork).setOnClickListener(this);
    }

    private void getGPSPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            new AlertDialog.Builder(this)
                    .setTitle("gps Permission needed to use gps jutsu")
                    .setMessage("This permission is needed because the app needs to be able to use maps")
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(MapsActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_FINE_LOCATION);
                        }
                    })
                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    })
                    .create().show();

        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_FINE_LOCATION);

        }

    }

    public String getCriteria()
    {
        Criteria criteria = new Criteria(); //indicates criteria for selction on location provider
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setAltitudeRequired(true);
        criteria.setBearingRequired(true);

        //get our best provider
        String bestProvicer =  locationManager.getBestProvider(criteria,true);// if false best GPS service will be wokend and used
        // if true only the gps wifi or gprs that are lit
        return bestProvicer;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        // this is a call back methode it fires up with the service
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        //LatLng hackerU = new LatLng(32.0831646, 34.8032984);
        LatLng home=HOME;

        mMap.addMarker(new MarkerOptions().position(home).title(motiToast(home)));

        //move instantly
        //mMap.moveCamera(CameraUpdateFactory.newLatLng(hackerU));
        //animate move
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(home, 17.4f)); // zoom on map
    }

    @Override
    public void onLocationChanged(Location location) {
        // fires up when device phisically moves
        this.myLocation=location;
        LatLng myCurrentLocation = new LatLng(myLocation.getLatitude(),myLocation.getLongitude());
        //mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myCurrentLocation,17.4f));

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onClick(View v) {
        switch (v.getId())
        {
            case R.id.btnHome:
                //it's coming home, it's coming home
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(HOME,17.4f));
                //Toast.makeText(this, HOME.latitude+","+HOME.longitude, Toast.LENGTH_SHORT).show();
                motiToast(HOME);
                break;
            case R.id.btnWork:
                //let's got to work (not)
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(WORK,17.4f));
                //Toast.makeText(this, WORK.latitude+","+WORK.longitude, Toast.LENGTH_SHORT).show();
                motiToast(WORK);
                break;
        }
    }

    public String motiToast(LatLng myLocation)
    {
        // convert gps coordinates into place name
        String returnString = "";
        Geocoder gcdLocale = new Geocoder(this); //new Geocoder(this, Locale.ENGLISH)
        List<Address> localeAdd = null;
        try {
            localeAdd = gcdLocale.getFromLocation(myLocation.latitude,myLocation.longitude,1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //if localeAdd is null (false) get out of the function (method)
        assert localeAdd != null;
        if (localeAdd.size()>0)
        {
            String myAdd = localeAdd.get(0).getAddressLine(0);
            Toast.makeText(this, myAdd, Toast.LENGTH_LONG).show();
            returnString=myAdd;
        }
        return returnString;
    }

}


hadouken  :greatscott:



android mobile app development grimoire - Page 3 2gcw0n

add a btn to activity_maps.xml:

Code:

<Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#009fff"
            android:textColor="#fff"
            android:text="last location"
            android:textAllCaps="false"
            android:layout_margin="16dp"
            android:id="@+id/lastLocation"
            />

at MapsActivity.java change onLocationChanged to :

Code:

public void onLocationChanged(Location location) {
        // fires up when device phisically moves
        this.myLocation=location;
        LatLng myCurrentLocation = new LatLng(myLocation.getLatitude(),myLocation.getLongitude());
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myCurrentLocation,17.4f));
        findViewById(R.id.lastLocation).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              motiToast(new LatLng(myLocation.getLatitude(),myLocation.getLongitude()));
            }
        });

    }


clicking the btn last location will toast where you at. :hisatsu:

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio classic animation walkthrough

more_horiz
android mobile app development grimoire - Page 3 2gjms4




go to :
https://ezgif.com/split
and split a gif image into frames and past them as .png into drawable dir (not v-24)
in this case it was : frame1.png to frame70.png

right click drawable folder, new drawable resource file :
walking_moti.xml

Code:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/frame1" android:duration="80"/>
    <item android:drawable="@drawable/frame2" android:duration="80"/>
    <item android:drawable="@drawable/frame3" android:duration="80"/>
    <item android:drawable="@drawable/frame4" android:duration="80"/>
    <item android:drawable="@drawable/frame5" android:duration="80"/>
    <item android:drawable="@drawable/frame6" android:duration="80"/>
    <item android:drawable="@drawable/frame7" android:duration="80"/>
    <item android:drawable="@drawable/frame8" android:duration="80"/>
    <item android:drawable="@drawable/frame9" android:duration="80"/>
    <item android:drawable="@drawable/frame10" android:duration="80"/>
    <item android:drawable="@drawable/frame11" android:duration="80"/>
    <item android:drawable="@drawable/frame12" android:duration="80"/>
    <item android:drawable="@drawable/frame13" android:duration="80"/>
    <item android:drawable="@drawable/frame14" android:duration="80"/>
    <item android:drawable="@drawable/frame15" android:duration="80"/>
    <item android:drawable="@drawable/frame16" android:duration="80"/>
    <item android:drawable="@drawable/frame17" android:duration="80"/>
    <item android:drawable="@drawable/frame18" android:duration="80"/>
    <item android:drawable="@drawable/frame19" android:duration="80"/>
    <item android:drawable="@drawable/frame20" android:duration="80"/>
    <item android:drawable="@drawable/frame21" android:duration="80"/>
    <item android:drawable="@drawable/frame22" android:duration="80"/>
    <item android:drawable="@drawable/frame23" android:duration="80"/>
    <item android:drawable="@drawable/frame24" android:duration="80"/>
    <item android:drawable="@drawable/frame25" android:duration="80"/>
    <item android:drawable="@drawable/frame26" android:duration="80"/>
    <item android:drawable="@drawable/frame27" android:duration="80"/>
    <item android:drawable="@drawable/frame28" android:duration="80"/>
    <item android:drawable="@drawable/frame29" android:duration="80"/>
    <item android:drawable="@drawable/frame30" android:duration="80"/>
    <item android:drawable="@drawable/frame31" android:duration="80"/>
    <item android:drawable="@drawable/frame32" android:duration="80"/>
    <item android:drawable="@drawable/frame33" android:duration="80"/>
    <item android:drawable="@drawable/frame34" android:duration="80"/>
    <item android:drawable="@drawable/frame35" android:duration="80"/>
    <item android:drawable="@drawable/frame36" android:duration="80"/>
    <item android:drawable="@drawable/frame37" android:duration="80"/>
    <item android:drawable="@drawable/frame38" android:duration="80"/>
    <item android:drawable="@drawable/frame39" android:duration="80"/>
    <item android:drawable="@drawable/frame40" android:duration="80"/>
    <item android:drawable="@drawable/frame41" android:duration="80"/>
    <item android:drawable="@drawable/frame42" android:duration="80"/>
    <item android:drawable="@drawable/frame43" android:duration="80"/>
    <item android:drawable="@drawable/frame44" android:duration="80"/>
    <item android:drawable="@drawable/frame45" android:duration="80"/>
    <item android:drawable="@drawable/frame46" android:duration="80"/>
    <item android:drawable="@drawable/frame47" android:duration="80"/>
    <item android:drawable="@drawable/frame48" android:duration="80"/>
    <item android:drawable="@drawable/frame49" android:duration="80"/>
    <item android:drawable="@drawable/frame50" android:duration="80"/>
    <item android:drawable="@drawable/frame51" android:duration="80"/>
    <item android:drawable="@drawable/frame52" android:duration="80"/>
    <item android:drawable="@drawable/frame53" android:duration="80"/>
    <item android:drawable="@drawable/frame54" android:duration="80"/>
    <item android:drawable="@drawable/frame55" android:duration="80"/>
    <item android:drawable="@drawable/frame56" android:duration="80"/>
    <item android:drawable="@drawable/frame57" android:duration="80"/>
    <item android:drawable="@drawable/frame58" android:duration="80"/>
    <item android:drawable="@drawable/frame59" android:duration="80"/>
    <item android:drawable="@drawable/frame60" android:duration="80"/>
    <item android:drawable="@drawable/frame61" android:duration="80"/>
    <item android:drawable="@drawable/frame62" android:duration="80"/>
    <item android:drawable="@drawable/frame63" android:duration="80"/>
    <item android:drawable="@drawable/frame64" android:duration="80"/>
    <item android:drawable="@drawable/frame65" android:duration="80"/>
    <item android:drawable="@drawable/frame66" android:duration="80"/>
    <item android:drawable="@drawable/frame67" android:duration="80"/>
    <item android:drawable="@drawable/frame68" android:duration="80"/>
    <item android:drawable="@drawable/frame69" android:duration="80"/>
    <item android:drawable="@drawable/frame70" android:duration="80"/>

</animation-list>


java program I wrote to write the above xml :

Code:

public class main {

 public static void main(String[] args) {

 String res = "<item android:drawable="@drawable/frame" + "1" + "" android:duration="80"/>";
 for (int i = 1; i < 71; i++) {
 System.out.println("<item android:drawable="@drawable/frame" + i + "" android:duration="80"/>");
 }
 
 
 }

}


notice I used \ to escape ".

activity_main.xml :

Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="16dp">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#009fff"
        android:text="Start/Stop Animation"
        android:textAllCaps="false"
        android:textColor="#fff"
        android:textSize="28sp"
        android:id="@+id/btnStartStop"/>

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/motiWalk"
        android:src="@drawable/walking_moti"/>
</LinearLayout>


MainActivity.java :

Code:

package com.yotamarker.animetion1;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {
    ImageView wolkingMoti;
    Context context;
    AnimationDrawable animationDrawable;
    Boolean isWalking=false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
    }

    private void setPointer() {
        this.context=this;
        wolkingMoti=findViewById(R.id.motiWalk);
        animationDrawable = (AnimationDrawable)wolkingMoti.getDrawable();
        animationDrawable.stop();
        findViewById(R.id.btnStartStop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isWalking)
                {
                    animationDrawable.stop();
                }
                else
                {
                    animationDrawable.start();
                }
                isWalking=!isWalking;
            }
        });
    }
}


shouryuken.

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio computer animation

more_horiz
android mobile app development grimoire - Page 3 2gjo6t

create res->anim

right click said anim folder, new , animation resource file :

Code:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:shareInterpolator="@android:anim/accelerate_interpolator">
 
    <alpha android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="600"
        android:repeatMode="reverse"
        android:repeatCount="infinite"
        />
</set>


paste moti.jpg in drawable directory.

activity_main.xml :

Code:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp">
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#009fff"
        android:textColor="#fff"
        android:text="Start"
        android:textAllCaps="false"
        android:textSize="28sp"
        android:id="@+id/btnMoti"/>
 
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/moti"
        android:id="@+id/motiPic"/>
</RelativeLayout>


MainActivity.java :

Code:

package com.yotamarker.computeranimation1;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity  implements Animation.AnimationListener{
    //create the folder anim under res folder
    ImageView motiImage;
    Context context;
    Animation animation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
    }

    private void setPointer() {
        this.context=this;
        motiImage=findViewById(R.id.motiPic);
        findViewById(R.id.btnMoti).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                motiImage.startAnimation(animation);
            }
        });
        //which animation we will use?!?!?!?
        animation= AnimationUtils.loadAnimation(context,R.anim.blink);
        animation.setAnimationListener(this);
    }

    @Override
    public void onAnimationStart(Animation animation) {

    }

    @Override
    public void onAnimationEnd(Animation animation) {

    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
}


some more examples of animation (replace it with blink xml you put in res,anim) :

Code:

bounce.xml
============
 
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true"
  android:interpolator="@android:anim/bounce_interpolator">
 
    <scale
      android:duration="500"
      android:fromXScale="1.0"
      android:fromYScale="0.0"
      android:toXScale="1.0"
      android:toYScale="1.0" />
 
</set>
 
fade_in.xml
===============
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true" >
 
    <alpha
      android:duration="1000"
      android:fromAlpha="0.0"
      android:interpolator="@android:anim/accelerate_interpolator"
      android:toAlpha="1.0" />
 
</set>
 
fade_out.xml
=================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true" >
 
    <alpha
      android:duration="1000"
      android:fromAlpha="1.0"
      android:interpolator="@android:anim/accelerate_interpolator"
      android:toAlpha="0.0" />
 
</set>
 
 
move.xml
===============
<?xml version="1.0" encoding="utf-8"?>
<set
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:interpolator="@android:anim/linear_interpolator"
  android:fillAfter="true">
 
  <translate
      android:fromXDelta="0%p"
      android:toXDelta="75%p"
      android:duration="800" />
</set>
 
 
 
rotate.xml
===========
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate android:fromDegrees="0"
      android:toDegrees="360"
      android:pivotX="50%"
      android:pivotY="50%"
      android:duration="600"
      android:repeatMode="restart"
      android:repeatCount="infinite"
      android:interpolator="@android:anim/cycle_interpolator"/>
 
</set>
 
 
 
sequential.xml
===============
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true"
  android:interpolator="@android:anim/linear_interpolator" >
 
    <!-- Use startOffset to give delay between animations -->
 
 
    <!-- Move -->
    <translate
      android:duration="800"
      android:fillAfter="true"
      android:fromXDelta="0%p"
      android:startOffset="300"
      android:toXDelta="75%p" />
    <translate
      android:duration="800"
      android:fillAfter="true"
      android:fromYDelta="0%p"
      android:startOffset="1100"
      android:toYDelta="70%p" />
    <translate
      android:duration="800"
      android:fillAfter="true"
      android:fromXDelta="0%p"
      android:startOffset="1900"
      android:toXDelta="-75%p" />
    <translate
      android:duration="800"
      android:fillAfter="true"
      android:fromYDelta="0%p"
      android:startOffset="2700"
      android:toYDelta="-70%p" />
 
    <!-- Rotate 360 degrees -->
    <rotate
      android:duration="1000"
      android:fromDegrees="0"
      android:interpolator="@android:anim/cycle_interpolator"
      android:pivotX="50%"
      android:pivotY="50%"
      android:startOffset="3800"
      android:repeatCount="infinite"
      android:repeatMode="restart"
      android:toDegrees="360" />
 
</set>
 
 
slide_down.xml
================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true">
 
  <scale
      android:duration="500"
      android:fromXScale="1.0"
      android:fromYScale="0.0"
      android:toXScale="1.0"
      android:toYScale="1.0" />
 
</set>
 
 
slide_up.xml
============
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true" >
 
    <scale
      android:duration="500"
      android:fromXScale="1.0"
      android:fromYScale="1.0"
      android:interpolator="@android:anim/linear_interpolator"
      android:toXScale="1.0"
      android:toYScale="0.0" />
 
</set>
 
 
 
together.xml
=============
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true"
  android:interpolator="@android:anim/linear_interpolator" >
 
    <!-- Use startOffset to give delay between animations -->
 
 
    <!-- Move -->
    <scale
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:duration="4000"
      android:fromXScale="1"
      android:fromYScale="1"
      android:pivotX="50%"
      android:pivotY="50%"
      android:toXScale="4"
      android:toYScale="4" >
    </scale>
 
    <!-- Rotate 180 degrees -->
    <rotate
      android:duration="500"
      android:fromDegrees="0"
      android:pivotX="50%"
      android:pivotY="50%"
      android:repeatCount="infinite"
      android:repeatMode="restart"
      android:toDegrees="360" />
 
</set>
 
 
zoom_in.xml
============
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true" >
 
    <scale
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:duration="1000"
      android:fromXScale="1"
      android:fromYScale="1"
      android:pivotX="50%"
      android:pivotY="50%"
      android:toXScale="3"
      android:toYScale="3" >
    </scale>
 
</set>
 
 
 
 
zoom_out.xml
============
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:fillAfter="true" >
 
  <scale
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:duration="1000"
      android:fromXScale="1.0"
      android:fromYScale="1.0"
      android:pivotX="50%"
      android:pivotY="50%"
      android:toXScale="0.5"
      android:toYScale="0.5" >
  </scale>
 
</set>

i_like_to_move_it_move_it.xml
=================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:shareInterpolator="@android:anim/accelerate_interpolator">
 
    <translate
        android:duration="3000"
        android:fromXDelta="-100%p"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toXDelta="100%p" />
</set>
 
 
moti_goes_mad.xml
====================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:shareInterpolator="@android:anim/accelerate_interpolator">
 
    <translate android:duration="2000"
        android:fromXDelta="0%p"
        android:toXDelta="35%p"
        android:startOffset="0"
        />
    <translate android:duration="2000"
        android:fromYDelta="0%p"
        android:toYDelta="35%p"
        android:startOffset="2000"
        />
    <translate android:duration="2000"
        android:fromXDelta="0%p"
        android:toXDelta="-35%p"
        android:startOffset="4000"
        />
    <translate android:duration="2000"
        android:fromYDelta="0%p"
        android:toYDelta="-35%p"
        android:startOffset="6000"/>
    <rotate android:fromDegrees="0"
        android:toDegrees="359"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="3000"
        android:repeatMode="restart"
        android:startOffset="8000"/>
    <alpha android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="500"
        android:repeatMode="restart"
        android:repeatCount="infinite"
        />
</set>
 
 
spin_the_world.xml
=====================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:shareInterpolator="@android:anim/accelerate_interpolator">
 
    <rotate android:fromDegrees="0"
        android:toDegrees="359"
        android:pivotX="25%"
        android:pivotY="25%"
        android:duration="3000"
        android:repeatMode="restart"
        android:repeatCount="infinite"/>
</set>
 
 
zoom_me.xml
================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:shareInterpolator="@android:anim/accelerate_interpolator">
 
    <scale
        android:duration="3000"
        android:fromXScale="1"
        android:fromYScale="1"
        android:toXScale="6"
        android:toYScale="6"
        android:pivotY="50%"
        android:pivotX="50%"
        />
</set>


hadouken. :interesting:

descriptionandroid mobile app development grimoire - Page 3 Emptymaximize triplet boost magic grimoire

more_horiz
body of effulgent beryl
sorry, but I"ll have you wait a bit before we engage.
fly, bless of magic caster, infinity wall, magic ward holy.
life essence, greater full potential, freedom, false data life.
see through, paranormal intuition, greater resistance, mantle of chaos.
Indomitability, sensor boost, greater luck, magic boost, draconic power.
Greater hardening. heavenly aura, absorption, penetrate up, greater magic shield.
mana essence, triplet maximize magic, explode mine, triplet magic, greater magic seal.
triplet maximize boosted magic, magic arrow






:...:

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio category screen using expandablerelativelayout

more_horiz
android mobile app development grimoire - Page 3 2gnih5



add :
implementation 'com.github.aakira:expandable-layout:1.4.1@aar'
to build.gradle(module:app)
so it looks like :

Code:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.yotamarker.collapsable1"
        minSdkVersion 26
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    implementation 'com.github.aakira:expandable-layout:1.4.1@aar'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="16dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingTop="16dp"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="#ffffff"
            android:elevation="4dp"
            android:outlineProvider="bounds"
            >
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                >
                <TextView
                    android:id="@+id/title1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="8dp"
                    android:layout_marginLeft="8dp"
                    android:text="Style &amp; Fashion"
                    />
                <TextView
                    android:layout_below="@+id/title1"
                    android:layout_toLeftOf="@+id/switch_button1"
                    android:layout_marginTop="4dp"
                    android:layout_marginLeft="8dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Style up yourself with our humpty number of collections"
                    android:textColor="#cccccc"/>
                <android.support.v7.widget.SwitchCompat
                    android:id="@+id/switch_button1"
                    android:layout_alignParentRight="true"
                    android:layout_marginRight="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="16dp" />
            </RelativeLayout>
        </LinearLayout>
        <com.github.aakira.expandablelayout.ExpandableRelativeLayout
            android:id="@+id/expandableLayout1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:ael_expanded="false"
            app:ael_duration="400"
            app:ael_interpolator="accelerate"
            app:ael_orientation="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:background="#ffffff"
                android:elevation="2dp">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp"
                    android:orientation="horizontal"
                    android:outlineProvider="bounds"
                    >
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Bags &amp; Wallets"/>
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Sports Wear"/>
                </LinearLayout>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp"
                    android:orientation="horizontal"
                    android:outlineProvider="bounds"
                    >
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Sneakers &amp; Shoes"
                        android:checked="false" />
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Party Wear"
                        android:checked="false" />
                </LinearLayout>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp"
                    android:orientation="horizontal"
                    android:outlineProvider="bounds"
                    >
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Jewellery"
                        android:checked="false" />
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Formal Wear"
                        android:checked="false" />
                </LinearLayout>
            </LinearLayout>
        </com.github.aakira.expandablelayout.ExpandableRelativeLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="#ffffff"
            android:elevation="4dp"
            android:outlineProvider="bounds"
            >
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                >
                <TextView
                    android:id="@+id/menu"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="8dp"
                    android:layout_marginLeft="8dp"
                    android:text="Electronics &amp; Gadgets"
                    />
                <TextView
                    android:layout_below="@+id/menu"
                    android:layout_toLeftOf="@+id/switch_button2"
                    android:layout_marginTop="4dp"
                    android:layout_marginLeft="8dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Mobiles, Tablets, Laptops, Accessories and much more"
                    android:textColor="#cccccc"/>
                <android.support.v7.widget.SwitchCompat
                    android:id="@+id/switch_button2"
                    android:layout_alignParentRight="true"
                    android:layout_marginRight="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="16dp" />
            </RelativeLayout>
        </LinearLayout>
        <com.github.aakira.expandablelayout.ExpandableRelativeLayout
            android:id="@+id/expandableLayout2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:ael_expanded="false"
            app:ael_duration="400"
            app:ael_interpolator="accelerate"
            app:ael_orientation="vertical"
            >
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:background="#f7f7f8"
                android:elevation="4dp">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp"
                    android:orientation="horizontal"
                    android:outlineProvider="bounds"
                    >
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Mobile Phones"/>
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Tablets"/>
                </LinearLayout>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp"
                    android:orientation="horizontal"
                    android:outlineProvider="bounds"
                    >
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="LED TVs"/>
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Projectors"/>
                </LinearLayout>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="8dp"
                    android:orientation="horizontal"
                    android:outlineProvider="bounds"
                    >
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Washing Machines"
                        android:checked="false" />
                    <android.support.v7.widget.AppCompatCheckBox
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:textColor="@android:color/secondary_text_light"
                        android:text="Refrigerators"
                        android:checked="false" />
                </LinearLayout>
            </LinearLayout>
        </com.github.aakira.expandablelayout.ExpandableRelativeLayout>
    </LinearLayout>


</ScrollView>


basicly you put linear layout in com.github.aakira.expandablelayout.ExpandableRelativeLayout in
ScrollView(which replaces the default layout when opening an empty activity project)

MainActivity.java :

Code:

package com.yotamarker.collapsable1;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
import android.widget.CompoundButton;

import com.github.aakira.expandablelayout.ExpandableRelativeLayout;

public class MainActivity extends AppCompatActivity {


    SwitchCompat switch1, switch2;
    ExpandableRelativeLayout layout1, layout2;
    private CompoundButton.OnCheckedChangeListener listener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listener = new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                toggle(compoundButton);
            }
        };
        switch1 = (SwitchCompat) findViewById(R.id.switch_button1);
        switch1.setOnCheckedChangeListener(listener);

        layout1 = (ExpandableRelativeLayout) findViewById(R.id.expandableLayout1);

        switch2 = (SwitchCompat) findViewById(R.id.switch_button2);
        switch2.setOnCheckedChangeListener(listener);

        layout2 = (ExpandableRelativeLayout) findViewById(R.id.expandableLayout2);

    }

    private void toggle(View v) {
        if(v.getId() == R.id.switch_button1)
        {
            layout1.toggle();
        }
        else if(v.getId() == R.id.switch_button2)
        {
            layout2.toggle();
        }
    }

}


the .toggle() toggles the collapsable layouts

layout1 = (ExpandableRelativeLayout) findViewById(R.id.expandableLayout1); inits said
layout

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio get camera image programmatically API > 26

more_horiz
android mobile app development grimoire - Page 3 2gthxy



manifet permissions :

Code:

<uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera2.full" />


full manifest :

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yotamarker.cam2test1">
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera2.full" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


activity_main.xml :

Code:

<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:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    android:paddingBottom="16dp" tools:context=".MainActivity">

    <TextureView
        android:id="@+id/textureview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:id="@+id/getpicture"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="getPicture"/>

</RelativeLayout>


MainActivity.java :

Code:

package com.yotamarker.cam2test1;

import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.LogRecord;

public class MainActivity extends AppCompatActivity {

    private Size previewsize;
    private Size jpegSizes[]=null;

    private TextureView textureView;
    private CameraDevice cameraDevice;
    private CaptureRequest.Builder previewBuilder;
    private CameraCaptureSession previewSession;
    Button getpicture;
    final int CAM =1;
    private void getCameraPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.CAMERA)) {

            new AlertDialog.Builder(this)
                    .setTitle("Permission needed")
                    .setMessage("This permission is needed because the app needs to be able to send SMSes")
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.CAMERA}, CAM);
                        }
                    })
                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    })
                    .create().show();

        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA}, CAM);

        }}


    private static final SparseIntArray ORIENTATIONS=new SparseIntArray();

    static
    {
        ORIENTATIONS.append(Surface.ROTATION_0,90);
        ORIENTATIONS.append(Surface.ROTATION_90,0);
        ORIENTATIONS.append(Surface.ROTATION_180,270);
        ORIENTATIONS.append(Surface.ROTATION_270,180);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getCameraPermission();
        textureView=(TextureView)findViewById(R.id.textureview);
        textureView.setSurfaceTextureListener(surfaceTextureListener);

        getpicture=(Button)findViewById(R.id.getpicture);
        getpicture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getPicture();
            }
        });
    }
    void getPicture()
    {
        if(cameraDevice==null)
        {
            return;
        }
        CameraManager manager=(CameraManager)getSystemService(Context.CAMERA_SERVICE);

        try
        {
            CameraCharacteristics characteristics=manager.getCameraCharacteristics(cameraDevice.getId());
            if(characteristics!=null)
            {
                jpegSizes=characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
            }
            int width=640,height=480;
            if(jpegSizes!=null && jpegSizes.length>0)
            {
                width=jpegSizes[0].getWidth();
                height=jpegSizes[0].getHeight();
            }
            ImageReader reader=ImageReader.newInstance(width,height,ImageFormat.JPEG,1);
            List<Surface> outputSurfaces=new ArrayList<Surface>(2);
            outputSurfaces.add(reader.getSurface());
            outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));

            final CaptureRequest.Builder capturebuilder=cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            capturebuilder.addTarget(reader.getSurface());
            capturebuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

            int rotation=getWindowManager().getDefaultDisplay().getRotation();
            capturebuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));

            ImageReader.OnImageAvailableListener imageAvailableListener=new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader) {
                    Image image = null;
                    try {
                        image = reader.acquireLatestImage();
                        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                        byte[] bytes = new byte[buffer.capacity()];
                        buffer.get(bytes);
                        save(bytes);
                    } catch (Exception ee) {

                    }
                    finally {
                        if(image!=null)
                            image.close();
                    }
                }
                void save(byte[] bytes)
                {
                    File file12=getOutputMediaFile();
                    OutputStream outputStream=null;
                    try
                    {
                        outputStream=new FileOutputStream(file12);
                        outputStream.write(bytes);
                    }catch (Exception e)
                    {
                        e.printStackTrace();
                    }finally {
                        try {
                            if (outputStream != null)
                                outputStream.close();
                        }catch (Exception e){}
                    }
                }
            };

            HandlerThread handlerThread=new HandlerThread("takepicture");
            handlerThread.start();

            final Handler handler=new Handler(handlerThread.getLooper());
            reader.setOnImageAvailableListener(imageAvailableListener,handler);

            final CameraCaptureSession.CaptureCallback  previewSSession=new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
                    super.onCaptureStarted(session, request, timestamp, frameNumber);
                }

                @Override
                public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                    startCamera();
                }
            };

            cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {

                    try
                    {
                        session.capture(capturebuilder.build(),previewSSession,handler);

                    }catch (Exception e)
                    {

                    }
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession session) {

                }
            },handler);
        }
        catch (Exception e)
        {

        }
    }

    public  void openCamera()
    {
        CameraManager manager=(CameraManager)getSystemService(Context.CAMERA_SERVICE);
        try
        {
            String camerId=manager.getCameraIdList()[0];
            CameraCharacteristics characteristics=manager.getCameraCharacteristics(camerId);
            StreamConfigurationMap map=characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            previewsize=map.getOutputSizes(SurfaceTexture.class)[0];
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                // Permission is not granted
            }else{manager.openCamera(camerId,stateCallback,null);}

        }catch (Exception e)
        {

        }
    }
    private TextureView.SurfaceTextureListener surfaceTextureListener=new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {

        }
    };
    private CameraDevice.StateCallback stateCallback=new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice camera) {
            cameraDevice=camera;
            startCamera();
        }

        @Override
        public void onDisconnected(CameraDevice camera) {

        }

        @Override
        public void onError(CameraDevice camera, int error) {

        }
    };

    @Override
    protected void onPause() {
        super.onPause();
        if(cameraDevice!=null)
        {
            cameraDevice.close();

        }
    }

    void  startCamera()
    {
        if(cameraDevice==null||!textureView.isAvailable()|| previewsize==null)
        {
            return;
        }

        SurfaceTexture texture=textureView.getSurfaceTexture();
        if(texture==null)
        {
            return;
        }

        texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
        Surface surface=new Surface(texture);

        try
        {
            previewBuilder=cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        }catch (Exception e)
        {
        }
        previewBuilder.addTarget(surface);
        try
        {
            cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {
                    previewSession=session;
                    getChangedPreview();
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession session) {

                }
            },null);
        }catch (Exception e)
        {

        }
    }
    void getChangedPreview()
    {
        if(cameraDevice==null)
        {
            return;
        }
        previewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
        HandlerThread thread=new HandlerThread("changed Preview");
        thread.start();
        Handler handler=new Handler(thread.getLooper());
        try
        {
            previewSession.setRepeatingRequest(previewBuilder.build(), null, handler);
        }catch (Exception e){}
    }

    //@Override
//    public boolean onCreateOptionsMenu(Menu menu) {
//        // Inflate the menu; this adds items to the action bar if it is present.
//        getMenuInflater().inflate(R.menu.menu_main, menu);
//        return true;
//    }

  //  @Override
//    public boolean onOptionsItemSelected(MenuItem item) {
//        // Handle action bar item clicks here. The action bar will
//        // automatically handle clicks on the Home/Up button, so long
//        // as you specify a parent activity in AndroidManifest.xml.
//        int id = item.getItemId();
//
//        //noinspection SimplifiableIfStatement
//        if (id == R.id.action_settings) {
//            return true;
//        }
//
//        return super.onOptionsItemSelected(item);
//    }

    private static File getOutputMediaFile() {
        File mediaStorageDir = new File(
                Environment
                        .getExternalStorageDirectory(),
                "MyCameraApp");
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d("MyCameraApp", "failed to create directory");
                return null;
            }
        }
        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
                .format(new Date());
        File mediaFile;
        mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "IMG_" + timeStamp + ".jpg");

        return mediaFile;
    }
}

study study study ! :sharingan:

Last edited by Moti Barski on Tue Feb 19, 2019 8:25 pm; edited 1 time in total

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio get picture from camera intent or image gallery manually from the user

more_horiz
android mobile app development grimoire - Page 3 2h2in5

add to the AndroidManifest.xml :

<uses-permission android:name="android.permission.CAMERA"/>
   <uses-permission android:name="android.permission.RECORD_AUDIO"/>
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

activity_main.xml :


Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="16dp">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="#009fff"
        android:textAllCaps="false"
        android:textColor="#fff"
        android:text="Show me the camera"
        android:textSize="22sp"
        android:id="@+id/btnCamera"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="#009fff"
        android:textAllCaps="false"
        android:textColor="#fff"
        android:text="get image from library"
        android:textSize="22sp"
        android:id="@+id/btnCameraSimple"/>
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/imgPicture"/>

</LinearLayout>


MainActivity.java:

Code:

package com.yotamarker.manualcam;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    //finals
    //take picture request code
    final private int CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE=1; // permission img from camera
    final private int CAMERA_SIMPLE_REQUEST = 2; // img from gallerys

    //pointer to image view
    ImageView imgPicture;
    //pointer to context
    Context context;
    //pointer to fileName
    String fileName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //calling the set pointer
        setPointer();
    }

    private void setPointer() {
        //get the context
        this.context=this;
        //check for camera permission, since camera is privacy violate
        //we need to ask permission by code from android 6 and above
        checkForPermissions();
        //pointer to camera on screen
        imgPicture=findViewById(R.id.imgPicture);
        //set a click listener to our button
        findViewById(R.id.btnCamera).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //check if user turned off the permission
                checkForPermissions();
                //fire the intent for camera if we have a permission to work
                if (checkForPermissions())
                {
                    //dispatch the image taking intent
                    dispatchTakeImageIntent();
                }
            }
        });
        findViewById(R.id.btnCameraSimple).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dispatchCameraSimple();
            }
        });
    }
    private void dispatchCameraSimple() {
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, CAMERA_SIMPLE_REQUEST);
        }
    }
    private boolean checkForPermissions() {
        Log.e("CHK permission", "checkForPermissions: checking permission" );
        //we create a list of permission to ask, so we can add more later on.
        List<String> listPermissionsNeeded = new ArrayList<>();
        //check if we have a permission for camera
        int camPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
        int writePerm = ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
        int readPerm = ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE);

        //we don't have the permission
        if (camPerm == PackageManager.PERMISSION_GRANTED && writePerm == PackageManager.PERMISSION_GRANTED && readPerm == PackageManager.PERMISSION_GRANTED) {
            //we have a permission we can move next
            return true;
        }
        listPermissionsNeeded.add(Manifest.permission.CAMERA);
        listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        if (!listPermissionsNeeded.isEmpty()) {
            ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
        }
        return false;
    }

    //we have a feedback from the user for permission
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //checking if we got a permission result
        Log.e("camera", "onRequestPermissionsResult: request");
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.e("Permission", "onRequestPermissionsResult: camera true ");
            dispatchTakeImageIntent();
        } else {
            //tell the user why we can not take pictures.
            Toast.makeText(context, "We can not take picture without permission", Toast.LENGTH_SHORT).show();
        }
    }

    //we calling system intent of the camera
    private void dispatchTakeImageIntent() {
        //to avoid api26+ policy restrictions.
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        //we call the android image capture
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

        //we creating a filename so we can use it later on and put the picture inside the imageView
        fileName = Environment.getExternalStorageDirectory() + File.separator + UUID.randomUUID().toString() + ".jpg";
        File file = new File(fileName);
        //we setting a global pointer to the file location
        Log.e("fileName", "dispatchTakeImageIntent: "+fileName );
        //telling the image capture intent what will be the file name of our image
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
        //since it can create exception, we surround it with try/catch block to avoid exception and application crash
        try {
            //call the intent and wait for result after intent is closed.
            startActivityForResult(intent, CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
        } catch (Exception e) {
            Log.e("Intent", "dispatchTakeImageIntent: \n" + e.getLocalizedMessage());
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE) // finished manual cam capture
        {
            try {
                Log.e("camera", "onActivityResult: "+fileName );
                //Get our saved file into a bitmap object:
                final File file = new File(fileName);

                //read the image from the file and convert it to bitmap;
                Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

                //get exif data (extra information) from the image so we will know orientation of the image
                ExifInterface exif = null;
                try {
                    exif = new ExifInterface(fileName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                assert exif != null;
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_UNDEFINED);
                //we will rotate the image so we can see it depending on screen rotation.
                Bitmap bmRotated =rotateImage(myBitmap, orientation);
                //now we can set the image into the image view that we have
                imgPicture.setImageBitmap(bmRotated);
            } catch (Exception e) {
                //printing the error that we have without crashing the application....
                e.printStackTrace();
            }
        }

        if (requestCode == CAMERA_SIMPLE_REQUEST && resultCode == RESULT_OK) { // finished gallery img selection
            Uri photoUri=data.getData();
            try {
                Bitmap selectedImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), photoUri);
                imgPicture.setImageBitmap(selectedImage);

            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    private Bitmap rotateImage(Bitmap myBitmap, int orientation) {
        //we create a matrix, so we can put the image on it and just rotate
        //it will be much faster then copy pixel by pixel
        Matrix matrix = new Matrix();
        //depending on the orientation that we got from the exif, we will rotate
        //in this sample we will deal with all kind of rotating from api 15 to api 27
        switch (orientation) {
            case ExifInterface.ORIENTATION_NORMAL:
                //all is o.k no need to rotate, just return the image
                return myBitmap;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                //flip the matrix horizontal
                matrix.setScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                //roate the matrix 180 degrees
                matrix.setRotate(180);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                //flip the picture vertical
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                //rotate 90 degrees and flip
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                //rotate 90 degress
                matrix.setRotate(90);
                break;
            case ExifInterface.ORIENTATION_TRANSVERSE:
                //rotate 90 degrees to other side and flip
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                //roate 90 degrees to other side
                matrix.setRotate(-90);
                break;
            default:
                //if we have a case that we don't thought of , just return the picture.
                return myBitmap;
        }
        try {
            //create an image from our rotated solution
            Bitmap bmRotated = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true);
            //recycle the data by calling the garbage collector
            //in this case, we free memory for big images.
            myBitmap.recycle();
            //return the rotated image
            return bmRotated;
        } catch (OutOfMemoryError e) {
            //if we have memory leak , we need to know about it.
            e.printStackTrace();
            return null;
        }
    }
}


to add video record summon btn :   :nekowhat:

new main xml :

Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_margin="16dp">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="#009fff"
        android:textAllCaps="false"
        android:textColor="#fff"
        android:text="Show me the camera"
        android:textSize="22sp"
        android:id="@+id/btnCamera"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="#009fff"
        android:textAllCaps="false"
        android:textColor="#fff"
        android:text="get image from library"
        android:textSize="22sp"
        android:id="@+id/btnCameraSimple"/>


    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="#009fff"
        android:textAllCaps="false"
        android:textColor="#fff"
        android:text="get video"
        android:textSize="22sp"
        android:id="@+id/btnVideo"/>
    <ImageView
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:id="@+id/imgPicture"/>

    <VideoView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:id="@+id/video_view"/>

</LinearLayout>


video view and btnVideo were added.

new MainActivity.java :

Code:

package com.yotamarker.manualcam;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.VideoView;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    //finals
    //take picture request code
    final private int CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE=1; // permission img from camera
    final private int CAMERA_SIMPLE_REQUEST = 2; // img from gallerys
    private static final int VIDEO_CAPTURE = 101;
    Uri cameraVideoURI;


    //pointer to image view
    ImageView imgPicture;
    //pointer to context
    Context context;
    //pointer to fileName
    String fileName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //calling the set pointer
        setPointer();
    }

    private void setPointer() {
        //get the context
        this.context=this;
        //check for camera permission, since camera is privacy violate
        //we need to ask permission by code from android 6 and above
        checkForPermissions();
        //pointer to camera on screen
        imgPicture=findViewById(R.id.imgPicture);
        //set a click listener to our button
        findViewById(R.id.btnCamera).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //check if user turned off the permission
                checkForPermissions();
                //fire the intent for camera if we have a permission to work
                if (checkForPermissions())
                {
                    //dispatch the image taking intent
                    dispatchTakeImageIntent();
                }
            }
        });
        findViewById(R.id.btnCameraSimple).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dispatchCameraSimple();
            }
        });
        findViewById(R.id.btnVideo).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                startRecordingVideo();
            }
        });
    }
    public void startRecordingVideo() {
        String fileName = "captureTemp.mp4";
        //create new values object
        ContentValues values = new ContentValues();
//insert file name as the title
        values.put(MediaStore.Video.Media.TITLE, fileName);
//create uri with values
        cameraVideoURI = getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);

        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
//put camera file name uri
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraVideoURI);
//set camera video quality
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
//set the maximum video size
        intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT,5000);
//start activity for result , the result will be on method onActivityResult
        startActivityForResult(intent, VIDEO_CAPTURE);
//        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
//            Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
//            File mediaFile = new File(
//                    Environment.getExternalStorageDirectory().getAbsolutePath() + "/myvideo.mp4");
//            videoUri = Uri.fromFile(mediaFile);
//            intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
//            startActivityForResult(intent, VIDEO_CAPTURE);
//        } else {
//            Toast.makeText(this, "No camera on device", Toast.LENGTH_LONG).show();
//        }
    }
    private void dispatchCameraSimple() {
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, CAMERA_SIMPLE_REQUEST);
        }
    }
    private boolean checkForPermissions() {
        Log.e("CHK permission", "checkForPermissions: checking permission" );
        //we create a list of permission to ask, so we can add more later on.
        List<String> listPermissionsNeeded = new ArrayList<>();
        //check if we have a permission for camera
        int camPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
        int writePerm = ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
        int readPerm = ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE);

        //we don't have the permission
        if (camPerm == PackageManager.PERMISSION_GRANTED && writePerm == PackageManager.PERMISSION_GRANTED && readPerm == PackageManager.PERMISSION_GRANTED) {
            //we have a permission we can move next
            return true;
        }
        listPermissionsNeeded.add(Manifest.permission.CAMERA);
        listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        if (!listPermissionsNeeded.isEmpty()) {
            ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
        }
        return false;
    }

    //we have a feedback from the user for permission
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //checking if we got a permission result
        Log.e("camera", "onRequestPermissionsResult: request");
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.e("Permission", "onRequestPermissionsResult: camera true ");
            dispatchTakeImageIntent();
        } else {
            //tell the user why we can not take pictures.
            Toast.makeText(context, "We can not take picture without permission", Toast.LENGTH_SHORT).show();
        }
    }

    //we calling system intent of the camera
    private void dispatchTakeImageIntent() {
        //to avoid api26+ policy restrictions.
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        //we call the android image capture
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

        //we creating a filename so we can use it later on and put the picture inside the imageView
        fileName = Environment.getExternalStorageDirectory() + File.separator + UUID.randomUUID().toString() + ".jpg";
        File file = new File(fileName);
        //we setting a global pointer to the file location
        Log.e("fileName", "dispatchTakeImageIntent: "+fileName );
        //telling the image capture intent what will be the file name of our image
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
        //since it can create exception, we surround it with try/catch block to avoid exception and application crash
        try {
            //call the intent and wait for result after intent is closed.
            startActivityForResult(intent, CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
        } catch (Exception e) {
            Log.e("Intent", "dispatchTakeImageIntent: \n" + e.getLocalizedMessage());
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE) // finished manual cam capture
        {
            try {
                Log.e("camera", "onActivityResult: "+fileName );
                //Get our saved file into a bitmap object:
                final File file = new File(fileName);

                //read the image from the file and convert it to bitmap;
                Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

                //get exif data (extra information) from the image so we will know orientation of the image
                ExifInterface exif = null;
                try {
                    exif = new ExifInterface(fileName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                assert exif != null;
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_UNDEFINED);
                //we will rotate the image so we can see it depending on screen rotation.
                Bitmap bmRotated =rotateImage(myBitmap, orientation);
                //now we can set the image into the image view that we have
                imgPicture.setImageBitmap(bmRotated);
            } catch (Exception e) {
                //printing the error that we have without crashing the application....
                e.printStackTrace();
            }
        }

        if (requestCode == CAMERA_SIMPLE_REQUEST && resultCode == RESULT_OK) { // finished gallery img selection
            Uri photoUri=data.getData();
            try {
                Bitmap selectedImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), photoUri);
                imgPicture.setImageBitmap(selectedImage);

            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        if (requestCode == VIDEO_CAPTURE) {
            if (resultCode == RESULT_OK) {
                Toast.makeText(this, "Video has been saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
                playbackRecordedVideo();
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "Video recording cancelled.",  Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, "Failed to record video",  Toast.LENGTH_LONG).show();
            }
        }

    }

    public void playbackRecordedVideo() {
        VideoView mVideoView = (VideoView) findViewById(R.id.video_view);
        mVideoView.setVideoURI(cameraVideoURI);
        mVideoView.setMediaController(new MediaController(this));
        mVideoView.requestFocus();
        mVideoView.start();

    }

    private Bitmap rotateImage(Bitmap myBitmap, int orientation) {
        //we create a matrix, so we can put the image on it and just rotate
        //it will be much faster then copy pixel by pixel
        Matrix matrix = new Matrix();
        //depending on the orientation that we got from the exif, we will rotate
        //in this sample we will deal with all kind of rotating from api 15 to api 27
        switch (orientation) {
            case ExifInterface.ORIENTATION_NORMAL:
                //all is o.k no need to rotate, just return the image
                return myBitmap;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                //flip the matrix horizontal
                matrix.setScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                //roate the matrix 180 degrees
                matrix.setRotate(180);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                //flip the picture vertical
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                //rotate 90 degrees and flip
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                //rotate 90 degress
                matrix.setRotate(90);
                break;
            case ExifInterface.ORIENTATION_TRANSVERSE:
                //rotate 90 degrees to other side and flip
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                //roate 90 degrees to other side
                matrix.setRotate(-90);
                break;
            default:
                //if we have a case that we don't thought of , just return the picture.
                return myBitmap;
        }
        try {
            //create an image from our rotated solution
            Bitmap bmRotated = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true);
            //recycle the data by calling the garbage collector
            //in this case, we free memory for big images.
            myBitmap.recycle();
            //return the rotated image
            return bmRotated;
        } catch (OutOfMemoryError e) {
            //if we have memory leak , we need to know about it.
            e.printStackTrace();
            return null;
        }
    }
}


global vars :
private static final int VIDEO_CAPTURE = 101;
   Uri cameraVideoURI;
were added

+ btnVideo).setOnClickListener

+ startRecordingVideo() methode
+ at onActivityResult, :

Code:

if (requestCode == VIDEO_CAPTURE) {
            if (resultCode == RESULT_OK) {
                Toast.makeText(this, "Video has been saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
                playbackRecordedVideo();
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "Video recording cancelled.",  Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, "Failed to record video",  Toast.LENGTH_LONG).show();
            }
        }

was added


+ playbackRecordedVideo() methode.

now the add also records and playback videos :ddr:

shouryuken :grimoire:

Last edited by Moti Barski on Sun Sep 02, 2018 9:39 pm; edited 4 times in total

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio firebase chit chat app

more_horiz
android mobile app development grimoire - Page 3 2h2lij

tool strip: tools, firebase, realtime firebase save and retrieve data, connect to firebase, add the real time
database to your app.

add
implementation 'com.android.support:design:27.1.1'
to gradle module.

at solution explorer window : project, app, google-services.json : change package name
to your package name. to make it work on different other apps put in that json file with the
other app package name, them those other apps can chat with the prime app and among themselves.


MainActivity.java

Code:

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    ListView myMsgList;
    EditText myMsg;
    Context context;
    List<String> msgList;
    final String REF_ID="message";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
        setMessageListener();
    }


    private void setPointer() {
        this.context=this;
        msgList=new ArrayList<>();
        myMsg=findViewById(R.id.txtMsg);
        myMsgList=findViewById(R.id.lstMsg);
        findViewById(R.id.btnSend).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessage();
            }
        });
    }

    private void sendMessage() {
        String msg = myMsg.getText().toString();
        myMsg.setText("");
        //fire base will give us singleton of his instance

        //creating an instance to the database
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        //creating a referance to message object
        DatabaseReference msgRef = database.getReference(REF_ID);
        //set value to the database
        msgRef.setValue(msg);
    }

    private void setMessageListener() {
        //create an instance to the database
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        //create a referance to the database
        DatabaseReference msgRef = database.getReference(REF_ID);
        //create an event listner with callback to our Reference
        msgRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                //this method is called once with the initial value and again
                //whenever data at this location is updated
                String value=dataSnapshot.getValue(String.class);
                msgList.add(0,value);
                ChatAdapter myAdapter = new ChatAdapter(context,msgList);
                myMsgList.setAdapter(myAdapter);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

}


ChatAdapter.java
========================

Code:

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

public class ChatAdapter extends BaseAdapter {
    Context context;
    List<String> msgList;

    public ChatAdapter(Context context, List<String> msgList) {
        this.context = context;
        this.msgList = msgList;
    }

    @Override
    public int getCount() {
        return msgList.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView txt = new TextView(context);
        txt.setText(msgList.get(position));
        return txt;
    }
}


activity_main.xml
========================

Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="enter your msg"
            android:layout_weight="1"
            android:id="@+id/txtMsg"/>
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:text="send"
            android:background="#009fff"
            android:textColor="#fff"
            android:textSize="22sp"
            android:id="@+id/btnSend"/>
    </LinearLayout>
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lstMsg"/>

</LinearLayout>


at fire base site U can also see the chat data at :

DB, appname, start test mode, read write true. :o

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio scheduled task jutsu walkthrough

more_horiz
android mobile app development grimoire - Page 3 2h9pyy

add MyTimeTask.java :

Code:

package com.yotamarker.scheduled1;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import java.io.IOException;
import java.util.TimerTask;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

public class MyTimeTask extends TimerTask {
    // summons task at needed time
    Context context;


    public MyTimeTask(Context context1) {
        super();
        this.context = context1;
    }

    @Override
    public void run() {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {

                createNotification(69,R.mipmap.ic_launcher,"tested","motis notification",context);
                Toast.makeText(context, "moti rulz", Toast.LENGTH_SHORT).show();

            }
        });
        Log.d("MyAlarmBelal", "hadouken hadoukenhadoukenhadoukenhadoukenhadoukenhadoukenhadoukenhadouken");
        createNotification(69,R.mipmap.ic_launcher,"tested","motis notification",context);

    }
    private void createNotification(int nId, int icon, String msg, String title, Context context) {
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context.getApplicationContext(), "notify_001");
        Intent ii = new Intent(context.getApplicationContext(), MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, ii, 0);

        NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
        bigText.bigText(msg);
        bigText.setBigContentTitle(msg);
        bigText.setSummaryText("Text in detail");

        mBuilder.setContentIntent(pendingIntent);
        mBuilder.setSmallIcon(icon);
        mBuilder.setContentTitle("Your Title");
        mBuilder.setContentText(msg);
        mBuilder.setPriority(Notification.PRIORITY_MAX);
        mBuilder.setStyle(bigText);

        NotificationManager mNotificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("notify_001",
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            mNotificationManager.createNotificationChannel(channel);
        }

        mNotificationManager.notify(0, mBuilder.build());


    }
}




modify MainActivity.java :


Code:

package com.yotamarker.scheduled1;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TimePicker;
import android.widget.Toast;

import java.util.Calendar;
import java.util.Timer;

public class MainActivity extends AppCompatActivity {
    Timer timer = new Timer();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        timer.schedule(new MyTimeTask(this), 5000);



    }
}



key notes : replace 5000 with in how many milisecs from current time you want
the scheduled task to fire up (scream of the banshee)

to calculate delay you can use (from moti barski java grimoire):

DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
java.util.Date date2 = dateFormatter.parse("1955-11-05 " + RAL1.getEndTime());
Calendar cal = Calendar.getInstance();
int h2 = date2.getHours() - cal.getTime().getHours();
              int m2 = date2.getMinutes() - cal.getTime().getMinutes();
              int s2 = date2.getSeconds() - cal.getTime().getSeconds();
              int delay2 = h * 3600000 + m * 60000 + s * 1000;
              if (delay2 < 0) {
                 delay2 += 24 * 24 * 3600000;
              }

keynote 2 : the Handler in MyTimeTask enables the toast message :grimoire:

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio java thread techniques

more_horiz
android mobile app development grimoire - Page 3 2hlnsk

threading makes codes run inparallel on different processor cores at the same time, giving
the app speed, this is called asyncro. unlike syncro that runs linearly.

1 main anonymous object example:


Code:

package com.yotamarker.egyptiancotton;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TextView pelet;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pelet = findViewById(R.id.txtOutput);
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0;i<500;i++){
                    Log.d("async", "___ " + i);
                }
            }
        });
        t.start();
        for(int i = 0;i<500;i++){
            Log.d("syncro", "___ " + i);
        }
    }
}


at logcat debug you can see a blender between the asyncro and syncro, meaning they run in parrallal
not one after the other (asyncro not syncro).

2 main (using external variable in a thread) :

Code:

package com.yotamarker.egyptiancotton;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.util.Date;

public class MainActivity extends AppCompatActivity {
//    TextView pelet;
    final Date now = new Date();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //pelet = findViewById(R.id.txtOutput);
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0;i<500;i++){
                    Log.d("async", now + " ___ " + i);
                }
            }
        });
        t.start();
    }
}


set  thread priority importance : t.setPriority(5);
get thread priority : t.getPriority(5);
get current thread priority : Thread.currentThread().getPriority();

3 join : makes whatever is on the main program thread wait till joined threads finish :

ExThread.java

Code:

package com.yotamarker.egyptiancotton;

import android.util.Log;

public class ExThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 500; i++) {
            Log.d("async", " ___ " + i);
        }
    }
}


main :

Code:

package com.yotamarker.egyptiancotton;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.util.Date;

public class MainActivity extends AppCompatActivity {
//    TextView pelet;
    final Date now = new Date();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ExThread t1 = new ExThread();
        ExThread t2 = new ExThread();
        t1.start();;
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 500; i++) {
            Log.d("sync", " ___ " + i);
        }
    }
}



4 pause a thread :
Thread.sleep(5000);
5 stop a thread :

t.stopThread(); // assuming it started (t.start();)

6 mutex syncro shoukan:

Code:

import android.util.Log;

public class ExThread extends Thread {
    private static Object mutex = new Object();
    @Override
    public void run() {
        synchronized (mutex){
            // this code block will run syncro
        }
        // outside mutex runs asyncro
        for (int i = 0; i < 500; i++) {
            Log.d("async", " ___ " + i);
        }
    }
}


7 making a thread stop for racing several threads

stoppable thread class ExThread.java :

Code:

package com.yotamarker.egyptiancotton;

import android.util.Log;

public class ExThread extends Thread {
    public boolean stop = false; // can also set as static var
    @Override
    public void run() {
        for (int i = 0; i < 5000; i++) {
            if(!stop){ Log.d("async", "long thread ___ " + i);}
            else{return;}

        }
    }
}


fast thread ExThread2:

Code:

package com.yotamarker.egyptiancotton;

import android.util.Log;

public class ExThread2 extends Thread {
    private static Object mutex = new Object();
    @Override
    public void run() {

        for (int i = 0; i < 500; i++) {
            Log.d("async", " short thread___ " + i);
        }
    }
}


it simply less running code.

main :

Code:

package com.yotamarker.egyptiancotton;

import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.util.Date;

public class MainActivity extends AppCompatActivity {
//    TextView pelet;
    final Date now = new Date();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ExThread t1 = new ExThread();
        ExThread2 t2 = new ExThread2();
        t1.start();;
        t2.start();
        try {
            t2.join();
            t1.stop = true;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        for (int i = 0; i < 500; i++) {
            Log.d("sync", " ___ stopped");
        }
    }

}


just set t1.stop to true from the main program thread to stop it

:tokushushoukan

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio lock app orientation by code or from manifest

more_horiz
android mobile app development grimoire - Page 3 2hs93f

by code :

in the activity oncreate methode :

Code:

protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // Make to run your application only in portrait mode

        //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // Make to run your application only in LANDSCAPE mode


by manifest :

in AndroidManifest.xml :

add android:screenOrientation="landscape"
like this : <activity android:name=".MainActivity" android:screenOrientation="landscape">
:rlx:

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio get B8Triz level percentage

more_horiz
android mobile app development grimoire - Page 3 2i03fx

main xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/batteryTxt"/>

</android.support.constraint.ConstraintLayout>


main java :

Code:

package com.yotamarker.batery;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private TextView batteryTxt;
    private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
        @Override
        public void onReceive(Context ctxt, Intent intent) {
            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
            batteryTxt.setText(String.valueOf(level) + "%");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        batteryTxt = (TextView) this.findViewById(R.id.batteryTxt);
        this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
}


hadouken :face:

descriptionandroid mobile app development grimoire - Page 3 Emptyandroid studio show EULA

more_horiz
R values strings.xml :

Code:

<resources>
    <string name="app_name">testEula</string>
    <string name="EULA">
        COPYRIGHTS:

\nCopyright 2013 APP_NAME. All Rights Reserved.

\n\nThis software may not, in whole or in any part, be copied, reproduced, transmitted, translated (into any
language, natural or computer), stored in a retrieval system, reduced to any electronic medium or machine readable
format, or by any other form or means without prior consent, in writing, from APP_NAME.

\n\nYou are granted a limited license to use this software. The software may be used or copied only in accordance
with the terms of that license, which is described in the following paragraphs.

\n\nTRADEMARKS:
\n\n[Software logos, icons, etc that are Trademarked]

\n\nLICENSE:
\n\n\"THE SOFTWARE\" shall be taken to mean the software contained in this app and any subsequent versions
or upgrades received as a result of having purchased this app. \"BUYER\" shall be taken as the original
purchaser of the software.

\n\nBuyer has the non-exclusive right to the use of software only on a single device. Buyer may not electronically
transfer the program from one device to another over any type of network. Buyer may not distribute copies
of the software or the accompanying documentation to others either for a fee or without charge. Buyer may not modify
or translate the program or documentation. User may not disassemble the program or allow it to be disassembled
into its constituent source code. Buyer\'s use of the software indicates his/her acceptance of these terms
and conditions. If buyer does not agree to these conditions, return the distribution media, documentation, and
associated materials to the vendor from whom the software was purchased, and/or uninstall the software from the device,
and erase the software from any and all storage devices upon which it may have been installed.

\n\nThis license agreement shall be governed by the laws of The United States of America, Massachusetts and
shall inure to the benefit of APP_NAME or its assigns.

\n\nDISCLAIMER / LIMITATION OF LIABILITY:
\n\nBuyer acknowledges that the software may not be free from defects and may not satisfy all of buyer\'s
needs. APP_NAME warrants all media on which the software is distributed for 60 days to be free from defects
in normal use. The software and any accompanying written materials are licensed \"AS IS\". Buyer\'s exclusive
remedy during the warranty period (if any) shall consist of replacement of distribution media if determined to be
faulty. In no event will APP_NAME be liable for direct, indirect, incidental or consequential damage or
damages resulting from loss of use, or loss of anticipated profits resulting from any defect in the software,
even if it has been advised of the possibility of such damage. Some laws do not allow exclusion or limitation
of implied warranties or liabilities for incidental or consequential damages, so the above limitations or
exclusion may not apply.

\n\nSPECIFIC RESTRICTIONS:
\n\nIn accordance with the COMPUTER SOFTWARE RENTAL ACT OF 1990, this software may not be rented, lent or leased.
\n\nThe software and accompanying documentation may not be provided by a \"Backup Service\" or any other vendor
which does not provide an original package as composed of APP_NAME, including but not limited to all original
distribution media, documentation, registration cards, and insertions.
    </string>
</resources>


MainActivity.java :

Code:

package com.yotamarker.testeula;

import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class MainActivity extends AppCompatActivity {
    final String EULA_FLAG = "1";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(!readEula()){EULA();}

    }

    private void EULA() {
        new AlertDialog.Builder(this)
                .setTitle("agreement to use app")
                .setMessage(R.string.EULA)
                .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        saveTrue();
                    }
                })
                .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                        System.exit(0);
                        dialog.dismiss();
                    }
                })
                .create().show();

    }
    private void saveTrue(){
        String fileName = "mmmkay";
        String data = EULA_FLAG;

        // calling FileOutputStream
        FileOutputStream fos;
        try
        {
            fos = openFileOutput(fileName, Context.MODE_PRIVATE);
            // Context.MODE_PRIVATE IS DEFAULT
            fos.write(data.getBytes());
            fos.close();
            Toast.makeText(getApplicationContext(), fileName + "Saved " ,
                    Toast.LENGTH_SHORT).show();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e){
            e.printStackTrace();
        }

    }
private Boolean readEula(){
    String fileName = "mmmkay";
    StringBuffer stringBuffer = new StringBuffer();
    try
    {
        BufferedReader inputReader =
                new BufferedReader(new
                        InputStreamReader(openFileInput(fileName)));
        String inputString;
        while((inputString = inputReader.readLine())!= null) {
            stringBuffer.append(inputString);
        }
    }
    catch (IOException e){
        e.printStackTrace();
    }
    String str = stringBuffer.toString().trim();
    http://Toast.makeText(this,str.length() + "",Toast.LENGTH_LONG);
    return str.contains(EULA_FLAG);

}
}


click cancel on the agreement : app closes
click ok : app saves you agreed, and doesn't display the EULA any more when the app opens
note that :
finish();
System.exit(0);
are the code lines to close the app

:android:
privacy_tip Permissions in this forum:
You cannot reply to topics in this forum
power_settings_newLogin to reply